Skip to content

Commit 61490f5

Browse files
committed
chore: drop use of 'pytz'
Closes #74.
1 parent 35ba7d3 commit 61490f5

File tree

3 files changed

+39
-33
lines changed

3 files changed

+39
-33
lines changed

google/api_core/datetime_helpers.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,10 @@
1818
import datetime
1919
import re
2020

21-
import pytz
22-
2321
from google.protobuf import timestamp_pb2
2422

2523

26-
_UTC_EPOCH = datetime.datetime.utcfromtimestamp(0).replace(tzinfo=pytz.utc)
24+
_UTC_EPOCH = datetime.datetime(1970, 1, 1, tzinfo=datetime.timezone.utc)
2725
_RFC3339_MICROS = "%Y-%m-%dT%H:%M:%S.%fZ"
2826
_RFC3339_NO_FRACTION = "%Y-%m-%dT%H:%M:%S"
2927
# datetime.strptime cannot handle nanosecond precision: parse w/ regex
@@ -83,9 +81,9 @@ def to_microseconds(value):
8381
int: Microseconds since the unix epoch.
8482
"""
8583
if not value.tzinfo:
86-
value = value.replace(tzinfo=pytz.utc)
84+
value = value.replace(tzinfo=datetime.timezone.utc)
8785
# Regardless of what timezone is on the value, convert it to UTC.
88-
value = value.astimezone(pytz.utc)
86+
value = value.astimezone(datetime.timezone.utc)
8987
# Convert the datetime to a microsecond timestamp.
9088
return int(calendar.timegm(value.timetuple()) * 1e6) + value.microsecond
9189

@@ -156,7 +154,7 @@ def from_rfc3339(value):
156154
nanos = int(fraction) * (10 ** scale)
157155
micros = nanos // 1000
158156

159-
return bare_seconds.replace(microsecond=micros, tzinfo=pytz.utc)
157+
return bare_seconds.replace(microsecond=micros, tzinfo=datetime.timezone.utc)
160158

161159

162160
from_rfc3339_nanos = from_rfc3339 # from_rfc3339_nanos method was deprecated.
@@ -256,7 +254,7 @@ def from_rfc3339(cls, stamp):
256254
bare.minute,
257255
bare.second,
258256
nanosecond=nanos,
259-
tzinfo=pytz.UTC,
257+
tzinfo=datetime.timezone.utc,
260258
)
261259

262260
def timestamp_pb(self):
@@ -265,7 +263,11 @@ def timestamp_pb(self):
265263
Returns:
266264
(:class:`~google.protobuf.timestamp_pb2.Timestamp`): Timestamp message
267265
"""
268-
inst = self if self.tzinfo is not None else self.replace(tzinfo=pytz.UTC)
266+
inst = (
267+
self
268+
if self.tzinfo is not None
269+
else self.replace(tzinfo=datetime.timezone.utc)
270+
)
269271
delta = inst - _UTC_EPOCH
270272
seconds = int(delta.total_seconds())
271273
nanos = self._nanosecond or self.microsecond * 1000
@@ -292,5 +294,5 @@ def from_timestamp_pb(cls, stamp):
292294
bare.minute,
293295
bare.second,
294296
nanosecond=stamp.nanos,
295-
tzinfo=pytz.UTC,
297+
tzinfo=datetime.timezone.utc,
296298
)

setup.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
"requests >= 2.18.0, < 3.0.0dev",
3636
"setuptools >= 40.3.0",
3737
"packaging >= 14.3",
38-
"pytz",
3938
'futures >= 3.2.0; python_version < "3.2"',
4039
]
4140
extras = {

tests/unit/test_datetime_helpers.py

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import datetime
1717

1818
import pytest
19-
import pytz
2019

2120
from google.api_core import datetime_helpers
2221
from google.protobuf import timestamp_pb2
@@ -31,7 +30,7 @@ def test_utcnow():
3130

3231

3332
def test_to_milliseconds():
34-
dt = datetime.datetime(1970, 1, 1, 0, 0, 1, tzinfo=pytz.utc)
33+
dt = datetime.datetime(1970, 1, 1, 0, 0, 1, tzinfo=datetime.timezone.utc)
3534
assert datetime_helpers.to_milliseconds(dt) == 1000
3635

3736

@@ -42,7 +41,7 @@ def test_to_microseconds():
4241

4342

4443
def test_to_microseconds_non_utc():
45-
zone = pytz.FixedOffset(-1)
44+
zone = datetime.timezone(datetime.timedelta(minutes=-1))
4645
dt = datetime.datetime(1970, 1, 1, 0, 0, 0, tzinfo=zone)
4746
assert datetime_helpers.to_microseconds(dt) == ONE_MINUTE_IN_MICROSECONDS
4847

@@ -56,7 +55,7 @@ def test_to_microseconds_naive():
5655
def test_from_microseconds():
5756
five_mins_from_epoch_in_microseconds = 5 * ONE_MINUTE_IN_MICROSECONDS
5857
five_mins_from_epoch_datetime = datetime.datetime(
59-
1970, 1, 1, 0, 5, 0, tzinfo=pytz.utc
58+
1970, 1, 1, 0, 5, 0, tzinfo=datetime.timezone.utc
6059
)
6160

6261
result = datetime_helpers.from_microseconds(five_mins_from_epoch_in_microseconds)
@@ -78,28 +77,28 @@ def test_from_iso8601_time():
7877
def test_from_rfc3339():
7978
value = "2009-12-17T12:44:32.123456Z"
8079
assert datetime_helpers.from_rfc3339(value) == datetime.datetime(
81-
2009, 12, 17, 12, 44, 32, 123456, pytz.utc
80+
2009, 12, 17, 12, 44, 32, 123456, datetime.timezone.utc
8281
)
8382

8483

8584
def test_from_rfc3339_nanos():
8685
value = "2009-12-17T12:44:32.123456Z"
8786
assert datetime_helpers.from_rfc3339_nanos(value) == datetime.datetime(
88-
2009, 12, 17, 12, 44, 32, 123456, pytz.utc
87+
2009, 12, 17, 12, 44, 32, 123456, datetime.timezone.utc
8988
)
9089

9190

9291
def test_from_rfc3339_without_nanos():
9392
value = "2009-12-17T12:44:32Z"
9493
assert datetime_helpers.from_rfc3339(value) == datetime.datetime(
95-
2009, 12, 17, 12, 44, 32, 0, pytz.utc
94+
2009, 12, 17, 12, 44, 32, 0, datetime.timezone.utc
9695
)
9796

9897

9998
def test_from_rfc3339_nanos_without_nanos():
10099
value = "2009-12-17T12:44:32Z"
101100
assert datetime_helpers.from_rfc3339_nanos(value) == datetime.datetime(
102-
2009, 12, 17, 12, 44, 32, 0, pytz.utc
101+
2009, 12, 17, 12, 44, 32, 0, datetime.timezone.utc
103102
)
104103

105104

@@ -119,7 +118,7 @@ def test_from_rfc3339_nanos_without_nanos():
119118
def test_from_rfc3339_with_truncated_nanos(truncated, micros):
120119
value = "2009-12-17T12:44:32.{}Z".format(truncated)
121120
assert datetime_helpers.from_rfc3339(value) == datetime.datetime(
122-
2009, 12, 17, 12, 44, 32, micros, pytz.utc
121+
2009, 12, 17, 12, 44, 32, micros, datetime.timezone.utc
123122
)
124123

125124

@@ -148,7 +147,7 @@ def test_from_rfc3339_nanos_is_deprecated():
148147
def test_from_rfc3339_nanos_with_truncated_nanos(truncated, micros):
149148
value = "2009-12-17T12:44:32.{}Z".format(truncated)
150149
assert datetime_helpers.from_rfc3339_nanos(value) == datetime.datetime(
151-
2009, 12, 17, 12, 44, 32, micros, pytz.utc
150+
2009, 12, 17, 12, 44, 32, micros, datetime.timezone.utc
152151
)
153152

154153

@@ -171,20 +170,20 @@ def test_to_rfc3339():
171170

172171

173172
def test_to_rfc3339_with_utc():
174-
value = datetime.datetime(2016, 4, 5, 13, 30, 0, tzinfo=pytz.utc)
173+
value = datetime.datetime(2016, 4, 5, 13, 30, 0, tzinfo=datetime.timezone.utc)
175174
expected = "2016-04-05T13:30:00.000000Z"
176175
assert datetime_helpers.to_rfc3339(value, ignore_zone=False) == expected
177176

178177

179178
def test_to_rfc3339_with_non_utc():
180-
zone = pytz.FixedOffset(-60)
179+
zone = datetime.timezone(datetime.timedelta(minutes=-60))
181180
value = datetime.datetime(2016, 4, 5, 13, 30, 0, tzinfo=zone)
182181
expected = "2016-04-05T14:30:00.000000Z"
183182
assert datetime_helpers.to_rfc3339(value, ignore_zone=False) == expected
184183

185184

186185
def test_to_rfc3339_with_non_utc_ignore_zone():
187-
zone = pytz.FixedOffset(-60)
186+
zone = datetime.timezone(datetime.timedelta(minutes=-60))
188187
value = datetime.datetime(2016, 4, 5, 13, 30, 0, tzinfo=zone)
189188
expected = "2016-04-05T13:30:00.000000Z"
190189
assert datetime_helpers.to_rfc3339(value, ignore_zone=True) == expected
@@ -283,7 +282,7 @@ def test_from_rfc3339_w_invalid():
283282
def test_from_rfc3339_wo_fraction():
284283
timestamp = "2016-12-20T21:13:47Z"
285284
expected = datetime_helpers.DatetimeWithNanoseconds(
286-
2016, 12, 20, 21, 13, 47, tzinfo=pytz.UTC
285+
2016, 12, 20, 21, 13, 47, tzinfo=datetime.timezone.utc
287286
)
288287
stamp = datetime_helpers.DatetimeWithNanoseconds.from_rfc3339(timestamp)
289288
assert stamp == expected
@@ -292,7 +291,7 @@ def test_from_rfc3339_wo_fraction():
292291
def test_from_rfc3339_w_partial_precision():
293292
timestamp = "2016-12-20T21:13:47.1Z"
294293
expected = datetime_helpers.DatetimeWithNanoseconds(
295-
2016, 12, 20, 21, 13, 47, microsecond=100000, tzinfo=pytz.UTC
294+
2016, 12, 20, 21, 13, 47, microsecond=100000, tzinfo=datetime.timezone.utc
296295
)
297296
stamp = datetime_helpers.DatetimeWithNanoseconds.from_rfc3339(timestamp)
298297
assert stamp == expected
@@ -301,7 +300,7 @@ def test_from_rfc3339_w_partial_precision():
301300
def test_from_rfc3339_w_full_precision():
302301
timestamp = "2016-12-20T21:13:47.123456789Z"
303302
expected = datetime_helpers.DatetimeWithNanoseconds(
304-
2016, 12, 20, 21, 13, 47, nanosecond=123456789, tzinfo=pytz.UTC
303+
2016, 12, 20, 21, 13, 47, nanosecond=123456789, tzinfo=datetime.timezone.utc
305304
)
306305
stamp = datetime_helpers.DatetimeWithNanoseconds.from_rfc3339(timestamp)
307306
assert stamp == expected
@@ -332,7 +331,9 @@ def test_timestamp_pb_wo_nanos_naive():
332331
stamp = datetime_helpers.DatetimeWithNanoseconds(
333332
2016, 12, 20, 21, 13, 47, 123456
334333
)
335-
delta = stamp.replace(tzinfo=pytz.UTC) - datetime_helpers._UTC_EPOCH
334+
delta = (
335+
stamp.replace(tzinfo=datetime.timezone.utc) - datetime_helpers._UTC_EPOCH
336+
)
336337
seconds = int(delta.total_seconds())
337338
nanos = 123456000
338339
timestamp = timestamp_pb2.Timestamp(seconds=seconds, nanos=nanos)
@@ -341,7 +342,7 @@ def test_timestamp_pb_wo_nanos_naive():
341342
@staticmethod
342343
def test_timestamp_pb_w_nanos():
343344
stamp = datetime_helpers.DatetimeWithNanoseconds(
344-
2016, 12, 20, 21, 13, 47, nanosecond=123456789, tzinfo=pytz.UTC
345+
2016, 12, 20, 21, 13, 47, nanosecond=123456789, tzinfo=datetime.timezone.utc
345346
)
346347
delta = stamp - datetime_helpers._UTC_EPOCH
347348
timestamp = timestamp_pb2.Timestamp(
@@ -351,7 +352,9 @@ def test_timestamp_pb_w_nanos():
351352

352353
@staticmethod
353354
def test_from_timestamp_pb_wo_nanos():
354-
when = datetime.datetime(2016, 12, 20, 21, 13, 47, 123456, tzinfo=pytz.UTC)
355+
when = datetime.datetime(
356+
2016, 12, 20, 21, 13, 47, 123456, tzinfo=datetime.timezone.utc
357+
)
355358
delta = when - datetime_helpers._UTC_EPOCH
356359
seconds = int(delta.total_seconds())
357360
timestamp = timestamp_pb2.Timestamp(seconds=seconds)
@@ -361,11 +364,13 @@ def test_from_timestamp_pb_wo_nanos():
361364
assert _to_seconds(when) == _to_seconds(stamp)
362365
assert stamp.microsecond == 0
363366
assert stamp.nanosecond == 0
364-
assert stamp.tzinfo == pytz.UTC
367+
assert stamp.tzinfo == datetime.timezone.utc
365368

366369
@staticmethod
367370
def test_from_timestamp_pb_w_nanos():
368-
when = datetime.datetime(2016, 12, 20, 21, 13, 47, 123456, tzinfo=pytz.UTC)
371+
when = datetime.datetime(
372+
2016, 12, 20, 21, 13, 47, 123456, tzinfo=datetime.timezone.utc
373+
)
369374
delta = when - datetime_helpers._UTC_EPOCH
370375
seconds = int(delta.total_seconds())
371376
timestamp = timestamp_pb2.Timestamp(seconds=seconds, nanos=123456789)
@@ -375,7 +380,7 @@ def test_from_timestamp_pb_w_nanos():
375380
assert _to_seconds(when) == _to_seconds(stamp)
376381
assert stamp.microsecond == 123456
377382
assert stamp.nanosecond == 123456789
378-
assert stamp.tzinfo == pytz.UTC
383+
assert stamp.tzinfo == datetime.timezone.utc
379384

380385

381386
def _to_seconds(value):
@@ -387,5 +392,5 @@ def _to_seconds(value):
387392
Returns:
388393
int: Microseconds since the unix epoch.
389394
"""
390-
assert value.tzinfo is pytz.UTC
395+
assert value.tzinfo is datetime.timezone.utc
391396
return calendar.timegm(value.timetuple())

0 commit comments

Comments
 (0)