This is an automated email from the ASF dual-hosted git repository.
JackieTien97 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new 7dcad2b6b44 Fix Python client CI: handle Timestamps outside Python
stdlib range (#17715)
7dcad2b6b44 is described below
commit 7dcad2b6b449b9cda07cd8f8662e228664fc2991
Author: Jackie Tien <[email protected]>
AuthorDate: Tue May 19 12:07:50 2026 +0800
Fix Python client CI: handle Timestamps outside Python stdlib range (#17715)
---
iotdb-client/client-py/iotdb/utils/rpc_utils.py | 56 +++++++++++++++++++++++--
1 file changed, 53 insertions(+), 3 deletions(-)
diff --git a/iotdb-client/client-py/iotdb/utils/rpc_utils.py
b/iotdb-client/client-py/iotdb/utils/rpc_utils.py
index 7b292737f0c..0912fd14d95 100644
--- a/iotdb-client/client-py/iotdb/utils/rpc_utils.py
+++ b/iotdb-client/client-py/iotdb/utils/rpc_utils.py
@@ -79,15 +79,34 @@ def
verify_success_with_redirection_for_multi_devices(status: TSStatus, devices:
def convert_to_timestamp(time: int, precision: str, timezone: str):
try:
- return pd.Timestamp(time, unit=precision, tz=timezone)
+ ts = pd.Timestamp(time, unit=precision, tz=timezone)
except OutOfBoundsDatetime:
- return pd.Timestamp(time, unit=precision).tz_localize(timezone)
+ try:
+ ts = pd.Timestamp(time, unit=precision).tz_localize(timezone)
+ except NotImplementedError:
+ return pd.Timestamp(time, unit=precision)
except ValueError:
logger.warning(
f"Timezone string '{timezone}' cannot be recognized by pandas. "
f"Falling back to local timezone: '{get_localzone_name()}'."
)
- return pd.Timestamp(time, unit=precision, tz=get_localzone_name())
+ ts = pd.Timestamp(time, unit=precision, tz=get_localzone_name())
+ except NotImplementedError:
+ # Timestamp falls outside Python's stdlib datetime range (year < 1 or
+ # > 9999). pandas >= 3.0 cannot attach a timezone to such Timestamps
+ # because tz conversion relies on toordinal(). Return naive instead.
+ return pd.Timestamp(time, unit=precision)
+ # Construction succeeded but utcoffset() may still fail downstream (e.g.
+ # in pd.DataFrame's tz alignment) when the Timestamp's year is outside
+ # 1..9999 and tz is not the canonical UTC. Probe early and fall back to
+ # naive so callers like result_set_to_pandas() don't blow up. NaT does
+ # not need this check (and does not support utcoffset()).
+ if ts is not pd.NaT:
+ try:
+ ts.utcoffset()
+ except NotImplementedError:
+ return pd.Timestamp(time, unit=precision)
+ return ts
unit_map = {
@@ -108,3 +127,34 @@ def isoformat(ts: pd.Timestamp, unit: str):
f"Falling back to use auto timespec'."
)
return ts.isoformat()
+ except NotImplementedError:
+ # Timestamp falls outside Python's stdlib datetime range. pandas >= 3.0
+ # routes isoformat through datetime.isoformat, which calls toordinal()
+ # and fails. Build the ISO 8601 string from individual components.
+ return _isoformat_from_components(ts, unit)
+
+
+def _isoformat_from_components(ts: pd.Timestamp, unit: str) -> str:
+ base = (
+ f"{ts.year:04d}-{ts.month:02d}-{ts.day:02d}"
+ f"T{ts.hour:02d}:{ts.minute:02d}:{ts.second:02d}"
+ )
+ if unit == "ms":
+ base += f".{ts.microsecond // 1000:03d}"
+ elif unit == "us":
+ base += f".{ts.microsecond:06d}"
+ elif unit == "ns":
+ base += f".{ts.microsecond:06d}{ts.nanosecond:03d}"
+ if ts.tzinfo is not None:
+ try:
+ offset = ts.utcoffset()
+ except NotImplementedError:
+ # utcoffset() needs toordinal() for zones like Etc/UTC. Omit
offset.
+ offset = None
+ if offset is not None:
+ total_seconds = int(offset.total_seconds())
+ sign = "+" if total_seconds >= 0 else "-"
+ total_seconds = abs(total_seconds)
+ hh, mm = divmod(total_seconds // 60, 60)
+ base += f"{sign}{hh:02d}:{mm:02d}"
+ return base