From c71152148554d397dfa83c5f6ad9ec91d46d32e5 Mon Sep 17 00:00:00 2001 From: "Korn, Uwe" Date: Sat, 29 Sep 2018 15:16:43 +0200 Subject: [PATCH 1/3] =?UTF-8?q?ARROW-3363:=20[C++/Python]=C2=A0Add=20helpe?= =?UTF-8?q?r=20functions=20to=20detect=20scalar=20Python=20types?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cpp/src/arrow/python/inference.cc | 15 +++++++++++++++ cpp/src/arrow/python/inference.h | 12 ++++++++++++ cpp/src/arrow/python/numpy-internal.h | 4 ++++ python/pyarrow/includes/libarrow.pxd | 6 ++++++ python/pyarrow/tests/test_types.py | 24 +++++++++++++++++++++++- python/pyarrow/types.pxi | 12 ++++++++++++ python/pyarrow/types.py | 2 ++ 7 files changed, 74 insertions(+), 1 deletion(-) diff --git a/cpp/src/arrow/python/inference.cc b/cpp/src/arrow/python/inference.cc index 880fe8467ea..9700db60193 100644 --- a/cpp/src/arrow/python/inference.cc +++ b/cpp/src/arrow/python/inference.cc @@ -583,5 +583,20 @@ 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..37b7bc48c31 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_object(): + assert pa.types.is_integer_object(1) + assert pa.types.is_integer_object(np.int64(1)) + assert not pa.types.is_integer_object('1') + + +def test_is_float_object(): + assert not pa.types.is_float_object(1) + assert pa.types.is_float_object(1.) + assert pa.types.is_float_object(np.float64(1)) + assert not pa.types.is_float_object('1.0') + + +def test_is_boolean_object(): + assert not pa.types.is_boolean_object(1) + assert pa.types.is_boolean_object(True) + assert pa.types.is_boolean_object(False) + assert pa.types.is_boolean_object(np.bool_(True)) + assert pa.types.is_boolean_object(np.bool_(False)) diff --git a/python/pyarrow/types.pxi b/python/pyarrow/types.pxi index 98c0dda5a45..3bea7e5a415 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_object(object obj): + return IsPyBool(obj) + + +def is_integer_object(object obj): + return IsPyInt(obj) + + +def is_float_object(object obj): + return IsPyFloat(obj) diff --git a/python/pyarrow/types.py b/python/pyarrow/types.py index 6ce438657f5..c658934dad1 100644 --- a/python/pyarrow/types.py +++ b/python/pyarrow/types.py @@ -17,6 +17,8 @@ # Tools for dealing with Arrow type metadata in Python +from pyarrow.lib import is_integer_object, is_float_object, is_boolean_object + import pyarrow.lib as lib From ffcc20c8e156f933d5205886b9982da8baf6456a Mon Sep 17 00:00:00 2001 From: "Korn, Uwe" Date: Sun, 30 Sep 2018 12:30:03 +0200 Subject: [PATCH 2/3] Rename functions to _value --- cpp/src/arrow/python/inference.cc | 12 +++--------- python/pyarrow/tests/test_types.py | 30 +++++++++++++++--------------- python/pyarrow/types.pxi | 6 +++--- python/pyarrow/types.py | 2 +- 4 files changed, 22 insertions(+), 28 deletions(-) diff --git a/cpp/src/arrow/python/inference.cc b/cpp/src/arrow/python/inference.cc index 9700db60193..e619a64eb8a 100644 --- a/cpp/src/arrow/python/inference.cc +++ b/cpp/src/arrow/python/inference.cc @@ -584,19 +584,13 @@ Status InferArrowTypeAndSize(PyObject* obj, int64_t* size, } ARROW_EXPORT -bool IsPyBool(PyObject* obj) { - return internal::PyBoolScalar_Check(obj); -} +bool IsPyBool(PyObject* obj) { return internal::PyBoolScalar_Check(obj); } ARROW_EXPORT -bool IsPyInt(PyObject* obj) { - return internal::PyIntScalar_Check(obj); -} +bool IsPyInt(PyObject* obj) { return internal::PyIntScalar_Check(obj); } ARROW_EXPORT -bool IsPyFloat(PyObject* obj) { - return internal::PyFloatScalar_Check(obj); -} +bool IsPyFloat(PyObject* obj) { return internal::PyFloatScalar_Check(obj); } } // namespace py } // namespace arrow diff --git a/python/pyarrow/tests/test_types.py b/python/pyarrow/tests/test_types.py index 37b7bc48c31..bd73fe0dd0f 100644 --- a/python/pyarrow/tests/test_types.py +++ b/python/pyarrow/tests/test_types.py @@ -474,22 +474,22 @@ def test_empty_table(): assert table.schema == schema -def test_is_integer_object(): - assert pa.types.is_integer_object(1) - assert pa.types.is_integer_object(np.int64(1)) - assert not pa.types.is_integer_object('1') +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_object(): - assert not pa.types.is_float_object(1) - assert pa.types.is_float_object(1.) - assert pa.types.is_float_object(np.float64(1)) - assert not pa.types.is_float_object('1.0') +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_object(): - assert not pa.types.is_boolean_object(1) - assert pa.types.is_boolean_object(True) - assert pa.types.is_boolean_object(False) - assert pa.types.is_boolean_object(np.bool_(True)) - assert pa.types.is_boolean_object(np.bool_(False)) +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 3bea7e5a415..3ba36c9c035 100644 --- a/python/pyarrow/types.pxi +++ b/python/pyarrow/types.pxi @@ -1476,13 +1476,13 @@ def from_numpy_dtype(object dtype): return pyarrow_wrap_data_type(c_type) -def is_boolean_object(object obj): +def is_boolean_value(object obj): return IsPyBool(obj) -def is_integer_object(object obj): +def is_integer_value(object obj): return IsPyInt(obj) -def is_float_object(object obj): +def is_float_value(object obj): return IsPyFloat(obj) diff --git a/python/pyarrow/types.py b/python/pyarrow/types.py index c658934dad1..c2d5b283f0d 100644 --- a/python/pyarrow/types.py +++ b/python/pyarrow/types.py @@ -17,7 +17,7 @@ # Tools for dealing with Arrow type metadata in Python -from pyarrow.lib import is_integer_object, is_float_object, is_boolean_object +from pyarrow.lib import is_integer_value, is_float_value, is_boolean_value import pyarrow.lib as lib From 3560fd3552b4082713cb64d8f7b0fe319575ba21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kriszti=C3=A1n=20Sz=C5=B1cs?= Date: Sun, 30 Sep 2018 13:05:24 +0200 Subject: [PATCH 3/3] flake8 --- python/pyarrow/types.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/python/pyarrow/types.py b/python/pyarrow/types.py index c2d5b283f0d..2bd70276e7e 100644 --- a/python/pyarrow/types.py +++ b/python/pyarrow/types.py @@ -17,7 +17,9 @@ # Tools for dealing with Arrow type metadata in Python -from pyarrow.lib import is_integer_value, is_float_value, is_boolean_value +from pyarrow.lib import (is_boolean_value, # noqa + is_integer_value, + is_float_value) import pyarrow.lib as lib