first commit

This commit is contained in:
Ayxan
2022-05-23 00:16:32 +04:00
commit d660f2a4ca
24786 changed files with 4428337 additions and 0 deletions

View File

@ -0,0 +1,30 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include "arrow/python/arrow_to_pandas.h"
#include "arrow/python/common.h"
#include "arrow/python/datetime.h"
#include "arrow/python/deserialize.h"
#include "arrow/python/helpers.h"
#include "arrow/python/inference.h"
#include "arrow/python/io.h"
#include "arrow/python/numpy_convert.h"
#include "arrow/python/numpy_to_arrow.h"
#include "arrow/python/python_to_arrow.h"
#include "arrow/python/serialize.h"

View File

@ -0,0 +1,124 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
// Functions for converting between pandas's NumPy-based data representation
// and Arrow data structures
#pragma once
#include "arrow/python/platform.h"
#include <memory>
#include <string>
#include <unordered_set>
#include "arrow/memory_pool.h"
#include "arrow/python/visibility.h"
namespace arrow {
class Array;
class ChunkedArray;
class Column;
class DataType;
class MemoryPool;
class Status;
class Table;
namespace py {
struct PandasOptions {
/// arrow::MemoryPool to use for memory allocations
MemoryPool* pool = default_memory_pool();
/// If true, we will convert all string columns to categoricals
bool strings_to_categorical = false;
bool zero_copy_only = false;
bool integer_object_nulls = false;
bool date_as_object = false;
bool timestamp_as_object = false;
bool use_threads = false;
/// Coerce all date and timestamp to datetime64[ns]
bool coerce_temporal_nanoseconds = false;
/// Used to maintain backwards compatibility for
/// timezone bugs (see ARROW-9528). Should be removed
/// after Arrow 2.0 release.
bool ignore_timezone = false;
/// \brief If true, do not create duplicate PyObject versions of equal
/// objects. This only applies to immutable objects like strings or datetime
/// objects
bool deduplicate_objects = false;
/// \brief For certain data types, a cast is needed in order to store the
/// data in a pandas DataFrame or Series (e.g. timestamps are always stored
/// as nanoseconds in pandas). This option controls whether it is a safe
/// cast or not.
bool safe_cast = true;
/// \brief If true, create one block per column rather than consolidated
/// blocks (1 per data type). Do zero-copy wrapping when there are no
/// nulls. pandas currently will consolidate the blocks on its own, causing
/// increased memory use, so keep this in mind if you are working on a
/// memory-constrained situation.
bool split_blocks = false;
/// \brief If true, allow non-writable zero-copy views to be created for
/// single column blocks. This option is also used to provide zero copy for
/// Series data
bool allow_zero_copy_blocks = false;
/// \brief If true, attempt to deallocate buffers in passed Arrow object if
/// it is the only remaining shared_ptr copy of it. See ARROW-3789 for
/// original context for this feature. Only currently implemented for Table
/// conversions
bool self_destruct = false;
// Used internally for nested arrays.
bool decode_dictionaries = false;
// Columns that should be casted to categorical
std::unordered_set<std::string> categorical_columns;
// Columns that should be passed through to be converted to
// ExtensionArray/Block
std::unordered_set<std::string> extension_columns;
};
ARROW_PYTHON_EXPORT
Status ConvertArrayToPandas(const PandasOptions& options, std::shared_ptr<Array> arr,
PyObject* py_ref, PyObject** out);
ARROW_PYTHON_EXPORT
Status ConvertChunkedArrayToPandas(const PandasOptions& options,
std::shared_ptr<ChunkedArray> col, PyObject* py_ref,
PyObject** out);
// Convert a whole table as efficiently as possible to a pandas.DataFrame.
//
// The returned Python object is a list of tuples consisting of the exact 2D
// BlockManager structure of the pandas.DataFrame used as of pandas 0.19.x.
//
// tuple item: (indices: ndarray[int32], block: ndarray[TYPE, ndim=2])
ARROW_PYTHON_EXPORT
Status ConvertTableToPandas(const PandasOptions& options, std::shared_ptr<Table> table,
PyObject** out);
} // namespace py
} // namespace arrow

View File

@ -0,0 +1,36 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include "arrow/python/platform.h"
#include "arrow/python/visibility.h"
namespace arrow {
namespace py {
namespace benchmark {
// Micro-benchmark routines for use from ASV
// Run PandasObjectIsNull() once over every object in *list*
ARROW_PYTHON_EXPORT
void Benchmark_PandasObjectIsNull(PyObject* list);
} // namespace benchmark
} // namespace py
} // namespace arrow

View File

@ -0,0 +1,360 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <memory>
#include <utility>
#include "arrow/buffer.h"
#include "arrow/python/pyarrow.h"
#include "arrow/python/visibility.h"
#include "arrow/result.h"
#include "arrow/util/macros.h"
namespace arrow {
class MemoryPool;
template <class T>
class Result;
namespace py {
// Convert current Python error to a Status. The Python error state is cleared
// and can be restored with RestorePyError().
ARROW_PYTHON_EXPORT Status ConvertPyError(StatusCode code = StatusCode::UnknownError);
// Query whether the given Status is a Python error (as wrapped by ConvertPyError()).
ARROW_PYTHON_EXPORT bool IsPyError(const Status& status);
// Restore a Python error wrapped in a Status.
ARROW_PYTHON_EXPORT void RestorePyError(const Status& status);
// Catch a pending Python exception and return the corresponding Status.
// If no exception is pending, Status::OK() is returned.
inline Status CheckPyError(StatusCode code = StatusCode::UnknownError) {
if (ARROW_PREDICT_TRUE(!PyErr_Occurred())) {
return Status::OK();
} else {
return ConvertPyError(code);
}
}
#define RETURN_IF_PYERROR() ARROW_RETURN_NOT_OK(CheckPyError())
#define PY_RETURN_IF_ERROR(CODE) ARROW_RETURN_NOT_OK(CheckPyError(CODE))
// For Cython, as you can't define template C++ functions in Cython, only use them.
// This function can set a Python exception. It assumes that T has a (cheap)
// default constructor.
template <class T>
T GetResultValue(Result<T> result) {
if (ARROW_PREDICT_TRUE(result.ok())) {
return *std::move(result);
} else {
int r = internal::check_status(result.status()); // takes the GIL
assert(r == -1); // should have errored out
ARROW_UNUSED(r);
return {};
}
}
// A RAII-style helper that ensures the GIL is acquired inside a lexical block.
class ARROW_PYTHON_EXPORT PyAcquireGIL {
public:
PyAcquireGIL() : acquired_gil_(false) { acquire(); }
~PyAcquireGIL() { release(); }
void acquire() {
if (!acquired_gil_) {
state_ = PyGILState_Ensure();
acquired_gil_ = true;
}
}
// idempotent
void release() {
if (acquired_gil_) {
PyGILState_Release(state_);
acquired_gil_ = false;
}
}
private:
bool acquired_gil_;
PyGILState_STATE state_;
ARROW_DISALLOW_COPY_AND_ASSIGN(PyAcquireGIL);
};
// A RAII-style helper that releases the GIL until the end of a lexical block
class ARROW_PYTHON_EXPORT PyReleaseGIL {
public:
PyReleaseGIL() { saved_state_ = PyEval_SaveThread(); }
~PyReleaseGIL() { PyEval_RestoreThread(saved_state_); }
private:
PyThreadState* saved_state_;
ARROW_DISALLOW_COPY_AND_ASSIGN(PyReleaseGIL);
};
// A helper to call safely into the Python interpreter from arbitrary C++ code.
// The GIL is acquired, and the current thread's error status is preserved.
template <typename Function>
auto SafeCallIntoPython(Function&& func) -> decltype(func()) {
PyAcquireGIL lock;
PyObject* exc_type;
PyObject* exc_value;
PyObject* exc_traceback;
PyErr_Fetch(&exc_type, &exc_value, &exc_traceback);
auto maybe_status = std::forward<Function>(func)();
// If the return Status is a "Python error", the current Python error status
// describes the error and shouldn't be clobbered.
if (!IsPyError(::arrow::internal::GenericToStatus(maybe_status)) &&
exc_type != NULLPTR) {
PyErr_Restore(exc_type, exc_value, exc_traceback);
}
return maybe_status;
}
// A RAII primitive that DECREFs the underlying PyObject* when it
// goes out of scope.
class ARROW_PYTHON_EXPORT OwnedRef {
public:
OwnedRef() : obj_(NULLPTR) {}
OwnedRef(OwnedRef&& other) : OwnedRef(other.detach()) {}
explicit OwnedRef(PyObject* obj) : obj_(obj) {}
OwnedRef& operator=(OwnedRef&& other) {
obj_ = other.detach();
return *this;
}
~OwnedRef() { reset(); }
void reset(PyObject* obj) {
Py_XDECREF(obj_);
obj_ = obj;
}
void reset() { reset(NULLPTR); }
PyObject* detach() {
PyObject* result = obj_;
obj_ = NULLPTR;
return result;
}
PyObject* obj() const { return obj_; }
PyObject** ref() { return &obj_; }
operator bool() const { return obj_ != NULLPTR; }
private:
ARROW_DISALLOW_COPY_AND_ASSIGN(OwnedRef);
PyObject* obj_;
};
// Same as OwnedRef, but ensures the GIL is taken when it goes out of scope.
// This is for situations where the GIL is not always known to be held
// (e.g. if it is released in the middle of a function for performance reasons)
class ARROW_PYTHON_EXPORT OwnedRefNoGIL : public OwnedRef {
public:
OwnedRefNoGIL() : OwnedRef() {}
OwnedRefNoGIL(OwnedRefNoGIL&& other) : OwnedRef(other.detach()) {}
explicit OwnedRefNoGIL(PyObject* obj) : OwnedRef(obj) {}
~OwnedRefNoGIL() {
PyAcquireGIL lock;
reset();
}
};
template <typename Fn>
struct BoundFunction;
template <typename... Args>
struct BoundFunction<void(PyObject*, Args...)> {
// We bind `cdef void fn(object, ...)` to get a `Status(...)`
// where the Status contains any Python error raised by `fn`
using Unbound = void(PyObject*, Args...);
using Bound = Status(Args...);
BoundFunction(Unbound* unbound, PyObject* bound_arg)
: bound_arg_(bound_arg), unbound_(unbound) {}
Status Invoke(Args... args) const {
PyAcquireGIL lock;
unbound_(bound_arg_.obj(), std::forward<Args>(args)...);
RETURN_IF_PYERROR();
return Status::OK();
}
Unbound* unbound_;
OwnedRefNoGIL bound_arg_;
};
template <typename Return, typename... Args>
struct BoundFunction<Return(PyObject*, Args...)> {
// We bind `cdef Return fn(object, ...)` to get a `Result<Return>(...)`
// where the Result contains any Python error raised by `fn` or the
// return value from `fn`.
using Unbound = Return(PyObject*, Args...);
using Bound = Result<Return>(Args...);
BoundFunction(Unbound* unbound, PyObject* bound_arg)
: bound_arg_(bound_arg), unbound_(unbound) {}
Result<Return> Invoke(Args... args) const {
PyAcquireGIL lock;
Return ret = unbound_(bound_arg_.obj(), std::forward<Args>(args)...);
RETURN_IF_PYERROR();
return ret;
}
Unbound* unbound_;
OwnedRefNoGIL bound_arg_;
};
template <typename OutFn, typename Return, typename... Args>
std::function<OutFn> BindFunction(Return (*unbound)(PyObject*, Args...),
PyObject* bound_arg) {
using Fn = BoundFunction<Return(PyObject*, Args...)>;
static_assert(std::is_same<typename Fn::Bound, OutFn>::value,
"requested bound function of unsupported type");
Py_XINCREF(bound_arg);
auto bound_fn = std::make_shared<Fn>(unbound, bound_arg);
return
[bound_fn](Args... args) { return bound_fn->Invoke(std::forward<Args>(args)...); };
}
// A temporary conversion of a Python object to a bytes area.
struct PyBytesView {
const char* bytes;
Py_ssize_t size;
bool is_utf8;
static Result<PyBytesView> FromString(PyObject* obj, bool check_utf8 = false) {
PyBytesView self;
ARROW_RETURN_NOT_OK(self.ParseString(obj, check_utf8));
return std::move(self);
}
static Result<PyBytesView> FromUnicode(PyObject* obj) {
PyBytesView self;
ARROW_RETURN_NOT_OK(self.ParseUnicode(obj));
return std::move(self);
}
static Result<PyBytesView> FromBinary(PyObject* obj) {
PyBytesView self;
ARROW_RETURN_NOT_OK(self.ParseBinary(obj));
return std::move(self);
}
// View the given Python object as string-like, i.e. str or (utf8) bytes
Status ParseString(PyObject* obj, bool check_utf8 = false) {
if (PyUnicode_Check(obj)) {
return ParseUnicode(obj);
} else {
ARROW_RETURN_NOT_OK(ParseBinary(obj));
if (check_utf8) {
// Check the bytes are utf8 utf-8
OwnedRef decoded(PyUnicode_FromStringAndSize(bytes, size));
if (ARROW_PREDICT_TRUE(!PyErr_Occurred())) {
is_utf8 = true;
} else {
PyErr_Clear();
is_utf8 = false;
}
}
return Status::OK();
}
}
// View the given Python object as unicode string
Status ParseUnicode(PyObject* obj) {
// The utf-8 representation is cached on the unicode object
bytes = PyUnicode_AsUTF8AndSize(obj, &size);
RETURN_IF_PYERROR();
is_utf8 = true;
return Status::OK();
}
// View the given Python object as binary-like, i.e. bytes
Status ParseBinary(PyObject* obj) {
if (PyBytes_Check(obj)) {
bytes = PyBytes_AS_STRING(obj);
size = PyBytes_GET_SIZE(obj);
is_utf8 = false;
} else if (PyByteArray_Check(obj)) {
bytes = PyByteArray_AS_STRING(obj);
size = PyByteArray_GET_SIZE(obj);
is_utf8 = false;
} else if (PyMemoryView_Check(obj)) {
PyObject* ref = PyMemoryView_GetContiguous(obj, PyBUF_READ, 'C');
RETURN_IF_PYERROR();
Py_buffer* buffer = PyMemoryView_GET_BUFFER(ref);
bytes = reinterpret_cast<const char*>(buffer->buf);
size = buffer->len;
is_utf8 = false;
} else {
return Status::TypeError("Expected bytes, got a '", Py_TYPE(obj)->tp_name,
"' object");
}
return Status::OK();
}
protected:
OwnedRef ref;
};
class ARROW_PYTHON_EXPORT PyBuffer : public Buffer {
public:
/// While memoryview objects support multi-dimensional buffers, PyBuffer only supports
/// one-dimensional byte buffers.
~PyBuffer();
static Result<std::shared_ptr<Buffer>> FromPyObject(PyObject* obj);
private:
PyBuffer();
Status Init(PyObject*);
Py_buffer py_buf_;
};
// Return the common PyArrow memory pool
ARROW_PYTHON_EXPORT void set_default_memory_pool(MemoryPool* pool);
ARROW_PYTHON_EXPORT MemoryPool* get_memory_pool();
// This is annoying: because C++11 does not allow implicit conversion of string
// literals to non-const char*, we need to go through some gymnastics to use
// PyObject_CallMethod without a lot of pain (its arguments are non-const
// char*)
template <typename... ArgTypes>
static inline PyObject* cpp_PyObject_CallMethod(PyObject* obj, const char* method_name,
const char* argspec, ArgTypes... args) {
return PyObject_CallMethod(obj, const_cast<char*>(method_name),
const_cast<char*>(argspec), args...);
}
} // namespace py
} // namespace arrow

View File

@ -0,0 +1,42 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <functional>
#include <memory>
#include <string>
#include <vector>
#include "arrow/csv/options.h"
#include "arrow/python/common.h"
#include "arrow/util/macros.h"
namespace arrow {
namespace py {
namespace csv {
using PyInvalidRowCallback = std::function<::arrow::csv::InvalidRowResult(
PyObject*, const ::arrow::csv::InvalidRow&)>;
ARROW_PYTHON_EXPORT
::arrow::csv::InvalidRowHandler MakeInvalidRowHandler(PyInvalidRowCallback,
PyObject* handler);
} // namespace csv
} // namespace py
} // namespace arrow

View File

@ -0,0 +1,211 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <algorithm>
#include <chrono>
#include "arrow/python/platform.h"
#include "arrow/python/visibility.h"
#include "arrow/status.h"
#include "arrow/type.h"
#include "arrow/type_fwd.h"
#include "arrow/util/logging.h"
// By default, PyDateTimeAPI is a *static* variable. This forces
// PyDateTime_IMPORT to be called in every C/C++ module using the
// C datetime API. This is error-prone and potentially costly.
// Instead, we redefine PyDateTimeAPI to point to a global variable,
// which is initialized once by calling InitDatetime().
#define PyDateTimeAPI ::arrow::py::internal::datetime_api
namespace arrow {
namespace py {
namespace internal {
extern PyDateTime_CAPI* datetime_api;
ARROW_PYTHON_EXPORT
void InitDatetime();
// Returns the MonthDayNano namedtuple type (increments the reference count).
ARROW_PYTHON_EXPORT
PyObject* NewMonthDayNanoTupleType();
ARROW_PYTHON_EXPORT
inline int64_t PyTime_to_us(PyObject* pytime) {
return (PyDateTime_TIME_GET_HOUR(pytime) * 3600000000LL +
PyDateTime_TIME_GET_MINUTE(pytime) * 60000000LL +
PyDateTime_TIME_GET_SECOND(pytime) * 1000000LL +
PyDateTime_TIME_GET_MICROSECOND(pytime));
}
ARROW_PYTHON_EXPORT
inline int64_t PyTime_to_s(PyObject* pytime) { return PyTime_to_us(pytime) / 1000000; }
ARROW_PYTHON_EXPORT
inline int64_t PyTime_to_ms(PyObject* pytime) { return PyTime_to_us(pytime) / 1000; }
ARROW_PYTHON_EXPORT
inline int64_t PyTime_to_ns(PyObject* pytime) { return PyTime_to_us(pytime) * 1000; }
ARROW_PYTHON_EXPORT
Status PyTime_from_int(int64_t val, const TimeUnit::type unit, PyObject** out);
ARROW_PYTHON_EXPORT
Status PyDate_from_int(int64_t val, const DateUnit unit, PyObject** out);
// WARNING: This function returns a naive datetime.
ARROW_PYTHON_EXPORT
Status PyDateTime_from_int(int64_t val, const TimeUnit::type unit, PyObject** out);
// This declaration must be the same as in filesystem/filesystem.h
using TimePoint =
std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>;
ARROW_PYTHON_EXPORT
int64_t PyDate_to_days(PyDateTime_Date* pydate);
ARROW_PYTHON_EXPORT
inline int64_t PyDate_to_s(PyDateTime_Date* pydate) {
return PyDate_to_days(pydate) * 86400LL;
}
ARROW_PYTHON_EXPORT
inline int64_t PyDate_to_ms(PyDateTime_Date* pydate) {
return PyDate_to_days(pydate) * 86400000LL;
}
ARROW_PYTHON_EXPORT
inline int64_t PyDateTime_to_s(PyDateTime_DateTime* pydatetime) {
return (PyDate_to_s(reinterpret_cast<PyDateTime_Date*>(pydatetime)) +
PyDateTime_DATE_GET_HOUR(pydatetime) * 3600LL +
PyDateTime_DATE_GET_MINUTE(pydatetime) * 60LL +
PyDateTime_DATE_GET_SECOND(pydatetime));
}
ARROW_PYTHON_EXPORT
inline int64_t PyDateTime_to_ms(PyDateTime_DateTime* pydatetime) {
return (PyDateTime_to_s(pydatetime) * 1000LL +
PyDateTime_DATE_GET_MICROSECOND(pydatetime) / 1000);
}
ARROW_PYTHON_EXPORT
inline int64_t PyDateTime_to_us(PyDateTime_DateTime* pydatetime) {
return (PyDateTime_to_s(pydatetime) * 1000000LL +
PyDateTime_DATE_GET_MICROSECOND(pydatetime));
}
ARROW_PYTHON_EXPORT
inline int64_t PyDateTime_to_ns(PyDateTime_DateTime* pydatetime) {
return PyDateTime_to_us(pydatetime) * 1000LL;
}
ARROW_PYTHON_EXPORT
inline TimePoint PyDateTime_to_TimePoint(PyDateTime_DateTime* pydatetime) {
return TimePoint(TimePoint::duration(PyDateTime_to_ns(pydatetime)));
}
ARROW_PYTHON_EXPORT
inline int64_t TimePoint_to_ns(TimePoint val) { return val.time_since_epoch().count(); }
ARROW_PYTHON_EXPORT
inline TimePoint TimePoint_from_s(double val) {
return TimePoint(TimePoint::duration(static_cast<int64_t>(1e9 * val)));
}
ARROW_PYTHON_EXPORT
inline TimePoint TimePoint_from_ns(int64_t val) {
return TimePoint(TimePoint::duration(val));
}
ARROW_PYTHON_EXPORT
inline int64_t PyDelta_to_s(PyDateTime_Delta* pytimedelta) {
return (PyDateTime_DELTA_GET_DAYS(pytimedelta) * 86400LL +
PyDateTime_DELTA_GET_SECONDS(pytimedelta));
}
ARROW_PYTHON_EXPORT
inline int64_t PyDelta_to_ms(PyDateTime_Delta* pytimedelta) {
return (PyDelta_to_s(pytimedelta) * 1000LL +
PyDateTime_DELTA_GET_MICROSECONDS(pytimedelta) / 1000);
}
ARROW_PYTHON_EXPORT
inline int64_t PyDelta_to_us(PyDateTime_Delta* pytimedelta) {
return (PyDelta_to_s(pytimedelta) * 1000000LL +
PyDateTime_DELTA_GET_MICROSECONDS(pytimedelta));
}
ARROW_PYTHON_EXPORT
inline int64_t PyDelta_to_ns(PyDateTime_Delta* pytimedelta) {
return PyDelta_to_us(pytimedelta) * 1000LL;
}
ARROW_PYTHON_EXPORT
Result<int64_t> PyDateTime_utcoffset_s(PyObject* pydatetime);
/// \brief Convert a time zone name into a time zone object.
///
/// Supported input strings are:
/// * As used in the Olson time zone database (the "tz database" or
/// "tzdata"), such as "America/New_York"
/// * An absolute time zone offset of the form +XX:XX or -XX:XX, such as +07:30
/// GIL must be held when calling this method.
ARROW_PYTHON_EXPORT
Result<PyObject*> StringToTzinfo(const std::string& tz);
/// \brief Convert a time zone object to a string representation.
///
/// The output strings are:
/// * An absolute time zone offset of the form +XX:XX or -XX:XX, such as +07:30
/// if the input object is either an instance of pytz._FixedOffset or
/// datetime.timedelta
/// * The timezone's name if the input object's tzname() method returns with a
/// non-empty timezone name such as "UTC" or "America/New_York"
///
/// GIL must be held when calling this method.
ARROW_PYTHON_EXPORT
Result<std::string> TzinfoToString(PyObject* pytzinfo);
/// \brief Convert MonthDayNano to a python namedtuple.
///
/// Return a named tuple (pyarrow.MonthDayNano) containing attributes
/// "months", "days", "nanoseconds" in the given order
/// with values extracted from the fields on interval.
///
/// GIL must be held when calling this method.
ARROW_PYTHON_EXPORT
PyObject* MonthDayNanoIntervalToNamedTuple(
const MonthDayNanoIntervalType::MonthDayNanos& interval);
/// \brief Convert the given Array to a PyList object containing
/// pyarrow.MonthDayNano objects.
ARROW_PYTHON_EXPORT
Result<PyObject*> MonthDayNanoIntervalArrayToPyList(
const MonthDayNanoIntervalArray& array);
/// \brief Convert the Scalar obect to a pyarrow.MonthDayNano (or None if
/// is isn't valid).
ARROW_PYTHON_EXPORT
Result<PyObject*> MonthDayNanoIntervalScalarToPyObject(
const MonthDayNanoIntervalScalar& scalar);
} // namespace internal
} // namespace py
} // namespace arrow

View File

@ -0,0 +1,128 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <string>
#include "arrow/python/visibility.h"
#include "arrow/type.h"
namespace arrow {
class Decimal128;
class Decimal256;
namespace py {
class OwnedRef;
//
// Python Decimal support
//
namespace internal {
// \brief Import the Python Decimal type
ARROW_PYTHON_EXPORT
Status ImportDecimalType(OwnedRef* decimal_type);
// \brief Convert a Python Decimal object to a C++ string
// \param[in] python_decimal A Python decimal.Decimal instance
// \param[out] The string representation of the Python Decimal instance
// \return The status of the operation
ARROW_PYTHON_EXPORT
Status PythonDecimalToString(PyObject* python_decimal, std::string* out);
// \brief Convert a C++ std::string to a Python Decimal instance
// \param[in] decimal_constructor The decimal type object
// \param[in] decimal_string A decimal string
// \return An instance of decimal.Decimal
ARROW_PYTHON_EXPORT
PyObject* DecimalFromString(PyObject* decimal_constructor,
const std::string& decimal_string);
// \brief Convert a Python decimal to an Arrow Decimal128 object
// \param[in] python_decimal A Python decimal.Decimal instance
// \param[in] arrow_type An instance of arrow::DecimalType
// \param[out] out A pointer to a Decimal128
// \return The status of the operation
ARROW_PYTHON_EXPORT
Status DecimalFromPythonDecimal(PyObject* python_decimal, const DecimalType& arrow_type,
Decimal128* out);
// \brief Convert a Python object to an Arrow Decimal128 object
// \param[in] python_decimal A Python int or decimal.Decimal instance
// \param[in] arrow_type An instance of arrow::DecimalType
// \param[out] out A pointer to a Decimal128
// \return The status of the operation
ARROW_PYTHON_EXPORT
Status DecimalFromPyObject(PyObject* obj, const DecimalType& arrow_type, Decimal128* out);
// \brief Convert a Python decimal to an Arrow Decimal256 object
// \param[in] python_decimal A Python decimal.Decimal instance
// \param[in] arrow_type An instance of arrow::DecimalType
// \param[out] out A pointer to a Decimal256
// \return The status of the operation
ARROW_PYTHON_EXPORT
Status DecimalFromPythonDecimal(PyObject* python_decimal, const DecimalType& arrow_type,
Decimal256* out);
// \brief Convert a Python object to an Arrow Decimal256 object
// \param[in] python_decimal A Python int or decimal.Decimal instance
// \param[in] arrow_type An instance of arrow::DecimalType
// \param[out] out A pointer to a Decimal256
// \return The status of the operation
ARROW_PYTHON_EXPORT
Status DecimalFromPyObject(PyObject* obj, const DecimalType& arrow_type, Decimal256* out);
// \brief Check whether obj is an instance of Decimal
ARROW_PYTHON_EXPORT
bool PyDecimal_Check(PyObject* obj);
// \brief Check whether obj is nan. This function will abort the program if the argument
// is not a Decimal instance
ARROW_PYTHON_EXPORT
bool PyDecimal_ISNAN(PyObject* obj);
// \brief Helper class to track and update the precision and scale of a decimal
class ARROW_PYTHON_EXPORT DecimalMetadata {
public:
DecimalMetadata();
DecimalMetadata(int32_t precision, int32_t scale);
// \brief Adjust the precision and scale of a decimal type given a new precision and a
// new scale \param[in] suggested_precision A candidate precision \param[in]
// suggested_scale A candidate scale \return The status of the operation
Status Update(int32_t suggested_precision, int32_t suggested_scale);
// \brief A convenient interface for updating the precision and scale based on a Python
// Decimal object \param object A Python Decimal object \return The status of the
// operation
Status Update(PyObject* object);
int32_t precision() const { return precision_; }
int32_t scale() const { return scale_; }
private:
int32_t precision_;
int32_t scale_;
};
} // namespace internal
} // namespace py
} // namespace arrow

View File

@ -0,0 +1,106 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <cstdint>
#include <memory>
#include <vector>
#include "arrow/python/serialize.h"
#include "arrow/python/visibility.h"
#include "arrow/status.h"
namespace arrow {
class RecordBatch;
class Tensor;
namespace io {
class RandomAccessFile;
} // namespace io
namespace py {
struct ARROW_PYTHON_EXPORT SparseTensorCounts {
int coo;
int csr;
int csc;
int csf;
int ndim_csf;
int num_total_tensors() const { return coo + csr + csc + csf; }
int num_total_buffers() const {
return coo * 3 + csr * 4 + csc * 4 + 2 * ndim_csf + csf;
}
};
/// \brief Read serialized Python sequence from file interface using Arrow IPC
/// \param[in] src a RandomAccessFile
/// \param[out] out the reconstructed data
/// \return Status
ARROW_PYTHON_EXPORT
Status ReadSerializedObject(io::RandomAccessFile* src, SerializedPyObject* out);
/// \brief Reconstruct SerializedPyObject from representation produced by
/// SerializedPyObject::GetComponents.
///
/// \param[in] num_tensors number of tensors in the object
/// \param[in] num_sparse_tensors number of sparse tensors in the object
/// \param[in] num_ndarrays number of numpy Ndarrays in the object
/// \param[in] num_buffers number of buffers in the object
/// \param[in] data a list containing pyarrow.Buffer instances. It must be 1 +
/// num_tensors * 2 + num_coo_tensors * 3 + num_csr_tensors * 4 + num_csc_tensors * 4 +
/// num_csf_tensors * (2 * ndim_csf + 3) + num_buffers in length
/// \param[out] out the reconstructed object
/// \return Status
ARROW_PYTHON_EXPORT
Status GetSerializedFromComponents(int num_tensors,
const SparseTensorCounts& num_sparse_tensors,
int num_ndarrays, int num_buffers, PyObject* data,
SerializedPyObject* out);
/// \brief Reconstruct Python object from Arrow-serialized representation
/// \param[in] context Serialization context which contains custom serialization
/// and deserialization callbacks. Can be any Python object with a
/// _serialize_callback method for serialization and a _deserialize_callback
/// method for deserialization. If context is None, no custom serialization
/// will be attempted.
/// \param[in] object Object to deserialize
/// \param[in] base a Python object holding the underlying data that any NumPy
/// arrays will reference, to avoid premature deallocation
/// \param[out] out The returned object
/// \return Status
/// This acquires the GIL
ARROW_PYTHON_EXPORT
Status DeserializeObject(PyObject* context, const SerializedPyObject& object,
PyObject* base, PyObject** out);
/// \brief Reconstruct Ndarray from Arrow-serialized representation
/// \param[in] object Object to deserialize
/// \param[out] out The deserialized tensor
/// \return Status
ARROW_PYTHON_EXPORT
Status DeserializeNdarray(const SerializedPyObject& object, std::shared_ptr<Tensor>* out);
ARROW_PYTHON_EXPORT
Status NdarrayFromBuffer(std::shared_ptr<Buffer> src, std::shared_ptr<Tensor>* out);
} // namespace py
} // namespace arrow

View File

@ -0,0 +1,85 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <memory>
#include <string>
#include "arrow/extension_type.h"
#include "arrow/python/common.h"
#include "arrow/python/visibility.h"
#include "arrow/util/macros.h"
namespace arrow {
namespace py {
class ARROW_PYTHON_EXPORT PyExtensionType : public ExtensionType {
public:
// Implement extensionType API
std::string extension_name() const override { return extension_name_; }
std::string ToString() const override;
bool ExtensionEquals(const ExtensionType& other) const override;
std::shared_ptr<Array> MakeArray(std::shared_ptr<ArrayData> data) const override;
Result<std::shared_ptr<DataType>> Deserialize(
std::shared_ptr<DataType> storage_type,
const std::string& serialized) const override;
std::string Serialize() const override;
// For use from Cython
// Assumes that `typ` is borrowed
static Status FromClass(const std::shared_ptr<DataType> storage_type,
const std::string extension_name, PyObject* typ,
std::shared_ptr<ExtensionType>* out);
// Return new ref
PyObject* GetInstance() const;
Status SetInstance(PyObject*) const;
protected:
PyExtensionType(std::shared_ptr<DataType> storage_type, PyObject* typ,
PyObject* inst = NULLPTR);
PyExtensionType(std::shared_ptr<DataType> storage_type, std::string extension_name,
PyObject* typ, PyObject* inst = NULLPTR);
std::string extension_name_;
// These fields are mutable because of two-step initialization.
mutable OwnedRefNoGIL type_class_;
// A weakref or null. Storing a strong reference to the Python extension type
// instance would create an unreclaimable reference cycle between Python and C++
// (the Python instance has to keep a strong reference to the C++ ExtensionType
// in other direction). Instead, we store a weakref to the instance.
// If the weakref is dead, we reconstruct the instance from its serialized form.
mutable OwnedRefNoGIL type_instance_;
// Empty if type_instance_ is null
mutable std::string serialized_;
};
ARROW_PYTHON_EXPORT std::string PyExtensionName();
ARROW_PYTHON_EXPORT Status RegisterPyExtensionType(const std::shared_ptr<DataType>&);
ARROW_PYTHON_EXPORT Status UnregisterPyExtensionType(const std::string& type_name);
} // namespace py
} // namespace arrow

View File

@ -0,0 +1,126 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <memory>
#include <string>
#include <vector>
#include "arrow/filesystem/filesystem.h"
#include "arrow/python/common.h"
#include "arrow/python/visibility.h"
#include "arrow/util/macros.h"
namespace arrow {
namespace py {
namespace fs {
class ARROW_PYTHON_EXPORT PyFileSystemVtable {
public:
std::function<void(PyObject*, std::string* out)> get_type_name;
std::function<bool(PyObject*, const arrow::fs::FileSystem& other)> equals;
std::function<void(PyObject*, const std::string& path, arrow::fs::FileInfo* out)>
get_file_info;
std::function<void(PyObject*, const std::vector<std::string>& paths,
std::vector<arrow::fs::FileInfo>* out)>
get_file_info_vector;
std::function<void(PyObject*, const arrow::fs::FileSelector&,
std::vector<arrow::fs::FileInfo>* out)>
get_file_info_selector;
std::function<void(PyObject*, const std::string& path, bool)> create_dir;
std::function<void(PyObject*, const std::string& path)> delete_dir;
std::function<void(PyObject*, const std::string& path, bool)> delete_dir_contents;
std::function<void(PyObject*)> delete_root_dir_contents;
std::function<void(PyObject*, const std::string& path)> delete_file;
std::function<void(PyObject*, const std::string& src, const std::string& dest)> move;
std::function<void(PyObject*, const std::string& src, const std::string& dest)>
copy_file;
std::function<void(PyObject*, const std::string& path,
std::shared_ptr<io::InputStream>* out)>
open_input_stream;
std::function<void(PyObject*, const std::string& path,
std::shared_ptr<io::RandomAccessFile>* out)>
open_input_file;
std::function<void(PyObject*, const std::string& path,
const std::shared_ptr<const KeyValueMetadata>&,
std::shared_ptr<io::OutputStream>* out)>
open_output_stream;
std::function<void(PyObject*, const std::string& path,
const std::shared_ptr<const KeyValueMetadata>&,
std::shared_ptr<io::OutputStream>* out)>
open_append_stream;
std::function<void(PyObject*, const std::string& path, std::string* out)>
normalize_path;
};
class ARROW_PYTHON_EXPORT PyFileSystem : public arrow::fs::FileSystem {
public:
PyFileSystem(PyObject* handler, PyFileSystemVtable vtable);
~PyFileSystem() override;
static std::shared_ptr<PyFileSystem> Make(PyObject* handler, PyFileSystemVtable vtable);
std::string type_name() const override;
bool Equals(const FileSystem& other) const override;
Result<arrow::fs::FileInfo> GetFileInfo(const std::string& path) override;
Result<std::vector<arrow::fs::FileInfo>> GetFileInfo(
const std::vector<std::string>& paths) override;
Result<std::vector<arrow::fs::FileInfo>> GetFileInfo(
const arrow::fs::FileSelector& select) override;
Status CreateDir(const std::string& path, bool recursive = true) override;
Status DeleteDir(const std::string& path) override;
Status DeleteDirContents(const std::string& path, bool missing_dir_ok = false) override;
Status DeleteRootDirContents() override;
Status DeleteFile(const std::string& path) override;
Status Move(const std::string& src, const std::string& dest) override;
Status CopyFile(const std::string& src, const std::string& dest) override;
Result<std::shared_ptr<io::InputStream>> OpenInputStream(
const std::string& path) override;
Result<std::shared_ptr<io::RandomAccessFile>> OpenInputFile(
const std::string& path) override;
Result<std::shared_ptr<io::OutputStream>> OpenOutputStream(
const std::string& path,
const std::shared_ptr<const KeyValueMetadata>& metadata = {}) override;
Result<std::shared_ptr<io::OutputStream>> OpenAppendStream(
const std::string& path,
const std::shared_ptr<const KeyValueMetadata>& metadata = {}) override;
Result<std::string> NormalizePath(std::string path) override;
PyObject* handler() const { return handler_.obj(); }
private:
OwnedRefNoGIL handler_;
PyFileSystemVtable vtable_;
};
} // namespace fs
} // namespace py
} // namespace arrow

View File

@ -0,0 +1,350 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <memory>
#include <string>
#include <vector>
#include "arrow/flight/api.h"
#include "arrow/ipc/dictionary.h"
#include "arrow/python/common.h"
#if defined(_WIN32) || defined(__CYGWIN__) // Windows
#if defined(_MSC_VER)
#pragma warning(disable : 4251)
#else
#pragma GCC diagnostic ignored "-Wattributes"
#endif
#ifdef ARROW_STATIC
#define ARROW_PYFLIGHT_EXPORT
#elif defined(ARROW_PYFLIGHT_EXPORTING)
#define ARROW_PYFLIGHT_EXPORT __declspec(dllexport)
#else
#define ARROW_PYFLIGHT_EXPORT __declspec(dllimport)
#endif
#else // Not Windows
#ifndef ARROW_PYFLIGHT_EXPORT
#define ARROW_PYFLIGHT_EXPORT __attribute__((visibility("default")))
#endif
#endif // Non-Windows
namespace arrow {
namespace py {
namespace flight {
ARROW_PYFLIGHT_EXPORT
extern const char* kPyServerMiddlewareName;
/// \brief A table of function pointers for calling from C++ into
/// Python.
class ARROW_PYFLIGHT_EXPORT PyFlightServerVtable {
public:
std::function<Status(PyObject*, const arrow::flight::ServerCallContext&,
const arrow::flight::Criteria*,
std::unique_ptr<arrow::flight::FlightListing>*)>
list_flights;
std::function<Status(PyObject*, const arrow::flight::ServerCallContext&,
const arrow::flight::FlightDescriptor&,
std::unique_ptr<arrow::flight::FlightInfo>*)>
get_flight_info;
std::function<Status(PyObject*, const arrow::flight::ServerCallContext&,
const arrow::flight::FlightDescriptor&,
std::unique_ptr<arrow::flight::SchemaResult>*)>
get_schema;
std::function<Status(PyObject*, const arrow::flight::ServerCallContext&,
const arrow::flight::Ticket&,
std::unique_ptr<arrow::flight::FlightDataStream>*)>
do_get;
std::function<Status(PyObject*, const arrow::flight::ServerCallContext&,
std::unique_ptr<arrow::flight::FlightMessageReader>,
std::unique_ptr<arrow::flight::FlightMetadataWriter>)>
do_put;
std::function<Status(PyObject*, const arrow::flight::ServerCallContext&,
std::unique_ptr<arrow::flight::FlightMessageReader>,
std::unique_ptr<arrow::flight::FlightMessageWriter>)>
do_exchange;
std::function<Status(PyObject*, const arrow::flight::ServerCallContext&,
const arrow::flight::Action&,
std::unique_ptr<arrow::flight::ResultStream>*)>
do_action;
std::function<Status(PyObject*, const arrow::flight::ServerCallContext&,
std::vector<arrow::flight::ActionType>*)>
list_actions;
};
class ARROW_PYFLIGHT_EXPORT PyServerAuthHandlerVtable {
public:
std::function<Status(PyObject*, arrow::flight::ServerAuthSender*,
arrow::flight::ServerAuthReader*)>
authenticate;
std::function<Status(PyObject*, const std::string&, std::string*)> is_valid;
};
class ARROW_PYFLIGHT_EXPORT PyClientAuthHandlerVtable {
public:
std::function<Status(PyObject*, arrow::flight::ClientAuthSender*,
arrow::flight::ClientAuthReader*)>
authenticate;
std::function<Status(PyObject*, std::string*)> get_token;
};
/// \brief A helper to implement an auth mechanism in Python.
class ARROW_PYFLIGHT_EXPORT PyServerAuthHandler
: public arrow::flight::ServerAuthHandler {
public:
explicit PyServerAuthHandler(PyObject* handler,
const PyServerAuthHandlerVtable& vtable);
Status Authenticate(arrow::flight::ServerAuthSender* outgoing,
arrow::flight::ServerAuthReader* incoming) override;
Status IsValid(const std::string& token, std::string* peer_identity) override;
private:
OwnedRefNoGIL handler_;
PyServerAuthHandlerVtable vtable_;
};
/// \brief A helper to implement an auth mechanism in Python.
class ARROW_PYFLIGHT_EXPORT PyClientAuthHandler
: public arrow::flight::ClientAuthHandler {
public:
explicit PyClientAuthHandler(PyObject* handler,
const PyClientAuthHandlerVtable& vtable);
Status Authenticate(arrow::flight::ClientAuthSender* outgoing,
arrow::flight::ClientAuthReader* incoming) override;
Status GetToken(std::string* token) override;
private:
OwnedRefNoGIL handler_;
PyClientAuthHandlerVtable vtable_;
};
class ARROW_PYFLIGHT_EXPORT PyFlightServer : public arrow::flight::FlightServerBase {
public:
explicit PyFlightServer(PyObject* server, const PyFlightServerVtable& vtable);
// Like Serve(), but set up signals and invoke Python signal handlers
// if necessary. This function may return with a Python exception set.
Status ServeWithSignals();
Status ListFlights(const arrow::flight::ServerCallContext& context,
const arrow::flight::Criteria* criteria,
std::unique_ptr<arrow::flight::FlightListing>* listings) override;
Status GetFlightInfo(const arrow::flight::ServerCallContext& context,
const arrow::flight::FlightDescriptor& request,
std::unique_ptr<arrow::flight::FlightInfo>* info) override;
Status GetSchema(const arrow::flight::ServerCallContext& context,
const arrow::flight::FlightDescriptor& request,
std::unique_ptr<arrow::flight::SchemaResult>* result) override;
Status DoGet(const arrow::flight::ServerCallContext& context,
const arrow::flight::Ticket& request,
std::unique_ptr<arrow::flight::FlightDataStream>* stream) override;
Status DoPut(const arrow::flight::ServerCallContext& context,
std::unique_ptr<arrow::flight::FlightMessageReader> reader,
std::unique_ptr<arrow::flight::FlightMetadataWriter> writer) override;
Status DoExchange(const arrow::flight::ServerCallContext& context,
std::unique_ptr<arrow::flight::FlightMessageReader> reader,
std::unique_ptr<arrow::flight::FlightMessageWriter> writer) override;
Status DoAction(const arrow::flight::ServerCallContext& context,
const arrow::flight::Action& action,
std::unique_ptr<arrow::flight::ResultStream>* result) override;
Status ListActions(const arrow::flight::ServerCallContext& context,
std::vector<arrow::flight::ActionType>* actions) override;
private:
OwnedRefNoGIL server_;
PyFlightServerVtable vtable_;
};
/// \brief A callback that obtains the next result from a Flight action.
typedef std::function<Status(PyObject*, std::unique_ptr<arrow::flight::Result>*)>
PyFlightResultStreamCallback;
/// \brief A ResultStream built around a Python callback.
class ARROW_PYFLIGHT_EXPORT PyFlightResultStream : public arrow::flight::ResultStream {
public:
/// \brief Construct a FlightResultStream from a Python object and callback.
/// Must only be called while holding the GIL.
explicit PyFlightResultStream(PyObject* generator,
PyFlightResultStreamCallback callback);
arrow::Result<std::unique_ptr<arrow::flight::Result>> Next() override;
private:
OwnedRefNoGIL generator_;
PyFlightResultStreamCallback callback_;
};
/// \brief A wrapper around a FlightDataStream that keeps alive a
/// Python object backing it.
class ARROW_PYFLIGHT_EXPORT PyFlightDataStream : public arrow::flight::FlightDataStream {
public:
/// \brief Construct a FlightDataStream from a Python object and underlying stream.
/// Must only be called while holding the GIL.
explicit PyFlightDataStream(PyObject* data_source,
std::unique_ptr<arrow::flight::FlightDataStream> stream);
std::shared_ptr<Schema> schema() override;
arrow::Result<arrow::flight::FlightPayload> GetSchemaPayload() override;
arrow::Result<arrow::flight::FlightPayload> Next() override;
private:
OwnedRefNoGIL data_source_;
std::unique_ptr<arrow::flight::FlightDataStream> stream_;
};
class ARROW_PYFLIGHT_EXPORT PyServerMiddlewareFactory
: public arrow::flight::ServerMiddlewareFactory {
public:
/// \brief A callback to create the middleware instance in Python
typedef std::function<Status(
PyObject*, const arrow::flight::CallInfo& info,
const arrow::flight::CallHeaders& incoming_headers,
std::shared_ptr<arrow::flight::ServerMiddleware>* middleware)>
StartCallCallback;
/// \brief Must only be called while holding the GIL.
explicit PyServerMiddlewareFactory(PyObject* factory, StartCallCallback start_call);
Status StartCall(const arrow::flight::CallInfo& info,
const arrow::flight::CallHeaders& incoming_headers,
std::shared_ptr<arrow::flight::ServerMiddleware>* middleware) override;
private:
OwnedRefNoGIL factory_;
StartCallCallback start_call_;
};
class ARROW_PYFLIGHT_EXPORT PyServerMiddleware : public arrow::flight::ServerMiddleware {
public:
typedef std::function<Status(PyObject*,
arrow::flight::AddCallHeaders* outgoing_headers)>
SendingHeadersCallback;
typedef std::function<Status(PyObject*, const Status& status)> CallCompletedCallback;
struct Vtable {
SendingHeadersCallback sending_headers;
CallCompletedCallback call_completed;
};
/// \brief Must only be called while holding the GIL.
explicit PyServerMiddleware(PyObject* middleware, Vtable vtable);
void SendingHeaders(arrow::flight::AddCallHeaders* outgoing_headers) override;
void CallCompleted(const Status& status) override;
std::string name() const override;
/// \brief Get the underlying Python object.
PyObject* py_object() const;
private:
OwnedRefNoGIL middleware_;
Vtable vtable_;
};
class ARROW_PYFLIGHT_EXPORT PyClientMiddlewareFactory
: public arrow::flight::ClientMiddlewareFactory {
public:
/// \brief A callback to create the middleware instance in Python
typedef std::function<Status(
PyObject*, const arrow::flight::CallInfo& info,
std::unique_ptr<arrow::flight::ClientMiddleware>* middleware)>
StartCallCallback;
/// \brief Must only be called while holding the GIL.
explicit PyClientMiddlewareFactory(PyObject* factory, StartCallCallback start_call);
void StartCall(const arrow::flight::CallInfo& info,
std::unique_ptr<arrow::flight::ClientMiddleware>* middleware) override;
private:
OwnedRefNoGIL factory_;
StartCallCallback start_call_;
};
class ARROW_PYFLIGHT_EXPORT PyClientMiddleware : public arrow::flight::ClientMiddleware {
public:
typedef std::function<Status(PyObject*,
arrow::flight::AddCallHeaders* outgoing_headers)>
SendingHeadersCallback;
typedef std::function<Status(PyObject*,
const arrow::flight::CallHeaders& incoming_headers)>
ReceivedHeadersCallback;
typedef std::function<Status(PyObject*, const Status& status)> CallCompletedCallback;
struct Vtable {
SendingHeadersCallback sending_headers;
ReceivedHeadersCallback received_headers;
CallCompletedCallback call_completed;
};
/// \brief Must only be called while holding the GIL.
explicit PyClientMiddleware(PyObject* factory, Vtable vtable);
void SendingHeaders(arrow::flight::AddCallHeaders* outgoing_headers) override;
void ReceivedHeaders(const arrow::flight::CallHeaders& incoming_headers) override;
void CallCompleted(const Status& status) override;
private:
OwnedRefNoGIL middleware_;
Vtable vtable_;
};
/// \brief A callback that obtains the next payload from a Flight result stream.
typedef std::function<Status(PyObject*, arrow::flight::FlightPayload*)>
PyGeneratorFlightDataStreamCallback;
/// \brief A FlightDataStream built around a Python callback.
class ARROW_PYFLIGHT_EXPORT PyGeneratorFlightDataStream
: public arrow::flight::FlightDataStream {
public:
/// \brief Construct a FlightDataStream from a Python object and underlying stream.
/// Must only be called while holding the GIL.
explicit PyGeneratorFlightDataStream(PyObject* generator,
std::shared_ptr<arrow::Schema> schema,
PyGeneratorFlightDataStreamCallback callback,
const ipc::IpcWriteOptions& options);
std::shared_ptr<Schema> schema() override;
arrow::Result<arrow::flight::FlightPayload> GetSchemaPayload() override;
arrow::Result<arrow::flight::FlightPayload> Next() override;
private:
OwnedRefNoGIL generator_;
std::shared_ptr<arrow::Schema> schema_;
ipc::DictionaryFieldMapper mapper_;
ipc::IpcWriteOptions options_;
PyGeneratorFlightDataStreamCallback callback_;
};
ARROW_PYFLIGHT_EXPORT
Status CreateFlightInfo(const std::shared_ptr<arrow::Schema>& schema,
const arrow::flight::FlightDescriptor& descriptor,
const std::vector<arrow::flight::FlightEndpoint>& endpoints,
int64_t total_records, int64_t total_bytes,
std::unique_ptr<arrow::flight::FlightInfo>* out);
/// \brief Create a SchemaResult from schema.
ARROW_PYFLIGHT_EXPORT
Status CreateSchemaResult(const std::shared_ptr<arrow::Schema>& schema,
std::unique_ptr<arrow::flight::SchemaResult>* out);
} // namespace flight
} // namespace py
} // namespace arrow

View File

@ -0,0 +1,29 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include "arrow/python/visibility.h"
namespace arrow {
namespace gdb {
ARROW_PYTHON_EXPORT
void TestSession();
} // namespace gdb
} // namespace arrow

View File

@ -0,0 +1,159 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include "arrow/python/platform.h"
#include <limits>
#include <memory>
#include <string>
#include <utility>
#include "arrow/python/numpy_interop.h"
#include <numpy/halffloat.h>
#include "arrow/python/visibility.h"
#include "arrow/type.h"
#include "arrow/util/macros.h"
namespace arrow {
namespace py {
class OwnedRef;
// \brief Get an arrow DataType instance from Arrow's Type::type enum
// \param[in] type One of the values of Arrow's Type::type enum
// \return A shared pointer to DataType
ARROW_PYTHON_EXPORT std::shared_ptr<DataType> GetPrimitiveType(Type::type type);
// \brief Construct a np.float16 object from a npy_half value.
ARROW_PYTHON_EXPORT PyObject* PyHalf_FromHalf(npy_half value);
// \brief Convert a Python object to a npy_half value.
ARROW_PYTHON_EXPORT Status PyFloat_AsHalf(PyObject* obj, npy_half* out);
namespace internal {
// \brief Check that a Python module has been already imported
// \param[in] module_name The name of the module
Result<bool> IsModuleImported(const std::string& module_name);
// \brief Import a Python module
// \param[in] module_name The name of the module
// \param[out] ref The OwnedRef containing the module PyObject*
ARROW_PYTHON_EXPORT
Status ImportModule(const std::string& module_name, OwnedRef* ref);
// \brief Import an object from a Python module
// \param[in] module A Python module
// \param[in] name The name of the object to import
// \param[out] ref The OwnedRef containing the \c name attribute of the Python module \c
// module
ARROW_PYTHON_EXPORT
Status ImportFromModule(PyObject* module, const std::string& name, OwnedRef* ref);
// \brief Check whether obj is an integer, independent of Python versions.
inline bool IsPyInteger(PyObject* obj) { return PyLong_Check(obj); }
// \brief Import symbols from pandas that we need for various type-checking,
// like pandas.NaT or pandas.NA
void InitPandasStaticData();
// \brief Use pandas missing value semantics to check if a value is null
ARROW_PYTHON_EXPORT
bool PandasObjectIsNull(PyObject* obj);
// \brief Check that obj is a pandas.Timedelta instance
ARROW_PYTHON_EXPORT
bool IsPandasTimedelta(PyObject* obj);
// \brief Check that obj is a pandas.Timestamp instance
bool IsPandasTimestamp(PyObject* obj);
// \brief Returned a borrowed reference to the pandas.tseries.offsets.DateOffset
PyObject* BorrowPandasDataOffsetType();
// \brief Check whether obj is a floating-point NaN
ARROW_PYTHON_EXPORT
bool PyFloat_IsNaN(PyObject* obj);
inline bool IsPyBinary(PyObject* obj) {
return PyBytes_Check(obj) || PyByteArray_Check(obj) || PyMemoryView_Check(obj);
}
// \brief Convert a Python integer into a C integer
// \param[in] obj A Python integer
// \param[out] out A pointer to a C integer to hold the result of the conversion
// \return The status of the operation
template <typename Int>
Status CIntFromPython(PyObject* obj, Int* out, const std::string& overflow_message = "");
// \brief Convert a Python unicode string to a std::string
ARROW_PYTHON_EXPORT
Status PyUnicode_AsStdString(PyObject* obj, std::string* out);
// \brief Convert a Python bytes object to a std::string
ARROW_PYTHON_EXPORT
std::string PyBytes_AsStdString(PyObject* obj);
// \brief Call str() on the given object and return the result as a std::string
ARROW_PYTHON_EXPORT
Status PyObject_StdStringStr(PyObject* obj, std::string* out);
// \brief Return the repr() of the given object (always succeeds)
ARROW_PYTHON_EXPORT
std::string PyObject_StdStringRepr(PyObject* obj);
// \brief Cast the given size to int32_t, with error checking
inline Status CastSize(Py_ssize_t size, int32_t* out,
const char* error_msg = "Maximum size exceeded (2GB)") {
// size is assumed to be positive
if (size > std::numeric_limits<int32_t>::max()) {
return Status::Invalid(error_msg);
}
*out = static_cast<int32_t>(size);
return Status::OK();
}
inline Status CastSize(Py_ssize_t size, int64_t* out, const char* error_msg = NULLPTR) {
// size is assumed to be positive
*out = static_cast<int64_t>(size);
return Status::OK();
}
// \brief Print the Python object's __str__ form along with the passed error
// message
ARROW_PYTHON_EXPORT
Status InvalidValue(PyObject* obj, const std::string& why);
ARROW_PYTHON_EXPORT
Status InvalidType(PyObject* obj, const std::string& why);
ARROW_PYTHON_EXPORT
Status IntegerScalarToDoubleSafe(PyObject* obj, double* result);
ARROW_PYTHON_EXPORT
Status IntegerScalarToFloat32Safe(PyObject* obj, float* result);
// \brief Print Python object __repr__
void DebugPrint(PyObject* obj);
} // namespace internal
} // namespace py
} // namespace arrow

View File

@ -0,0 +1,64 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
// Functions for converting between CPython built-in data structures and Arrow
// data structures
#pragma once
#include "arrow/python/platform.h"
#include <memory>
#include "arrow/python/visibility.h"
#include "arrow/type.h"
#include "arrow/util/macros.h"
#include "arrow/python/common.h"
namespace arrow {
class Array;
class Status;
namespace py {
// These functions take a sequence input, not arbitrary iterables
/// \brief Infer Arrow type from a Python sequence
/// \param[in] obj the sequence of values
/// \param[in] mask an optional mask where True values are null. May
/// be nullptr
/// \param[in] pandas_null_sentinels use pandas's null value markers
ARROW_PYTHON_EXPORT
Result<std::shared_ptr<arrow::DataType>> InferArrowType(PyObject* obj, PyObject* mask,
bool pandas_null_sentinels);
/// Checks whether the passed Python object is a boolean scalar
ARROW_PYTHON_EXPORT
bool IsPyBool(PyObject* obj);
/// Checks whether the passed Python object is an integer scalar
ARROW_PYTHON_EXPORT
bool IsPyInt(PyObject* obj);
/// Checks whether the passed Python object is a float scalar
ARROW_PYTHON_EXPORT
bool IsPyFloat(PyObject* obj);
} // namespace py
} // namespace arrow

View File

@ -0,0 +1,26 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include "arrow/python/platform.h"
#include "arrow/python/visibility.h"
extern "C" {
ARROW_PYTHON_EXPORT
int arrow_init_numpy();
}

View File

@ -0,0 +1,116 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <memory>
#include "arrow/io/interfaces.h"
#include "arrow/io/transform.h"
#include "arrow/python/common.h"
#include "arrow/python/visibility.h"
namespace arrow {
namespace py {
class ARROW_NO_EXPORT PythonFile;
class ARROW_PYTHON_EXPORT PyReadableFile : public io::RandomAccessFile {
public:
explicit PyReadableFile(PyObject* file);
~PyReadableFile() override;
Status Close() override;
Status Abort() override;
bool closed() const override;
Result<int64_t> Read(int64_t nbytes, void* out) override;
Result<std::shared_ptr<Buffer>> Read(int64_t nbytes) override;
// Thread-safe version
Result<int64_t> ReadAt(int64_t position, int64_t nbytes, void* out) override;
// Thread-safe version
Result<std::shared_ptr<Buffer>> ReadAt(int64_t position, int64_t nbytes) override;
Result<int64_t> GetSize() override;
Status Seek(int64_t position) override;
Result<int64_t> Tell() const override;
private:
std::unique_ptr<PythonFile> file_;
};
class ARROW_PYTHON_EXPORT PyOutputStream : public io::OutputStream {
public:
explicit PyOutputStream(PyObject* file);
~PyOutputStream() override;
Status Close() override;
Status Abort() override;
bool closed() const override;
Result<int64_t> Tell() const override;
Status Write(const void* data, int64_t nbytes) override;
Status Write(const std::shared_ptr<Buffer>& buffer) override;
private:
std::unique_ptr<PythonFile> file_;
int64_t position_;
};
// TODO(wesm): seekable output files
// A Buffer subclass that keeps a PyObject reference throughout its
// lifetime, such that the Python object is kept alive as long as the
// C++ buffer is still needed.
// Keeping the reference in a Python wrapper would be incorrect as
// the Python wrapper can get destroyed even though the wrapped C++
// buffer is still alive (ARROW-2270).
class ARROW_PYTHON_EXPORT PyForeignBuffer : public Buffer {
public:
static Status Make(const uint8_t* data, int64_t size, PyObject* base,
std::shared_ptr<Buffer>* out);
private:
PyForeignBuffer(const uint8_t* data, int64_t size, PyObject* base)
: Buffer(data, size) {
Py_INCREF(base);
base_.reset(base);
}
OwnedRefNoGIL base_;
};
// All this rigamarole because Cython is really poor with std::function<>
using TransformCallback = std::function<void(
PyObject*, const std::shared_ptr<Buffer>& src, std::shared_ptr<Buffer>* out)>;
struct TransformInputStreamVTable {
TransformCallback transform;
};
ARROW_PYTHON_EXPORT
std::shared_ptr<::arrow::io::InputStream> MakeTransformInputStream(
std::shared_ptr<::arrow::io::InputStream> wrapped, TransformInputStreamVTable vtable,
PyObject* arg);
} // namespace py
} // namespace arrow

View File

@ -0,0 +1,52 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <memory>
#include "arrow/python/common.h"
#include "arrow/python/visibility.h"
#include "arrow/record_batch.h"
#include "arrow/result.h"
#include "arrow/util/macros.h"
namespace arrow {
namespace py {
class ARROW_PYTHON_EXPORT PyRecordBatchReader : public RecordBatchReader {
public:
std::shared_ptr<Schema> schema() const override;
Status ReadNext(std::shared_ptr<RecordBatch>* batch) override;
// For use from Cython
// Assumes that `iterable` is borrowed
static Result<std::shared_ptr<RecordBatchReader>> Make(std::shared_ptr<Schema>,
PyObject* iterable);
protected:
PyRecordBatchReader();
Status Init(std::shared_ptr<Schema>, PyObject* iterable);
std::shared_ptr<Schema> schema_;
OwnedRefNoGIL iterator_;
};
} // namespace py
} // namespace arrow

View File

@ -0,0 +1,194 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <utility>
#include "arrow/array/array_primitive.h"
#include "arrow/python/common.h"
#include "arrow/python/numpy_internal.h"
namespace arrow {
namespace py {
namespace internal {
using arrow::internal::checked_cast;
// Visit the Python sequence, calling the given callable on each element. If
// the callable returns a non-OK status, iteration stops and the status is
// returned.
//
// The call signature for Visitor must be
//
// Visit(PyObject* obj, int64_t index, bool* keep_going)
//
// If keep_going is set to false, the iteration terminates
template <class VisitorFunc>
inline Status VisitSequenceGeneric(PyObject* obj, int64_t offset, VisitorFunc&& func) {
// VisitorFunc may set to false to terminate iteration
bool keep_going = true;
if (PyArray_Check(obj)) {
PyArrayObject* arr_obj = reinterpret_cast<PyArrayObject*>(obj);
if (PyArray_NDIM(arr_obj) != 1) {
return Status::Invalid("Only 1D arrays accepted");
}
if (PyArray_DESCR(arr_obj)->type_num == NPY_OBJECT) {
// It's an array object, we can fetch object pointers directly
const Ndarray1DIndexer<PyObject*> objects(arr_obj);
for (int64_t i = offset; keep_going && i < objects.size(); ++i) {
RETURN_NOT_OK(func(objects[i], i, &keep_going));
}
return Status::OK();
}
// It's a non-object array, fall back on regular sequence access.
// (note PyArray_GETITEM() is slightly different: it returns standard
// Python types, not Numpy scalar types)
// This code path is inefficient: callers should implement dedicated
// logic for non-object arrays.
}
if (PySequence_Check(obj)) {
if (PyList_Check(obj) || PyTuple_Check(obj)) {
// Use fast item access
const Py_ssize_t size = PySequence_Fast_GET_SIZE(obj);
for (Py_ssize_t i = offset; keep_going && i < size; ++i) {
PyObject* value = PySequence_Fast_GET_ITEM(obj, i);
RETURN_NOT_OK(func(value, static_cast<int64_t>(i), &keep_going));
}
} else {
// Regular sequence: avoid making a potentially large copy
const Py_ssize_t size = PySequence_Size(obj);
RETURN_IF_PYERROR();
for (Py_ssize_t i = offset; keep_going && i < size; ++i) {
OwnedRef value_ref(PySequence_ITEM(obj, i));
RETURN_IF_PYERROR();
RETURN_NOT_OK(func(value_ref.obj(), static_cast<int64_t>(i), &keep_going));
}
}
} else {
return Status::TypeError("Object is not a sequence");
}
return Status::OK();
}
// Visit sequence with no null mask
template <class VisitorFunc>
inline Status VisitSequence(PyObject* obj, int64_t offset, VisitorFunc&& func) {
return VisitSequenceGeneric(
obj, offset, [&func](PyObject* value, int64_t i /* unused */, bool* keep_going) {
return func(value, keep_going);
});
}
/// Visit sequence with null mask
template <class VisitorFunc>
inline Status VisitSequenceMasked(PyObject* obj, PyObject* mo, int64_t offset,
VisitorFunc&& func) {
if (PyArray_Check(mo)) {
PyArrayObject* mask = reinterpret_cast<PyArrayObject*>(mo);
if (PyArray_NDIM(mask) != 1) {
return Status::Invalid("Mask must be 1D array");
}
if (PyArray_SIZE(mask) != static_cast<int64_t>(PySequence_Size(obj))) {
return Status::Invalid("Mask was a different length from sequence being converted");
}
const int dtype = fix_numpy_type_num(PyArray_DESCR(mask)->type_num);
if (dtype == NPY_BOOL) {
Ndarray1DIndexer<uint8_t> mask_values(mask);
return VisitSequenceGeneric(
obj, offset,
[&func, &mask_values](PyObject* value, int64_t i, bool* keep_going) {
return func(value, mask_values[i], keep_going);
});
} else {
return Status::TypeError("Mask must be boolean dtype");
}
} else if (py::is_array(mo)) {
auto unwrap_mask_result = unwrap_array(mo);
ARROW_RETURN_NOT_OK(unwrap_mask_result);
std::shared_ptr<Array> mask_ = unwrap_mask_result.ValueOrDie();
if (mask_->type_id() != Type::type::BOOL) {
return Status::TypeError("Mask must be an array of booleans");
}
if (mask_->length() != PySequence_Size(obj)) {
return Status::Invalid("Mask was a different length from sequence being converted");
}
if (mask_->null_count() != 0) {
return Status::TypeError("Mask must be an array of booleans");
}
BooleanArray* boolmask = checked_cast<BooleanArray*>(mask_.get());
return VisitSequenceGeneric(
obj, offset, [&func, &boolmask](PyObject* value, int64_t i, bool* keep_going) {
return func(value, boolmask->Value(i), keep_going);
});
} else if (PySequence_Check(mo)) {
if (PySequence_Size(mo) != PySequence_Size(obj)) {
return Status::Invalid("Mask was a different length from sequence being converted");
}
RETURN_IF_PYERROR();
return VisitSequenceGeneric(
obj, offset, [&func, &mo](PyObject* value, int64_t i, bool* keep_going) {
OwnedRef value_ref(PySequence_ITEM(mo, i));
if (!PyBool_Check(value_ref.obj()))
return Status::TypeError("Mask must be a sequence of booleans");
return func(value, value_ref.obj() == Py_True, keep_going);
});
} else {
return Status::Invalid("Null mask must be a NumPy array, Arrow array or a Sequence");
}
return Status::OK();
}
// Like IterateSequence, but accepts any generic iterable (including
// non-restartable iterators, e.g. generators).
//
// The call signature for VisitorFunc must be Visit(PyObject*, bool*
// keep_going). If keep_going is set to false, the iteration terminates
template <class VisitorFunc>
inline Status VisitIterable(PyObject* obj, VisitorFunc&& func) {
if (PySequence_Check(obj)) {
// Numpy arrays fall here as well
return VisitSequence(obj, /*offset=*/0, std::forward<VisitorFunc>(func));
}
// Fall back on the iterator protocol
OwnedRef iter_ref(PyObject_GetIter(obj));
PyObject* iter = iter_ref.obj();
RETURN_IF_PYERROR();
PyObject* value;
bool keep_going = true;
while (keep_going && (value = PyIter_Next(iter))) {
OwnedRef value_ref(value);
RETURN_NOT_OK(func(value_ref.obj(), &keep_going));
}
RETURN_IF_PYERROR(); // __next__() might have raised
return Status::OK();
}
} // namespace internal
} // namespace py
} // namespace arrow

View File

@ -0,0 +1,120 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
// Functions for converting between pandas's NumPy-based data representation
// and Arrow data structures
#pragma once
#include "arrow/python/platform.h"
#include <memory>
#include <string>
#include <vector>
#include "arrow/buffer.h"
#include "arrow/python/visibility.h"
#include "arrow/sparse_tensor.h"
namespace arrow {
class DataType;
class MemoryPool;
class Status;
class Tensor;
namespace py {
class ARROW_PYTHON_EXPORT NumPyBuffer : public Buffer {
public:
explicit NumPyBuffer(PyObject* arr);
virtual ~NumPyBuffer();
private:
PyObject* arr_;
};
ARROW_PYTHON_EXPORT
Status NumPyDtypeToArrow(PyObject* dtype, std::shared_ptr<DataType>* out);
ARROW_PYTHON_EXPORT
Status NumPyDtypeToArrow(PyArray_Descr* descr, std::shared_ptr<DataType>* out);
ARROW_PYTHON_EXPORT Status NdarrayToTensor(MemoryPool* pool, PyObject* ao,
const std::vector<std::string>& dim_names,
std::shared_ptr<Tensor>* out);
ARROW_PYTHON_EXPORT Status TensorToNdarray(const std::shared_ptr<Tensor>& tensor,
PyObject* base, PyObject** out);
ARROW_PYTHON_EXPORT Status
SparseCOOTensorToNdarray(const std::shared_ptr<SparseCOOTensor>& sparse_tensor,
PyObject* base, PyObject** out_data, PyObject** out_coords);
Status SparseCSXMatrixToNdarray(const std::shared_ptr<SparseTensor>& sparse_tensor,
PyObject* base, PyObject** out_data,
PyObject** out_indptr, PyObject** out_indices);
ARROW_PYTHON_EXPORT Status SparseCSRMatrixToNdarray(
const std::shared_ptr<SparseCSRMatrix>& sparse_tensor, PyObject* base,
PyObject** out_data, PyObject** out_indptr, PyObject** out_indices);
ARROW_PYTHON_EXPORT Status SparseCSCMatrixToNdarray(
const std::shared_ptr<SparseCSCMatrix>& sparse_tensor, PyObject* base,
PyObject** out_data, PyObject** out_indptr, PyObject** out_indices);
ARROW_PYTHON_EXPORT Status SparseCSFTensorToNdarray(
const std::shared_ptr<SparseCSFTensor>& sparse_tensor, PyObject* base,
PyObject** out_data, PyObject** out_indptr, PyObject** out_indices);
ARROW_PYTHON_EXPORT Status NdarraysToSparseCOOTensor(
MemoryPool* pool, PyObject* data_ao, PyObject* coords_ao,
const std::vector<int64_t>& shape, const std::vector<std::string>& dim_names,
std::shared_ptr<SparseCOOTensor>* out);
ARROW_PYTHON_EXPORT Status NdarraysToSparseCSRMatrix(
MemoryPool* pool, PyObject* data_ao, PyObject* indptr_ao, PyObject* indices_ao,
const std::vector<int64_t>& shape, const std::vector<std::string>& dim_names,
std::shared_ptr<SparseCSRMatrix>* out);
ARROW_PYTHON_EXPORT Status NdarraysToSparseCSCMatrix(
MemoryPool* pool, PyObject* data_ao, PyObject* indptr_ao, PyObject* indices_ao,
const std::vector<int64_t>& shape, const std::vector<std::string>& dim_names,
std::shared_ptr<SparseCSCMatrix>* out);
ARROW_PYTHON_EXPORT Status NdarraysToSparseCSFTensor(
MemoryPool* pool, PyObject* data_ao, PyObject* indptr_ao, PyObject* indices_ao,
const std::vector<int64_t>& shape, const std::vector<int64_t>& axis_order,
const std::vector<std::string>& dim_names, std::shared_ptr<SparseCSFTensor>* out);
ARROW_PYTHON_EXPORT Status
TensorToSparseCOOTensor(const std::shared_ptr<Tensor>& tensor,
std::shared_ptr<SparseCOOTensor>* csparse_tensor);
ARROW_PYTHON_EXPORT Status
TensorToSparseCSRMatrix(const std::shared_ptr<Tensor>& tensor,
std::shared_ptr<SparseCSRMatrix>* csparse_tensor);
ARROW_PYTHON_EXPORT Status
TensorToSparseCSCMatrix(const std::shared_ptr<Tensor>& tensor,
std::shared_ptr<SparseCSCMatrix>* csparse_tensor);
ARROW_PYTHON_EXPORT Status
TensorToSparseCSFTensor(const std::shared_ptr<Tensor>& tensor,
std::shared_ptr<SparseCSFTensor>* csparse_tensor);
} // namespace py
} // namespace arrow

View File

@ -0,0 +1,96 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include "arrow/python/platform.h" // IWYU pragma: export
#include <numpy/numpyconfig.h> // IWYU pragma: export
// Don't use the deprecated Numpy functions
#ifdef NPY_1_7_API_VERSION
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#else
#define NPY_ARRAY_NOTSWAPPED NPY_NOTSWAPPED
#define NPY_ARRAY_ALIGNED NPY_ALIGNED
#define NPY_ARRAY_WRITEABLE NPY_WRITEABLE
#define NPY_ARRAY_UPDATEIFCOPY NPY_UPDATEIFCOPY
#endif
// This is required to be able to access the NumPy C API properly in C++ files
// other than init.cc.
#define PY_ARRAY_UNIQUE_SYMBOL arrow_ARRAY_API
#ifndef NUMPY_IMPORT_ARRAY
#define NO_IMPORT_ARRAY
#endif
#include <numpy/arrayobject.h> // IWYU pragma: export
#include <numpy/arrayscalars.h> // IWYU pragma: export
#include <numpy/ufuncobject.h> // IWYU pragma: export
// A bit subtle. Numpy has 5 canonical integer types:
// (or, rather, type pairs: signed and unsigned)
// NPY_BYTE, NPY_SHORT, NPY_INT, NPY_LONG, NPY_LONGLONG
// It also has 4 fixed-width integer aliases.
// When mapping Arrow integer types to these 4 fixed-width aliases,
// we always miss one of the canonical types (even though it may
// have the same width as one of the aliases).
// Which one depends on the platform...
// On a LP64 system, NPY_INT64 maps to NPY_LONG and
// NPY_LONGLONG needs to be handled separately.
// On a LLP64 system, NPY_INT32 maps to NPY_LONG and
// NPY_INT needs to be handled separately.
#if NPY_BITSOF_LONG == 32 && NPY_BITSOF_LONGLONG == 64
#define NPY_INT64_IS_LONG_LONG 1
#else
#define NPY_INT64_IS_LONG_LONG 0
#endif
#if NPY_BITSOF_INT == 32 && NPY_BITSOF_LONG == 64
#define NPY_INT32_IS_INT 1
#else
#define NPY_INT32_IS_INT 0
#endif
namespace arrow {
namespace py {
inline int import_numpy() {
#ifdef NUMPY_IMPORT_ARRAY
import_array1(-1);
import_umath1(-1);
#endif
return 0;
}
// See above about the missing Numpy integer type numbers
inline int fix_numpy_type_num(int type_num) {
#if !NPY_INT32_IS_INT && NPY_BITSOF_INT == 32
if (type_num == NPY_INT) return NPY_INT32;
if (type_num == NPY_UINT) return NPY_UINT32;
#endif
#if !NPY_INT64_IS_LONG_LONG && NPY_BITSOF_LONGLONG == 64
if (type_num == NPY_LONGLONG) return NPY_INT64;
if (type_num == NPY_ULONGLONG) return NPY_UINT64;
#endif
return type_num;
}
} // namespace py
} // namespace arrow

View File

@ -0,0 +1,72 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
// Converting from pandas memory representation to Arrow data structures
#pragma once
#include "arrow/python/platform.h"
#include <memory>
#include "arrow/compute/api.h"
#include "arrow/python/visibility.h"
namespace arrow {
class Array;
class ChunkedArray;
class DataType;
class MemoryPool;
class Status;
namespace py {
/// Convert NumPy arrays to Arrow. If target data type is not known, pass a
/// type with null
///
/// \param[in] pool Memory pool for any memory allocations
/// \param[in] ao an ndarray with the array data
/// \param[in] mo an ndarray with a null mask (True is null), optional
/// \param[in] from_pandas If true, use pandas's null sentinels to determine
/// whether values are null
/// \param[in] type a specific type to cast to, may be null
/// \param[in] cast_options casting options
/// \param[out] out a ChunkedArray, to accommodate chunked output
ARROW_PYTHON_EXPORT
Status NdarrayToArrow(MemoryPool* pool, PyObject* ao, PyObject* mo, bool from_pandas,
const std::shared_ptr<DataType>& type,
const compute::CastOptions& cast_options,
std::shared_ptr<ChunkedArray>* out);
/// Safely convert NumPy arrays to Arrow. If target data type is not known,
/// pass a type with null.
///
/// \param[in] pool Memory pool for any memory allocations
/// \param[in] ao an ndarray with the array data
/// \param[in] mo an ndarray with a null mask (True is null), optional
/// \param[in] from_pandas If true, use pandas's null sentinels to determine
/// whether values are null
/// \param[in] type a specific type to cast to, may be null
/// \param[out] out a ChunkedArray, to accommodate chunked output
ARROW_PYTHON_EXPORT
Status NdarrayToArrow(MemoryPool* pool, PyObject* ao, PyObject* mo, bool from_pandas,
const std::shared_ptr<DataType>& type,
std::shared_ptr<ChunkedArray>* out);
} // namespace py
} // namespace arrow

View File

@ -0,0 +1,109 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <string>
#include "arrow/python/common.h"
#include "arrow/python/visibility.h"
#include "arrow/util/macros.h"
#include "parquet/encryption/crypto_factory.h"
#include "parquet/encryption/kms_client.h"
#include "parquet/encryption/kms_client_factory.h"
namespace arrow {
namespace py {
namespace parquet {
namespace encryption {
/// \brief A table of function pointers for calling from C++ into
/// Python.
class ARROW_PYTHON_EXPORT PyKmsClientVtable {
public:
std::function<void(PyObject*, const std::string& key_bytes,
const std::string& master_key_identifier, std::string* out)>
wrap_key;
std::function<void(PyObject*, const std::string& wrapped_key,
const std::string& master_key_identifier, std::string* out)>
unwrap_key;
};
/// \brief A helper for KmsClient implementation in Python.
class ARROW_PYTHON_EXPORT PyKmsClient : public ::parquet::encryption::KmsClient {
public:
PyKmsClient(PyObject* handler, PyKmsClientVtable vtable);
~PyKmsClient() override;
std::string WrapKey(const std::string& key_bytes,
const std::string& master_key_identifier) override;
std::string UnwrapKey(const std::string& wrapped_key,
const std::string& master_key_identifier) override;
private:
OwnedRefNoGIL handler_;
PyKmsClientVtable vtable_;
};
/// \brief A table of function pointers for calling from C++ into
/// Python.
class ARROW_PYTHON_EXPORT PyKmsClientFactoryVtable {
public:
std::function<void(
PyObject*, const ::parquet::encryption::KmsConnectionConfig& kms_connection_config,
std::shared_ptr<::parquet::encryption::KmsClient>* out)>
create_kms_client;
};
/// \brief A helper for KmsClientFactory implementation in Python.
class ARROW_PYTHON_EXPORT PyKmsClientFactory
: public ::parquet::encryption::KmsClientFactory {
public:
PyKmsClientFactory(PyObject* handler, PyKmsClientFactoryVtable vtable);
~PyKmsClientFactory() override;
std::shared_ptr<::parquet::encryption::KmsClient> CreateKmsClient(
const ::parquet::encryption::KmsConnectionConfig& kms_connection_config) override;
private:
OwnedRefNoGIL handler_;
PyKmsClientFactoryVtable vtable_;
};
/// \brief A CryptoFactory that returns Results instead of throwing exceptions.
class ARROW_PYTHON_EXPORT PyCryptoFactory : public ::parquet::encryption::CryptoFactory {
public:
arrow::Result<std::shared_ptr<::parquet::FileEncryptionProperties>>
SafeGetFileEncryptionProperties(
const ::parquet::encryption::KmsConnectionConfig& kms_connection_config,
const ::parquet::encryption::EncryptionConfiguration& encryption_config);
/// The returned FileDecryptionProperties object will use the cache inside this
/// CryptoFactory object, so please keep this
/// CryptoFactory object alive along with the returned
/// FileDecryptionProperties object.
arrow::Result<std::shared_ptr<::parquet::FileDecryptionProperties>>
SafeGetFileDecryptionProperties(
const ::parquet::encryption::KmsConnectionConfig& kms_connection_config,
const ::parquet::encryption::DecryptionConfiguration& decryption_config);
};
} // namespace encryption
} // namespace parquet
} // namespace py
} // namespace arrow

View File

@ -0,0 +1,24 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
// Often-used headers, for precompiling.
// If updating this header, please make sure you check compilation speed
// before checking in. Adding headers which are not used extremely often
// may incur a slowdown, since it makes the precompiled header heavier to load.
#include "arrow/pch.h"
#include "arrow/python/platform.h"

View File

@ -0,0 +1,36 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
// Functions for converting between pandas's NumPy-based data representation
// and Arrow data structures
#pragma once
// If PY_SSIZE_T_CLEAN is defined, argument parsing functions treat #-specifier
// to mean Py_ssize_t (defining this to suppress deprecation warning)
#define PY_SSIZE_T_CLEAN
#include <Python.h> // IWYU pragma: export
#include <datetime.h>
// Work around C2528 error
#ifdef _MSC_VER
#if _MSC_VER >= 1900
#undef timezone
#endif
#endif

View File

@ -0,0 +1,84 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include "arrow/python/platform.h"
#include <memory>
#include "arrow/python/visibility.h"
#include "arrow/sparse_tensor.h"
// Work around ARROW-2317 (C linkage warning from Cython)
extern "C++" {
namespace arrow {
class Array;
class Buffer;
class DataType;
class Field;
class RecordBatch;
class Schema;
class Status;
class Table;
class Tensor;
namespace py {
// Returns 0 on success, -1 on error.
ARROW_PYTHON_EXPORT int import_pyarrow();
#define DECLARE_WRAP_FUNCTIONS(FUNC_SUFFIX, TYPE_NAME) \
ARROW_PYTHON_EXPORT bool is_##FUNC_SUFFIX(PyObject*); \
ARROW_PYTHON_EXPORT Result<std::shared_ptr<TYPE_NAME>> unwrap_##FUNC_SUFFIX( \
PyObject*); \
ARROW_PYTHON_EXPORT PyObject* wrap_##FUNC_SUFFIX(const std::shared_ptr<TYPE_NAME>&);
DECLARE_WRAP_FUNCTIONS(buffer, Buffer)
DECLARE_WRAP_FUNCTIONS(data_type, DataType)
DECLARE_WRAP_FUNCTIONS(field, Field)
DECLARE_WRAP_FUNCTIONS(schema, Schema)
DECLARE_WRAP_FUNCTIONS(scalar, Scalar)
DECLARE_WRAP_FUNCTIONS(array, Array)
DECLARE_WRAP_FUNCTIONS(chunked_array, ChunkedArray)
DECLARE_WRAP_FUNCTIONS(sparse_coo_tensor, SparseCOOTensor)
DECLARE_WRAP_FUNCTIONS(sparse_csc_matrix, SparseCSCMatrix)
DECLARE_WRAP_FUNCTIONS(sparse_csf_tensor, SparseCSFTensor)
DECLARE_WRAP_FUNCTIONS(sparse_csr_matrix, SparseCSRMatrix)
DECLARE_WRAP_FUNCTIONS(tensor, Tensor)
DECLARE_WRAP_FUNCTIONS(batch, RecordBatch)
DECLARE_WRAP_FUNCTIONS(table, Table)
#undef DECLARE_WRAP_FUNCTIONS
namespace internal {
ARROW_PYTHON_EXPORT int check_status(const Status& status);
} // namespace internal
} // namespace py
} // namespace arrow
} // extern "C++"

View File

@ -0,0 +1,239 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
// DO NOT EDIT THIS FILE. Update from pyarrow/lib_api.h after pyarrow build
// This is used to be able to call back into Cython code from C++.
/* Generated by Cython 0.29.15 */
#ifndef __PYX_HAVE_API__pyarrow__lib
#define __PYX_HAVE_API__pyarrow__lib
#ifdef __MINGW64__
#define MS_WIN64
#endif
#include "Python.h"
#include "pyarrow_lib.h"
static PyObject *(*__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_scalar)(std::shared_ptr< arrow::Scalar> const &) = 0;
#define pyarrow_wrap_scalar __pyx_api_f_7pyarrow_3lib_pyarrow_wrap_scalar
static PyObject *(*__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_array)(std::shared_ptr< arrow::Array> const &) = 0;
#define pyarrow_wrap_array __pyx_api_f_7pyarrow_3lib_pyarrow_wrap_array
static PyObject *(*__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_chunked_array)(std::shared_ptr< arrow::ChunkedArray> const &) = 0;
#define pyarrow_wrap_chunked_array __pyx_api_f_7pyarrow_3lib_pyarrow_wrap_chunked_array
static PyObject *(*__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_batch)(std::shared_ptr< arrow::RecordBatch> const &) = 0;
#define pyarrow_wrap_batch __pyx_api_f_7pyarrow_3lib_pyarrow_wrap_batch
static PyObject *(*__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_buffer)(std::shared_ptr< arrow::Buffer> const &) = 0;
#define pyarrow_wrap_buffer __pyx_api_f_7pyarrow_3lib_pyarrow_wrap_buffer
static PyObject *(*__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_data_type)(std::shared_ptr< arrow::DataType> const &) = 0;
#define pyarrow_wrap_data_type __pyx_api_f_7pyarrow_3lib_pyarrow_wrap_data_type
static PyObject *(*__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_field)(std::shared_ptr< arrow::Field> const &) = 0;
#define pyarrow_wrap_field __pyx_api_f_7pyarrow_3lib_pyarrow_wrap_field
static PyObject *(*__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_resizable_buffer)(std::shared_ptr< arrow::ResizableBuffer> const &) = 0;
#define pyarrow_wrap_resizable_buffer __pyx_api_f_7pyarrow_3lib_pyarrow_wrap_resizable_buffer
static PyObject *(*__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_schema)(std::shared_ptr< arrow::Schema> const &) = 0;
#define pyarrow_wrap_schema __pyx_api_f_7pyarrow_3lib_pyarrow_wrap_schema
static PyObject *(*__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_table)(std::shared_ptr< arrow::Table> const &) = 0;
#define pyarrow_wrap_table __pyx_api_f_7pyarrow_3lib_pyarrow_wrap_table
static PyObject *(*__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_tensor)(std::shared_ptr< arrow::Tensor> const &) = 0;
#define pyarrow_wrap_tensor __pyx_api_f_7pyarrow_3lib_pyarrow_wrap_tensor
static PyObject *(*__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_sparse_coo_tensor)(std::shared_ptr< arrow::SparseCOOTensor> const &) = 0;
#define pyarrow_wrap_sparse_coo_tensor __pyx_api_f_7pyarrow_3lib_pyarrow_wrap_sparse_coo_tensor
static PyObject *(*__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_sparse_csr_matrix)(std::shared_ptr< arrow::SparseCSRMatrix> const &) = 0;
#define pyarrow_wrap_sparse_csr_matrix __pyx_api_f_7pyarrow_3lib_pyarrow_wrap_sparse_csr_matrix
static PyObject *(*__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_sparse_csc_matrix)(std::shared_ptr< arrow::SparseCSCMatrix> const &) = 0;
#define pyarrow_wrap_sparse_csc_matrix __pyx_api_f_7pyarrow_3lib_pyarrow_wrap_sparse_csc_matrix
static PyObject *(*__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_sparse_csf_tensor)(std::shared_ptr< arrow::SparseCSFTensor> const &) = 0;
#define pyarrow_wrap_sparse_csf_tensor __pyx_api_f_7pyarrow_3lib_pyarrow_wrap_sparse_csf_tensor
static std::shared_ptr< arrow::Scalar> (*__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_scalar)(PyObject *) = 0;
#define pyarrow_unwrap_scalar __pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_scalar
static std::shared_ptr< arrow::Array> (*__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_array)(PyObject *) = 0;
#define pyarrow_unwrap_array __pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_array
static std::shared_ptr< arrow::ChunkedArray> (*__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_chunked_array)(PyObject *) = 0;
#define pyarrow_unwrap_chunked_array __pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_chunked_array
static std::shared_ptr< arrow::RecordBatch> (*__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_batch)(PyObject *) = 0;
#define pyarrow_unwrap_batch __pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_batch
static std::shared_ptr< arrow::Buffer> (*__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_buffer)(PyObject *) = 0;
#define pyarrow_unwrap_buffer __pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_buffer
static std::shared_ptr< arrow::DataType> (*__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_data_type)(PyObject *) = 0;
#define pyarrow_unwrap_data_type __pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_data_type
static std::shared_ptr< arrow::Field> (*__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_field)(PyObject *) = 0;
#define pyarrow_unwrap_field __pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_field
static std::shared_ptr< arrow::Schema> (*__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_schema)(PyObject *) = 0;
#define pyarrow_unwrap_schema __pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_schema
static std::shared_ptr< arrow::Table> (*__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_table)(PyObject *) = 0;
#define pyarrow_unwrap_table __pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_table
static std::shared_ptr< arrow::Tensor> (*__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_tensor)(PyObject *) = 0;
#define pyarrow_unwrap_tensor __pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_tensor
static std::shared_ptr< arrow::SparseCOOTensor> (*__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_sparse_coo_tensor)(PyObject *) = 0;
#define pyarrow_unwrap_sparse_coo_tensor __pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_sparse_coo_tensor
static std::shared_ptr< arrow::SparseCSRMatrix> (*__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_sparse_csr_matrix)(PyObject *) = 0;
#define pyarrow_unwrap_sparse_csr_matrix __pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_sparse_csr_matrix
static std::shared_ptr< arrow::SparseCSCMatrix> (*__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_sparse_csc_matrix)(PyObject *) = 0;
#define pyarrow_unwrap_sparse_csc_matrix __pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_sparse_csc_matrix
static std::shared_ptr< arrow::SparseCSFTensor> (*__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_sparse_csf_tensor)(PyObject *) = 0;
#define pyarrow_unwrap_sparse_csf_tensor __pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_sparse_csf_tensor
static int (*__pyx_api_f_7pyarrow_3lib_pyarrow_internal_check_status)(arrow::Status const &) = 0;
#define pyarrow_internal_check_status __pyx_api_f_7pyarrow_3lib_pyarrow_internal_check_status
static int (*__pyx_api_f_7pyarrow_3lib_pyarrow_is_buffer)(PyObject *) = 0;
#define pyarrow_is_buffer __pyx_api_f_7pyarrow_3lib_pyarrow_is_buffer
static int (*__pyx_api_f_7pyarrow_3lib_pyarrow_is_data_type)(PyObject *) = 0;
#define pyarrow_is_data_type __pyx_api_f_7pyarrow_3lib_pyarrow_is_data_type
static int (*__pyx_api_f_7pyarrow_3lib_pyarrow_is_metadata)(PyObject *) = 0;
#define pyarrow_is_metadata __pyx_api_f_7pyarrow_3lib_pyarrow_is_metadata
static int (*__pyx_api_f_7pyarrow_3lib_pyarrow_is_field)(PyObject *) = 0;
#define pyarrow_is_field __pyx_api_f_7pyarrow_3lib_pyarrow_is_field
static int (*__pyx_api_f_7pyarrow_3lib_pyarrow_is_schema)(PyObject *) = 0;
#define pyarrow_is_schema __pyx_api_f_7pyarrow_3lib_pyarrow_is_schema
static int (*__pyx_api_f_7pyarrow_3lib_pyarrow_is_array)(PyObject *) = 0;
#define pyarrow_is_array __pyx_api_f_7pyarrow_3lib_pyarrow_is_array
static int (*__pyx_api_f_7pyarrow_3lib_pyarrow_is_chunked_array)(PyObject *) = 0;
#define pyarrow_is_chunked_array __pyx_api_f_7pyarrow_3lib_pyarrow_is_chunked_array
static int (*__pyx_api_f_7pyarrow_3lib_pyarrow_is_scalar)(PyObject *) = 0;
#define pyarrow_is_scalar __pyx_api_f_7pyarrow_3lib_pyarrow_is_scalar
static int (*__pyx_api_f_7pyarrow_3lib_pyarrow_is_tensor)(PyObject *) = 0;
#define pyarrow_is_tensor __pyx_api_f_7pyarrow_3lib_pyarrow_is_tensor
static int (*__pyx_api_f_7pyarrow_3lib_pyarrow_is_sparse_coo_tensor)(PyObject *) = 0;
#define pyarrow_is_sparse_coo_tensor __pyx_api_f_7pyarrow_3lib_pyarrow_is_sparse_coo_tensor
static int (*__pyx_api_f_7pyarrow_3lib_pyarrow_is_sparse_csr_matrix)(PyObject *) = 0;
#define pyarrow_is_sparse_csr_matrix __pyx_api_f_7pyarrow_3lib_pyarrow_is_sparse_csr_matrix
static int (*__pyx_api_f_7pyarrow_3lib_pyarrow_is_sparse_csc_matrix)(PyObject *) = 0;
#define pyarrow_is_sparse_csc_matrix __pyx_api_f_7pyarrow_3lib_pyarrow_is_sparse_csc_matrix
static int (*__pyx_api_f_7pyarrow_3lib_pyarrow_is_sparse_csf_tensor)(PyObject *) = 0;
#define pyarrow_is_sparse_csf_tensor __pyx_api_f_7pyarrow_3lib_pyarrow_is_sparse_csf_tensor
static int (*__pyx_api_f_7pyarrow_3lib_pyarrow_is_table)(PyObject *) = 0;
#define pyarrow_is_table __pyx_api_f_7pyarrow_3lib_pyarrow_is_table
static int (*__pyx_api_f_7pyarrow_3lib_pyarrow_is_batch)(PyObject *) = 0;
#define pyarrow_is_batch __pyx_api_f_7pyarrow_3lib_pyarrow_is_batch
#if !defined(__Pyx_PyIdentifier_FromString)
#if PY_MAJOR_VERSION < 3
#define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s)
#else
#define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s)
#endif
#endif
#ifndef __PYX_HAVE_RT_ImportFunction
#define __PYX_HAVE_RT_ImportFunction
static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig) {
PyObject *d = 0;
PyObject *cobj = 0;
union {
void (*fp)(void);
void *p;
} tmp;
d = PyObject_GetAttrString(module, (char *)"__pyx_capi__");
if (!d)
goto bad;
cobj = PyDict_GetItemString(d, funcname);
if (!cobj) {
PyErr_Format(PyExc_ImportError,
"%.200s does not export expected C function %.200s",
PyModule_GetName(module), funcname);
goto bad;
}
#if PY_VERSION_HEX >= 0x02070000
if (!PyCapsule_IsValid(cobj, sig)) {
PyErr_Format(PyExc_TypeError,
"C function %.200s.%.200s has wrong signature (expected %.500s, got %.500s)",
PyModule_GetName(module), funcname, sig, PyCapsule_GetName(cobj));
goto bad;
}
tmp.p = PyCapsule_GetPointer(cobj, sig);
#else
{const char *desc, *s1, *s2;
desc = (const char *)PyCObject_GetDesc(cobj);
if (!desc)
goto bad;
s1 = desc; s2 = sig;
while (*s1 != '\0' && *s1 == *s2) { s1++; s2++; }
if (*s1 != *s2) {
PyErr_Format(PyExc_TypeError,
"C function %.200s.%.200s has wrong signature (expected %.500s, got %.500s)",
PyModule_GetName(module), funcname, sig, desc);
goto bad;
}
tmp.p = PyCObject_AsVoidPtr(cobj);}
#endif
*f = tmp.fp;
if (!(*f))
goto bad;
Py_DECREF(d);
return 0;
bad:
Py_XDECREF(d);
return -1;
}
#endif
static int import_pyarrow__lib(void) {
PyObject *module = 0;
module = PyImport_ImportModule("pyarrow.lib");
if (!module) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_wrap_scalar", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_scalar, "PyObject *(std::shared_ptr< arrow::Scalar> const &)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_wrap_array", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_array, "PyObject *(std::shared_ptr< arrow::Array> const &)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_wrap_chunked_array", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_chunked_array, "PyObject *(std::shared_ptr< arrow::ChunkedArray> const &)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_wrap_batch", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_batch, "PyObject *(std::shared_ptr< arrow::RecordBatch> const &)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_wrap_buffer", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_buffer, "PyObject *(std::shared_ptr< arrow::Buffer> const &)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_wrap_data_type", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_data_type, "PyObject *(std::shared_ptr< arrow::DataType> const &)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_wrap_field", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_field, "PyObject *(std::shared_ptr< arrow::Field> const &)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_wrap_resizable_buffer", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_resizable_buffer, "PyObject *(std::shared_ptr< arrow::ResizableBuffer> const &)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_wrap_schema", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_schema, "PyObject *(std::shared_ptr< arrow::Schema> const &)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_wrap_table", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_table, "PyObject *(std::shared_ptr< arrow::Table> const &)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_wrap_tensor", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_tensor, "PyObject *(std::shared_ptr< arrow::Tensor> const &)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_wrap_sparse_coo_tensor", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_sparse_coo_tensor, "PyObject *(std::shared_ptr< arrow::SparseCOOTensor> const &)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_wrap_sparse_csr_matrix", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_sparse_csr_matrix, "PyObject *(std::shared_ptr< arrow::SparseCSRMatrix> const &)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_wrap_sparse_csc_matrix", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_sparse_csc_matrix, "PyObject *(std::shared_ptr< arrow::SparseCSCMatrix> const &)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_wrap_sparse_csf_tensor", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_wrap_sparse_csf_tensor, "PyObject *(std::shared_ptr< arrow::SparseCSFTensor> const &)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_unwrap_scalar", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_scalar, "std::shared_ptr< arrow::Scalar> (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_unwrap_array", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_array, "std::shared_ptr< arrow::Array> (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_unwrap_chunked_array", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_chunked_array, "std::shared_ptr< arrow::ChunkedArray> (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_unwrap_batch", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_batch, "std::shared_ptr< arrow::RecordBatch> (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_unwrap_buffer", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_buffer, "std::shared_ptr< arrow::Buffer> (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_unwrap_data_type", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_data_type, "std::shared_ptr< arrow::DataType> (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_unwrap_field", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_field, "std::shared_ptr< arrow::Field> (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_unwrap_schema", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_schema, "std::shared_ptr< arrow::Schema> (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_unwrap_table", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_table, "std::shared_ptr< arrow::Table> (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_unwrap_tensor", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_tensor, "std::shared_ptr< arrow::Tensor> (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_unwrap_sparse_coo_tensor", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_sparse_coo_tensor, "std::shared_ptr< arrow::SparseCOOTensor> (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_unwrap_sparse_csr_matrix", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_sparse_csr_matrix, "std::shared_ptr< arrow::SparseCSRMatrix> (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_unwrap_sparse_csc_matrix", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_sparse_csc_matrix, "std::shared_ptr< arrow::SparseCSCMatrix> (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_unwrap_sparse_csf_tensor", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_unwrap_sparse_csf_tensor, "std::shared_ptr< arrow::SparseCSFTensor> (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_internal_check_status", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_internal_check_status, "int (arrow::Status const &)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_is_buffer", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_is_buffer, "int (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_is_data_type", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_is_data_type, "int (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_is_metadata", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_is_metadata, "int (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_is_field", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_is_field, "int (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_is_schema", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_is_schema, "int (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_is_array", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_is_array, "int (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_is_chunked_array", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_is_chunked_array, "int (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_is_scalar", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_is_scalar, "int (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_is_tensor", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_is_tensor, "int (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_is_sparse_coo_tensor", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_is_sparse_coo_tensor, "int (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_is_sparse_csr_matrix", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_is_sparse_csr_matrix, "int (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_is_sparse_csc_matrix", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_is_sparse_csc_matrix, "int (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_is_sparse_csf_tensor", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_is_sparse_csf_tensor, "int (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_is_table", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_is_table, "int (PyObject *)") < 0) goto bad;
if (__Pyx_ImportFunction(module, "pyarrow_is_batch", (void (**)(void))&__pyx_api_f_7pyarrow_3lib_pyarrow_is_batch, "int (PyObject *)") < 0) goto bad;
Py_DECREF(module); module = 0;
return 0;
bad:
Py_XDECREF(module);
return -1;
}
#endif /* !__PYX_HAVE_API__pyarrow__lib */

View File

@ -0,0 +1,82 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
// DO NOT EDIT THIS FILE. Update from pyarrow/lib.h after pyarrow build
/* Generated by Cython 0.29.15 */
#ifndef __PYX_HAVE__pyarrow__lib
#define __PYX_HAVE__pyarrow__lib
#include "Python.h"
#ifndef __PYX_HAVE_API__pyarrow__lib
#ifndef __PYX_EXTERN_C
#ifdef __cplusplus
#define __PYX_EXTERN_C extern "C"
#else
#define __PYX_EXTERN_C extern
#endif
#endif
#ifndef DL_IMPORT
#define DL_IMPORT(_T) _T
#endif
__PYX_EXTERN_C PyObject *__pyx_f_7pyarrow_3lib_pyarrow_wrap_scalar(std::shared_ptr< arrow::Scalar> const &);
__PYX_EXTERN_C PyObject *__pyx_f_7pyarrow_3lib_pyarrow_wrap_array(std::shared_ptr< arrow::Array> const &);
__PYX_EXTERN_C PyObject *__pyx_f_7pyarrow_3lib_pyarrow_wrap_chunked_array(std::shared_ptr< arrow::ChunkedArray> const &);
__PYX_EXTERN_C PyObject *__pyx_f_7pyarrow_3lib_pyarrow_wrap_batch(std::shared_ptr< arrow::RecordBatch> const &);
__PYX_EXTERN_C PyObject *__pyx_f_7pyarrow_3lib_pyarrow_wrap_buffer(std::shared_ptr< arrow::Buffer> const &);
__PYX_EXTERN_C PyObject *__pyx_f_7pyarrow_3lib_pyarrow_wrap_data_type(std::shared_ptr< arrow::DataType> const &);
__PYX_EXTERN_C PyObject *__pyx_f_7pyarrow_3lib_pyarrow_wrap_field(std::shared_ptr< arrow::Field> const &);
__PYX_EXTERN_C PyObject *__pyx_f_7pyarrow_3lib_pyarrow_wrap_resizable_buffer(std::shared_ptr< arrow::ResizableBuffer> const &);
__PYX_EXTERN_C PyObject *__pyx_f_7pyarrow_3lib_pyarrow_wrap_schema(std::shared_ptr< arrow::Schema> const &);
__PYX_EXTERN_C PyObject *__pyx_f_7pyarrow_3lib_pyarrow_wrap_table(std::shared_ptr< arrow::Table> const &);
__PYX_EXTERN_C PyObject *__pyx_f_7pyarrow_3lib_pyarrow_wrap_tensor(std::shared_ptr< arrow::Tensor> const &);
__PYX_EXTERN_C PyObject *__pyx_f_7pyarrow_3lib_pyarrow_wrap_sparse_coo_tensor(std::shared_ptr< arrow::SparseCOOTensor> const &);
__PYX_EXTERN_C PyObject *__pyx_f_7pyarrow_3lib_pyarrow_wrap_sparse_csr_matrix(std::shared_ptr< arrow::SparseCSRMatrix> const &);
__PYX_EXTERN_C PyObject *__pyx_f_7pyarrow_3lib_pyarrow_wrap_sparse_csc_matrix(std::shared_ptr< arrow::SparseCSCMatrix> const &);
__PYX_EXTERN_C PyObject *__pyx_f_7pyarrow_3lib_pyarrow_wrap_sparse_csf_tensor(std::shared_ptr< arrow::SparseCSFTensor> const &);
__PYX_EXTERN_C std::shared_ptr< arrow::Scalar> __pyx_f_7pyarrow_3lib_pyarrow_unwrap_scalar(PyObject *);
__PYX_EXTERN_C std::shared_ptr< arrow::Array> __pyx_f_7pyarrow_3lib_pyarrow_unwrap_array(PyObject *);
__PYX_EXTERN_C std::shared_ptr< arrow::ChunkedArray> __pyx_f_7pyarrow_3lib_pyarrow_unwrap_chunked_array(PyObject *);
__PYX_EXTERN_C std::shared_ptr< arrow::RecordBatch> __pyx_f_7pyarrow_3lib_pyarrow_unwrap_batch(PyObject *);
__PYX_EXTERN_C std::shared_ptr< arrow::Buffer> __pyx_f_7pyarrow_3lib_pyarrow_unwrap_buffer(PyObject *);
__PYX_EXTERN_C std::shared_ptr< arrow::DataType> __pyx_f_7pyarrow_3lib_pyarrow_unwrap_data_type(PyObject *);
__PYX_EXTERN_C std::shared_ptr< arrow::Field> __pyx_f_7pyarrow_3lib_pyarrow_unwrap_field(PyObject *);
__PYX_EXTERN_C std::shared_ptr< arrow::Schema> __pyx_f_7pyarrow_3lib_pyarrow_unwrap_schema(PyObject *);
__PYX_EXTERN_C std::shared_ptr< arrow::Table> __pyx_f_7pyarrow_3lib_pyarrow_unwrap_table(PyObject *);
__PYX_EXTERN_C std::shared_ptr< arrow::Tensor> __pyx_f_7pyarrow_3lib_pyarrow_unwrap_tensor(PyObject *);
__PYX_EXTERN_C std::shared_ptr< arrow::SparseCOOTensor> __pyx_f_7pyarrow_3lib_pyarrow_unwrap_sparse_coo_tensor(PyObject *);
__PYX_EXTERN_C std::shared_ptr< arrow::SparseCSRMatrix> __pyx_f_7pyarrow_3lib_pyarrow_unwrap_sparse_csr_matrix(PyObject *);
__PYX_EXTERN_C std::shared_ptr< arrow::SparseCSCMatrix> __pyx_f_7pyarrow_3lib_pyarrow_unwrap_sparse_csc_matrix(PyObject *);
__PYX_EXTERN_C std::shared_ptr< arrow::SparseCSFTensor> __pyx_f_7pyarrow_3lib_pyarrow_unwrap_sparse_csf_tensor(PyObject *);
#endif /* !__PYX_HAVE_API__pyarrow__lib */
/* WARNING: the interface of the module init function changed in CPython 3.5. */
/* It now returns a PyModuleDef instance instead of a PyModule instance. */
#if PY_MAJOR_VERSION < 3
PyMODINIT_FUNC initlib(void);
#else
PyMODINIT_FUNC PyInit_lib(void);
#endif
#endif /* !__PYX_HAVE__pyarrow__lib */

View File

@ -0,0 +1,80 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
// Functions for converting between CPython built-in data structures and Arrow
// data structures
#pragma once
#include "arrow/python/platform.h"
#include <cstdint>
#include <memory>
#include "arrow/python/visibility.h"
#include "arrow/type.h"
#include "arrow/util/macros.h"
#include "arrow/python/common.h"
namespace arrow {
class Array;
class Status;
namespace py {
struct PyConversionOptions {
PyConversionOptions() = default;
PyConversionOptions(const std::shared_ptr<DataType>& type, int64_t size,
MemoryPool* pool, bool from_pandas)
: type(type), size(size), from_pandas(from_pandas) {}
// Set to null if to be inferred
std::shared_ptr<DataType> type;
// Default is -1, which indicates the size should the same as the input sequence
int64_t size = -1;
bool from_pandas = false;
/// Used to maintain backwards compatibility for
/// timezone bugs (see ARROW-9528). Should be removed
/// after Arrow 2.0 release.
bool ignore_timezone = false;
bool strict = false;
};
/// \brief Convert sequence (list, generator, NumPy array with dtype object) of
/// Python objects.
/// \param[in] obj the sequence to convert
/// \param[in] mask a NumPy array of true/false values to indicate whether
/// values in the sequence are null (true) or not null (false). This parameter
/// may be null
/// \param[in] options various conversion options
/// \param[in] pool MemoryPool to use for allocations
/// \return Result ChunkedArray
ARROW_PYTHON_EXPORT
Result<std::shared_ptr<ChunkedArray>> ConvertPySequence(
PyObject* obj, PyObject* mask, PyConversionOptions options,
MemoryPool* pool = default_memory_pool());
} // namespace py
} // namespace arrow

View File

@ -0,0 +1,145 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#include <memory>
#include <vector>
#include "arrow/ipc/options.h"
#include "arrow/python/visibility.h"
#include "arrow/sparse_tensor.h"
#include "arrow/status.h"
// Forward declaring PyObject, see
// https://mail.python.org/pipermail/python-dev/2003-August/037601.html
#ifndef PyObject_HEAD
struct _object;
typedef _object PyObject;
#endif
namespace arrow {
class Buffer;
class DataType;
class MemoryPool;
class RecordBatch;
class Tensor;
namespace io {
class OutputStream;
} // namespace io
namespace py {
struct ARROW_PYTHON_EXPORT SerializedPyObject {
std::shared_ptr<RecordBatch> batch;
std::vector<std::shared_ptr<Tensor>> tensors;
std::vector<std::shared_ptr<SparseTensor>> sparse_tensors;
std::vector<std::shared_ptr<Tensor>> ndarrays;
std::vector<std::shared_ptr<Buffer>> buffers;
ipc::IpcWriteOptions ipc_options;
SerializedPyObject();
/// \brief Write serialized Python object to OutputStream
/// \param[in,out] dst an OutputStream
/// \return Status
Status WriteTo(io::OutputStream* dst);
/// \brief Convert SerializedPyObject to a dict containing the message
/// components as Buffer instances with minimal memory allocation
///
/// {
/// 'num_tensors': M,
/// 'num_sparse_tensors': N,
/// 'num_buffers': K,
/// 'data': [Buffer]
/// }
///
/// Each tensor is written as two buffers, one for the metadata and one for
/// the body. Therefore, the number of buffers in 'data' is 2 * M + 2 * N + K + 1,
/// with the first buffer containing the serialized record batch containing
/// the UnionArray that describes the whole object
Status GetComponents(MemoryPool* pool, PyObject** out);
};
/// \brief Serialize Python sequence as a SerializedPyObject.
/// \param[in] context Serialization context which contains custom serialization
/// and deserialization callbacks. Can be any Python object with a
/// _serialize_callback method for serialization and a _deserialize_callback
/// method for deserialization. If context is None, no custom serialization
/// will be attempted.
/// \param[in] sequence A Python sequence object to serialize to Arrow data
/// structures
/// \param[out] out The serialized representation
/// \return Status
///
/// Release GIL before calling
ARROW_PYTHON_EXPORT
Status SerializeObject(PyObject* context, PyObject* sequence, SerializedPyObject* out);
/// \brief Serialize an Arrow Tensor as a SerializedPyObject.
/// \param[in] tensor Tensor to be serialized
/// \param[out] out The serialized representation
/// \return Status
ARROW_PYTHON_EXPORT
Status SerializeTensor(std::shared_ptr<Tensor> tensor, py::SerializedPyObject* out);
/// \brief Write the Tensor metadata header to an OutputStream.
/// \param[in] dtype DataType of the Tensor
/// \param[in] shape The shape of the tensor
/// \param[in] tensor_num_bytes The length of the Tensor data in bytes
/// \param[in] dst The OutputStream to write the Tensor header to
/// \return Status
ARROW_PYTHON_EXPORT
Status WriteNdarrayHeader(std::shared_ptr<DataType> dtype,
const std::vector<int64_t>& shape, int64_t tensor_num_bytes,
io::OutputStream* dst);
struct PythonType {
enum type {
NONE,
BOOL,
INT,
PY2INT, // Kept for compatibility
BYTES,
STRING,
HALF_FLOAT,
FLOAT,
DOUBLE,
DATE64,
LIST,
DICT,
TUPLE,
SET,
TENSOR,
NDARRAY,
BUFFER,
SPARSECOOTENSOR,
SPARSECSRMATRIX,
SPARSECSCMATRIX,
SPARSECSFTENSOR,
NUM_PYTHON_TYPES
};
};
} // namespace py
} // namespace arrow

View File

@ -0,0 +1,350 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
// Internal header
#pragma once
#include "arrow/python/platform.h"
#include <cstdint>
#include <limits>
#include "arrow/python/numpy_interop.h"
#include <numpy/halffloat.h>
#include "arrow/type_fwd.h"
#include "arrow/util/logging.h"
namespace arrow {
namespace py {
static constexpr int64_t kPandasTimestampNull = std::numeric_limits<int64_t>::min();
constexpr int64_t kNanosecondsInDay = 86400000000000LL;
namespace internal {
//
// Type traits for Numpy -> Arrow equivalence
//
template <int TYPE>
struct npy_traits {};
template <>
struct npy_traits<NPY_BOOL> {
typedef uint8_t value_type;
using TypeClass = BooleanType;
using BuilderClass = BooleanBuilder;
static constexpr bool supports_nulls = false;
static inline bool isnull(uint8_t v) { return false; }
};
#define NPY_INT_DECL(TYPE, CapType, T) \
template <> \
struct npy_traits<NPY_##TYPE> { \
typedef T value_type; \
using TypeClass = CapType##Type; \
using BuilderClass = CapType##Builder; \
\
static constexpr bool supports_nulls = false; \
static inline bool isnull(T v) { return false; } \
};
NPY_INT_DECL(INT8, Int8, int8_t);
NPY_INT_DECL(INT16, Int16, int16_t);
NPY_INT_DECL(INT32, Int32, int32_t);
NPY_INT_DECL(INT64, Int64, int64_t);
NPY_INT_DECL(UINT8, UInt8, uint8_t);
NPY_INT_DECL(UINT16, UInt16, uint16_t);
NPY_INT_DECL(UINT32, UInt32, uint32_t);
NPY_INT_DECL(UINT64, UInt64, uint64_t);
#if !NPY_INT32_IS_INT && NPY_BITSOF_INT == 32
NPY_INT_DECL(INT, Int32, int32_t);
NPY_INT_DECL(UINT, UInt32, uint32_t);
#endif
#if !NPY_INT64_IS_LONG_LONG && NPY_BITSOF_LONGLONG == 64
NPY_INT_DECL(LONGLONG, Int64, int64_t);
NPY_INT_DECL(ULONGLONG, UInt64, uint64_t);
#endif
template <>
struct npy_traits<NPY_FLOAT16> {
typedef npy_half value_type;
using TypeClass = HalfFloatType;
using BuilderClass = HalfFloatBuilder;
static constexpr npy_half na_sentinel = NPY_HALF_NAN;
static constexpr bool supports_nulls = true;
static inline bool isnull(npy_half v) { return v == NPY_HALF_NAN; }
};
template <>
struct npy_traits<NPY_FLOAT32> {
typedef float value_type;
using TypeClass = FloatType;
using BuilderClass = FloatBuilder;
// We need to use quiet_NaN here instead of the NAN macro as on Windows
// the NAN macro leads to "division-by-zero" compile-time error with clang.
static constexpr float na_sentinel = std::numeric_limits<float>::quiet_NaN();
static constexpr bool supports_nulls = true;
static inline bool isnull(float v) { return v != v; }
};
template <>
struct npy_traits<NPY_FLOAT64> {
typedef double value_type;
using TypeClass = DoubleType;
using BuilderClass = DoubleBuilder;
static constexpr double na_sentinel = std::numeric_limits<double>::quiet_NaN();
static constexpr bool supports_nulls = true;
static inline bool isnull(double v) { return v != v; }
};
template <>
struct npy_traits<NPY_DATETIME> {
typedef int64_t value_type;
using TypeClass = TimestampType;
using BuilderClass = TimestampBuilder;
static constexpr bool supports_nulls = true;
static inline bool isnull(int64_t v) {
// NaT = -2**63
// = -0x8000000000000000
// = -9223372036854775808;
// = std::numeric_limits<int64_t>::min()
return v == std::numeric_limits<int64_t>::min();
}
};
template <>
struct npy_traits<NPY_TIMEDELTA> {
typedef int64_t value_type;
using TypeClass = DurationType;
using BuilderClass = DurationBuilder;
static constexpr bool supports_nulls = true;
static inline bool isnull(int64_t v) {
// NaT = -2**63 = std::numeric_limits<int64_t>::min()
return v == std::numeric_limits<int64_t>::min();
}
};
template <>
struct npy_traits<NPY_OBJECT> {
typedef PyObject* value_type;
static constexpr bool supports_nulls = true;
static inline bool isnull(PyObject* v) { return v == Py_None; }
};
//
// Type traits for Arrow -> Numpy equivalence
// Note *supports_nulls* means the equivalent Numpy type support nulls
//
template <int TYPE>
struct arrow_traits {};
template <>
struct arrow_traits<Type::BOOL> {
static constexpr int npy_type = NPY_BOOL;
static constexpr bool supports_nulls = false;
typedef typename npy_traits<NPY_BOOL>::value_type T;
};
#define INT_DECL(TYPE) \
template <> \
struct arrow_traits<Type::TYPE> { \
static constexpr int npy_type = NPY_##TYPE; \
static constexpr bool supports_nulls = false; \
static constexpr double na_value = std::numeric_limits<double>::quiet_NaN(); \
typedef typename npy_traits<NPY_##TYPE>::value_type T; \
};
INT_DECL(INT8);
INT_DECL(INT16);
INT_DECL(INT32);
INT_DECL(INT64);
INT_DECL(UINT8);
INT_DECL(UINT16);
INT_DECL(UINT32);
INT_DECL(UINT64);
template <>
struct arrow_traits<Type::HALF_FLOAT> {
static constexpr int npy_type = NPY_FLOAT16;
static constexpr bool supports_nulls = true;
static constexpr uint16_t na_value = NPY_HALF_NAN;
typedef typename npy_traits<NPY_FLOAT16>::value_type T;
};
template <>
struct arrow_traits<Type::FLOAT> {
static constexpr int npy_type = NPY_FLOAT32;
static constexpr bool supports_nulls = true;
static constexpr float na_value = std::numeric_limits<float>::quiet_NaN();
typedef typename npy_traits<NPY_FLOAT32>::value_type T;
};
template <>
struct arrow_traits<Type::DOUBLE> {
static constexpr int npy_type = NPY_FLOAT64;
static constexpr bool supports_nulls = true;
static constexpr double na_value = std::numeric_limits<double>::quiet_NaN();
typedef typename npy_traits<NPY_FLOAT64>::value_type T;
};
template <>
struct arrow_traits<Type::TIMESTAMP> {
static constexpr int npy_type = NPY_DATETIME;
static constexpr int64_t npy_shift = 1;
static constexpr bool supports_nulls = true;
static constexpr int64_t na_value = kPandasTimestampNull;
typedef typename npy_traits<NPY_DATETIME>::value_type T;
};
template <>
struct arrow_traits<Type::DURATION> {
static constexpr int npy_type = NPY_TIMEDELTA;
static constexpr int64_t npy_shift = 1;
static constexpr bool supports_nulls = true;
static constexpr int64_t na_value = kPandasTimestampNull;
typedef typename npy_traits<NPY_TIMEDELTA>::value_type T;
};
template <>
struct arrow_traits<Type::DATE32> {
// Data stores as FR_D day unit
static constexpr int npy_type = NPY_DATETIME;
static constexpr int64_t npy_shift = 1;
static constexpr bool supports_nulls = true;
typedef typename npy_traits<NPY_DATETIME>::value_type T;
static constexpr int64_t na_value = kPandasTimestampNull;
static inline bool isnull(int64_t v) { return npy_traits<NPY_DATETIME>::isnull(v); }
};
template <>
struct arrow_traits<Type::DATE64> {
// Data stores as FR_D day unit
static constexpr int npy_type = NPY_DATETIME;
// There are 1000 * 60 * 60 * 24 = 86400000ms in a day
static constexpr int64_t npy_shift = 86400000;
static constexpr bool supports_nulls = true;
typedef typename npy_traits<NPY_DATETIME>::value_type T;
static constexpr int64_t na_value = kPandasTimestampNull;
static inline bool isnull(int64_t v) { return npy_traits<NPY_DATETIME>::isnull(v); }
};
template <>
struct arrow_traits<Type::TIME32> {
static constexpr int npy_type = NPY_OBJECT;
static constexpr bool supports_nulls = true;
static constexpr int64_t na_value = kPandasTimestampNull;
typedef typename npy_traits<NPY_DATETIME>::value_type T;
};
template <>
struct arrow_traits<Type::TIME64> {
static constexpr int npy_type = NPY_OBJECT;
static constexpr bool supports_nulls = true;
typedef typename npy_traits<NPY_DATETIME>::value_type T;
};
template <>
struct arrow_traits<Type::STRING> {
static constexpr int npy_type = NPY_OBJECT;
static constexpr bool supports_nulls = true;
};
template <>
struct arrow_traits<Type::BINARY> {
static constexpr int npy_type = NPY_OBJECT;
static constexpr bool supports_nulls = true;
};
static inline NPY_DATETIMEUNIT NumPyFrequency(TimeUnit::type unit) {
switch (unit) {
case TimestampType::Unit::SECOND:
return NPY_FR_s;
case TimestampType::Unit::MILLI:
return NPY_FR_ms;
break;
case TimestampType::Unit::MICRO:
return NPY_FR_us;
default:
// NANO
return NPY_FR_ns;
}
}
static inline int NumPyTypeSize(int npy_type) {
npy_type = fix_numpy_type_num(npy_type);
switch (npy_type) {
case NPY_BOOL:
case NPY_INT8:
case NPY_UINT8:
return 1;
case NPY_INT16:
case NPY_UINT16:
return 2;
case NPY_INT32:
case NPY_UINT32:
return 4;
case NPY_INT64:
case NPY_UINT64:
return 8;
case NPY_FLOAT16:
return 2;
case NPY_FLOAT32:
return 4;
case NPY_FLOAT64:
return 8;
case NPY_DATETIME:
return 8;
case NPY_OBJECT:
return sizeof(void*);
default:
ARROW_CHECK(false) << "unhandled numpy type";
break;
}
return -1;
}
} // namespace internal
} // namespace py
} // namespace arrow

View File

@ -0,0 +1,39 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#pragma once
#if defined(_WIN32) || defined(__CYGWIN__) // Windows
#if defined(_MSC_VER)
#pragma warning(disable : 4251)
#else
#pragma GCC diagnostic ignored "-Wattributes"
#endif
#ifdef ARROW_STATIC
#define ARROW_PYTHON_EXPORT
#elif defined(ARROW_PYTHON_EXPORTING)
#define ARROW_PYTHON_EXPORT __declspec(dllexport)
#else
#define ARROW_PYTHON_EXPORT __declspec(dllimport)
#endif
#else // Not Windows
#ifndef ARROW_PYTHON_EXPORT
#define ARROW_PYTHON_EXPORT __attribute__((visibility("default")))
#endif
#endif // Non-Windows