From 8efc1e1d84c7913267db62fcb2775ba22eaac2d9 Mon Sep 17 00:00:00 2001 From: Ashish Bailkeri Date: Tue, 25 Jul 2023 16:06:06 -0400 Subject: [PATCH 1/3] Timestamp scalar repr update --- python/pyarrow/scalar.pxi | 8 ++++++-- python/pyarrow/tests/test_scalars.py | 4 ++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/python/pyarrow/scalar.pxi b/python/pyarrow/scalar.pxi index f438c8847bb..1dcc121f098 100644 --- a/python/pyarrow/scalar.pxi +++ b/python/pyarrow/scalar.pxi @@ -113,8 +113,12 @@ cdef class Scalar(_Weakrefable): else: with nogil: check_status(self.wrapped.get().Validate()) - + def __repr__(self): + if isinstance(self, TimestampScalar): + return ''.format( + self.__class__.__name__, str(_pc().strftime(self)) + ) return ''.format( self.__class__.__name__, self.as_py() ) @@ -1127,4 +1131,4 @@ def scalar(value, type=None, *, from_pandas=None, MemoryPool memory_pool=None): # retrieve the scalar from the first position scalar = GetResultValue(array.get().GetScalar(0)) - return Scalar.wrap(scalar) + return Scalar.wrap(scalar) \ No newline at end of file diff --git a/python/pyarrow/tests/test_scalars.py b/python/pyarrow/tests/test_scalars.py index b7180e5250f..64ac4cbd5ee 100644 --- a/python/pyarrow/tests/test_scalars.py +++ b/python/pyarrow/tests/test_scalars.py @@ -68,6 +68,7 @@ ({'a': 1, 'b': [1, 2]}, None, pa.StructScalar), ([('a', 1), ('b', 2)], pa.map_(pa.string(), pa.int8()), pa.MapScalar), ]) + def test_basics(value, ty, klass): s = pa.scalar(value, type=ty) s.validate() @@ -153,6 +154,9 @@ def test_hashing_struct_scalar(): hash2 = hash(b[0]) assert hash1 == hash2 +def test_timestamp_scalar(): + s = repr(pa.scalar("0000-01-01").cast(pa.timestamp("s"))) + assert s == "" def test_bool(): false = pa.scalar(False) From 2db1c42a92103ed1da1b6f7321d013220b6df0ea Mon Sep 17 00:00:00 2001 From: Ashish Bailkeri Date: Fri, 28 Jul 2023 16:29:05 -0400 Subject: [PATCH 2/3] Add Documentation, Tests, and Code Revision --- python/pyarrow/scalar.pxi | 25 +++++++++++++++----- python/pyarrow/tests/test_convert_builtin.py | 2 +- python/pyarrow/tests/test_scalars.py | 14 ++++++++--- 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/python/pyarrow/scalar.pxi b/python/pyarrow/scalar.pxi index 1dcc121f098..3d971db7d14 100644 --- a/python/pyarrow/scalar.pxi +++ b/python/pyarrow/scalar.pxi @@ -113,12 +113,8 @@ cdef class Scalar(_Weakrefable): else: with nogil: check_status(self.wrapped.get().Validate()) - + def __repr__(self): - if isinstance(self, TimestampScalar): - return ''.format( - self.__class__.__name__, str(_pc().strftime(self)) - ) return ''.format( self.__class__.__name__, self.as_py() ) @@ -526,6 +522,23 @@ cdef class TimestampScalar(Scalar): return _datetime_from_int(sp.value, unit=dtype.unit(), tzinfo=tzinfo) + def __repr__(self): + """ + Return the representation of TimestampScalar using `strftime` to avoid + original repr datetime values being out of range. + """ + cdef: + CTimestampScalar* sp = self.wrapped.get() + CTimestampType* dtype = sp.type.get() + + if not dtype.timezone().empty(): + type_format = str(_pc().strftime(self, format="%Y-%m-%dT%H:%M:%S%z")) + else: + type_format = str(_pc().strftime(self)) + return ''.format( + self.__class__.__name__, type_format + ) + cdef class DurationScalar(Scalar): """ @@ -1131,4 +1144,4 @@ def scalar(value, type=None, *, from_pandas=None, MemoryPool memory_pool=None): # retrieve the scalar from the first position scalar = GetResultValue(array.get().GetScalar(0)) - return Scalar.wrap(scalar) \ No newline at end of file + return Scalar.wrap(scalar) diff --git a/python/pyarrow/tests/test_convert_builtin.py b/python/pyarrow/tests/test_convert_builtin.py index af4c91a8945..cf2535a3c62 100644 --- a/python/pyarrow/tests/test_convert_builtin.py +++ b/python/pyarrow/tests/test_convert_builtin.py @@ -1353,7 +1353,7 @@ def test_sequence_timestamp_from_int_with_unit(): assert len(arr_s) == 1 assert arr_s.type == s assert repr(arr_s[0]) == ( - "" + "" ) assert str(arr_s[0]) == "1970-01-01 00:00:01" diff --git a/python/pyarrow/tests/test_scalars.py b/python/pyarrow/tests/test_scalars.py index 64ac4cbd5ee..e08a71e3a26 100644 --- a/python/pyarrow/tests/test_scalars.py +++ b/python/pyarrow/tests/test_scalars.py @@ -68,7 +68,6 @@ ({'a': 1, 'b': [1, 2]}, None, pa.StructScalar), ([('a', 1), ('b', 2)], pa.map_(pa.string(), pa.int8()), pa.MapScalar), ]) - def test_basics(value, ty, klass): s = pa.scalar(value, type=ty) s.validate() @@ -154,9 +153,18 @@ def test_hashing_struct_scalar(): hash2 = hash(b[0]) assert hash1 == hash2 + def test_timestamp_scalar(): - s = repr(pa.scalar("0000-01-01").cast(pa.timestamp("s"))) - assert s == "" + a = repr(pa.scalar("0000-01-01").cast(pa.timestamp("s"))) + assert a == "" + b = repr(pa.scalar(datetime.datetime(2015, 1, 1), type=pa.timestamp('s', tz='UTC'))) + assert b == "" + c = repr(pa.scalar(datetime.datetime(2015, 1, 1), type=pa.timestamp('us'))) + assert c == "" + d = repr(pc.assume_timezone( + pa.scalar("2000-01-01").cast(pa.timestamp("s")), "America/New_York")) + assert d == "" + def test_bool(): false = pa.scalar(False) From ee285c15564d406b40a16983c1da35b560ada950 Mon Sep 17 00:00:00 2001 From: Ashish Bailkeri Date: Fri, 28 Jul 2023 20:46:44 -0400 Subject: [PATCH 3/3] Documentation Fixes for TimestampScalar --- python/pyarrow/types.pxi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/pyarrow/types.pxi b/python/pyarrow/types.pxi index fbd4f8a94b6..12ad2fc4b6f 100644 --- a/python/pyarrow/types.pxi +++ b/python/pyarrow/types.pxi @@ -3605,9 +3605,9 @@ def timestamp(unit, tz=None): >>> from datetime import datetime >>> pa.scalar(datetime(2012, 1, 1), type=pa.timestamp('s', tz='UTC')) - )> + >>> pa.scalar(datetime(2012, 1, 1), type=pa.timestamp('us')) - + Returns -------