diff --git a/cpp/src/arrow/python/inference.cc b/cpp/src/arrow/python/inference.cc index 880fe8467ea..e619a64eb8a 100644 --- a/cpp/src/arrow/python/inference.cc +++ b/cpp/src/arrow/python/inference.cc @@ -583,5 +583,14 @@ Status InferArrowTypeAndSize(PyObject* obj, int64_t* size, return Status::OK(); } +ARROW_EXPORT +bool IsPyBool(PyObject* obj) { return internal::PyBoolScalar_Check(obj); } + +ARROW_EXPORT +bool IsPyInt(PyObject* obj) { return internal::PyIntScalar_Check(obj); } + +ARROW_EXPORT +bool IsPyFloat(PyObject* obj) { return internal::PyFloatScalar_Check(obj); } + } // namespace py } // namespace arrow diff --git a/cpp/src/arrow/python/inference.h b/cpp/src/arrow/python/inference.h index 21cddf40532..2cffa17ac2d 100644 --- a/cpp/src/arrow/python/inference.h +++ b/cpp/src/arrow/python/inference.h @@ -48,6 +48,18 @@ ARROW_EXPORT arrow::Status InferArrowTypeAndSize(PyObject* obj, int64_t* size, std::shared_ptr* out_type); +/// Checks whether the passed Python object is a boolean scalar +ARROW_EXPORT +bool IsPyBool(PyObject* obj); + +/// Checks whether the passed Python object is an integer scalar +ARROW_EXPORT +bool IsPyInt(PyObject* obj); + +/// Checks whether the passed Python object is a float scalar +ARROW_EXPORT +bool IsPyFloat(PyObject* obj); + } // namespace py } // namespace arrow diff --git a/cpp/src/arrow/python/numpy-internal.h b/cpp/src/arrow/python/numpy-internal.h index b214a500edf..463795a2109 100644 --- a/cpp/src/arrow/python/numpy-internal.h +++ b/cpp/src/arrow/python/numpy-internal.h @@ -165,6 +165,10 @@ inline bool PyIntScalar_Check(PyObject* obj) { return PyLong_Check(obj) || PyArray_IsScalar(obj, Integer); } +inline bool PyBoolScalar_Check(PyObject* obj) { + return PyBool_Check(obj) || PyArray_IsScalar(obj, Bool); +} + } // namespace internal } // namespace py diff --git a/python/pyarrow/includes/libarrow.pxd b/python/pyarrow/includes/libarrow.pxd index 766811715a5..f6589f948ab 100644 --- a/python/pyarrow/includes/libarrow.pxd +++ b/python/pyarrow/includes/libarrow.pxd @@ -1067,6 +1067,12 @@ cdef extern from 'arrow/python/config.h' namespace 'arrow::py': void set_numpy_nan(object o) +cdef extern from 'arrow/python/inference.h' namespace 'arrow::py': + c_bool IsPyBool(object o) + c_bool IsPyInt(object o) + c_bool IsPyFloat(object o) + + cdef extern from 'arrow/python/benchmark.h' namespace 'arrow::py::benchmark': void Benchmark_PandasObjectIsNull(object lst) except * diff --git a/python/pyarrow/tests/test_types.py b/python/pyarrow/tests/test_types.py index 4aea73f4ab5..bd73fe0dd0f 100644 --- a/python/pyarrow/tests/test_types.py +++ b/python/pyarrow/tests/test_types.py @@ -16,8 +16,9 @@ # under the License. from collections import OrderedDict -import pickle +import numpy as np +import pickle import pytest import pyarrow as pa @@ -471,3 +472,24 @@ def test_empty_table(): assert isinstance(table, pa.Table) assert table.num_rows == 0 assert table.schema == schema + + +def test_is_integer_value(): + assert pa.types.is_integer_value(1) + assert pa.types.is_integer_value(np.int64(1)) + assert not pa.types.is_integer_value('1') + + +def test_is_float_value(): + assert not pa.types.is_float_value(1) + assert pa.types.is_float_value(1.) + assert pa.types.is_float_value(np.float64(1)) + assert not pa.types.is_float_value('1.0') + + +def test_is_boolean_value(): + assert not pa.types.is_boolean_value(1) + assert pa.types.is_boolean_value(True) + assert pa.types.is_boolean_value(False) + assert pa.types.is_boolean_value(np.bool_(True)) + assert pa.types.is_boolean_value(np.bool_(False)) diff --git a/python/pyarrow/types.pxi b/python/pyarrow/types.pxi index 98c0dda5a45..3ba36c9c035 100644 --- a/python/pyarrow/types.pxi +++ b/python/pyarrow/types.pxi @@ -1474,3 +1474,15 @@ def from_numpy_dtype(object dtype): check_status(NumPyDtypeToArrow(dtype, &c_type)) return pyarrow_wrap_data_type(c_type) + + +def is_boolean_value(object obj): + return IsPyBool(obj) + + +def is_integer_value(object obj): + return IsPyInt(obj) + + +def is_float_value(object obj): + return IsPyFloat(obj) diff --git a/python/pyarrow/types.py b/python/pyarrow/types.py index 6ce438657f5..2bd70276e7e 100644 --- a/python/pyarrow/types.py +++ b/python/pyarrow/types.py @@ -17,6 +17,10 @@ # Tools for dealing with Arrow type metadata in Python +from pyarrow.lib import (is_boolean_value, # noqa + is_integer_value, + is_float_value) + import pyarrow.lib as lib