Skip to content

Commit

Permalink
GH-36323: [Python] Fix Timestamp scalar repr error on values outside …
Browse files Browse the repository at this point in the history
…datetime range (#36942)

### Rationale for this change

#36323

### What changes are included in this PR?

Changed the way repr is handled for TimestampScalar

### Are these changes tested?

I have added a very basic test for this change to see whether it will error or not if outside the range.

### Are there any user-facing changes?

The functionality of TimestampScalar's repr now uses the `strftime` function.

* Closes: #36323

Lead-authored-by: Ashish Bailkeri <ashishbailkeri123@gmail.com>
Co-authored-by: Ashish Bailkeri <47304318+aboss123@users.noreply.github.com>
Signed-off-by: Sutou Kouhei <kou@clear-code.com>
  • Loading branch information
aboss123 committed Jul 31, 2023
1 parent 37cb592 commit 112f949
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 3 deletions.
17 changes: 17 additions & 0 deletions python/pyarrow/scalar.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -522,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 = <CTimestampScalar*> self.wrapped.get()
CTimestampType* dtype = <CTimestampType*> 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 '<pyarrow.{}: {!r}>'.format(
self.__class__.__name__, type_format
)


cdef class DurationScalar(Scalar):
"""
Expand Down
2 changes: 1 addition & 1 deletion python/pyarrow/tests/test_convert_builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]) == (
"<pyarrow.TimestampScalar: datetime.datetime(1970, 1, 1, 0, 0, 1)>"
"<pyarrow.TimestampScalar: '1970-01-01T00:00:01'>"
)
assert str(arr_s[0]) == "1970-01-01 00:00:01"

Expand Down
12 changes: 12 additions & 0 deletions python/pyarrow/tests/test_scalars.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,18 @@ def test_hashing_struct_scalar():
assert hash1 == hash2


def test_timestamp_scalar():
a = repr(pa.scalar("0000-01-01").cast(pa.timestamp("s")))
assert a == "<pyarrow.TimestampScalar: '0000-01-01T00:00:00'>"
b = repr(pa.scalar(datetime.datetime(2015, 1, 1), type=pa.timestamp('s', tz='UTC')))
assert b == "<pyarrow.TimestampScalar: '2015-01-01T00:00:00+0000'>"
c = repr(pa.scalar(datetime.datetime(2015, 1, 1), type=pa.timestamp('us')))
assert c == "<pyarrow.TimestampScalar: '2015-01-01T00:00:00.000000'>"
d = repr(pc.assume_timezone(
pa.scalar("2000-01-01").cast(pa.timestamp("s")), "America/New_York"))
assert d == "<pyarrow.TimestampScalar: '2000-01-01T00:00:00-0500'>"


def test_bool():
false = pa.scalar(False)
true = pa.scalar(True)
Expand Down
4 changes: 2 additions & 2 deletions python/pyarrow/types.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -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'))
<pyarrow.TimestampScalar: datetime.datetime(2012, 1, 1, 0, 0, tzinfo=<UTC>)>
<pyarrow.TimestampScalar: '2012-01-01T00:00:00+0000'>
>>> pa.scalar(datetime(2012, 1, 1), type=pa.timestamp('us'))
<pyarrow.TimestampScalar: datetime.datetime(2012, 1, 1, 0, 0)>
<pyarrow.TimestampScalar: '2012-01-01T00:00:00.000000'>
Returns
-------
Expand Down

0 comments on commit 112f949

Please sign in to comment.