Skip to content

Commit 1caf189

Browse files
rwgkcopybara-github
authored andcommitted
Make absl::Time from-python conversion (almost) identical to a Google-internal implementation under absl/python.
Note that the unit tests are unchanged (in the entire Google codebase). The remaining very subtle differences between `type_caster<absl::Time>::load()` and the corresponding from-python conversion under absl/python are related to the pybind11 two-pass overload resolution feature that does not exist in PyCLIF. As a side-effect, this change removes long-obsolete remnants of Python 2 support. PiperOrigin-RevId: 529457660
1 parent 0f8a776 commit 1caf189

File tree

1 file changed

+6
-57
lines changed

1 file changed

+6
-57
lines changed

pybind11_abseil/absl_casters.h

Lines changed: 6 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -64,27 +64,6 @@ inline int64_t GetInt64Attr(handle src, const char* name) {
6464
return src.attr(name).cast<int64_t>();
6565
}
6666

67-
// Given a python date or datetime object, figure out an appropriate
68-
// absl::TimeZone with a fixed offset, or default to the local timezone.
69-
inline absl::TimeZone GetTimeZone(handle src) {
70-
if (!hasattr(src, "tzinfo")) {
71-
// datetime.date objects lack this property, so assume local.
72-
return absl::LocalTimeZone();
73-
}
74-
object tzinfo = src.attr("tzinfo");
75-
if (tzinfo.is_none()) {
76-
// non-tz aware datetime, again assume local time.
77-
return absl::LocalTimeZone();
78-
}
79-
object utc_offset = tzinfo.attr("utcoffset")(src);
80-
if (utc_offset.is_none()) {
81-
return absl::LocalTimeZone();
82-
}
83-
int64_t offset_seconds =
84-
std::lround(utc_offset.attr("total_seconds")().cast<double>());
85-
return absl::FixedTimeZone(offset_seconds);
86-
}
87-
8867
template <>
8968
struct type_caster<absl::TimeZone> {
9069
public:
@@ -287,43 +266,13 @@ struct type_caster<absl::Time> {
287266
return true;
288267
}
289268
}
290-
if (!hasattr(src, "year") || !hasattr(src, "month") ||
291-
!hasattr(src, "day")) {
292-
return false;
293-
}
294-
if (hasattr(src, "timestamp")) {
295-
// python datetime.datetime object
296-
double timestamp = src.attr("timestamp")().cast<double>();
297-
int64_t as_micros = static_cast<int64_t>(timestamp * 1e6);
298-
value = absl::FromUnixMicros(as_micros);
299-
}
300-
#if PY_MAJOR_VERSION < 3
301-
else if (hasattr(src, "microsecond")) { // NOLINT(readability/braces)
302-
// python datetime.datetime object
303-
// This doesn't rely on datetime.datetime.timestamp(), which is not
304-
// available in Python 2.
305-
auto utc = module::import("dateutil.tz").attr("UTC");
306-
auto datetime = module_::import("datetime").attr("datetime");
307-
auto gettz = module::import("dateutil.tz").attr("gettz");
308-
309-
auto epoch_dt = datetime.attr("fromtimestamp")(0, utc);
310-
auto tz = (src.attr("tzinfo").is_none()) ? gettz() : src.attr("tzinfo");
311-
auto src_with_tz = src.attr("replace")("tzinfo"_a = tz);
312-
313-
double timestamp =
314-
(src_with_tz - epoch_dt).attr("total_seconds")().cast<double>();
315-
int64_t as_micros = static_cast<int64_t>(timestamp * 1e6);
316-
value = absl::FromUnixMicros(as_micros);
317-
}
318-
#endif
319-
else { // NOLINT(readability/braces)
320-
// python datetime.date object
321-
absl::CivilDay civil_day(GetInt64Attr(src, "year"),
322-
GetInt64Attr(src, "month"),
323-
GetInt64Attr(src, "day"));
324-
value = absl::FromCivil(civil_day, GetTimeZone(src));
269+
if (PyDate_Check(src.ptr())) {
270+
value = absl::FromDateTime(
271+
PyDateTime_GET_YEAR(src.ptr()), PyDateTime_GET_MONTH(src.ptr()),
272+
PyDateTime_GET_DAY(src.ptr()), 0, 0, 0, absl::LocalTimeZone());
273+
return true;
325274
}
326-
return true;
275+
return false;
327276
}
328277

329278
// Conversion part 2 (C++ -> Python)

0 commit comments

Comments
 (0)