Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 378b018

Browse files
committed
Drop dependency on pytz
Since pytz is only being used for UTC and fixed offsets — both of which are available in the standard library — there is no longer any reason for this dependency.
1 parent 7a09ca5 commit 378b018

File tree

3 files changed

+31
-33
lines changed

3 files changed

+31
-33
lines changed

google/api_core/datetime_helpers.py

Lines changed: 7 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.fromtimestamp(0, 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,7 @@ 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 = self if self.tzinfo is not None else self.replace(tzinfo=datetime.timezone.utc)
269267
delta = inst - _UTC_EPOCH
270268
seconds = int(delta.total_seconds())
271269
nanos = self._nanosecond or self.microsecond * 1000
@@ -292,5 +290,5 @@ def from_timestamp_pb(cls, stamp):
292290
bare.minute,
293291
bare.second,
294292
nanosecond=stamp.nanos,
295-
tzinfo=pytz.UTC,
293+
tzinfo=datetime.timezone.utc,
296294
)

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 >= 34.0.0",
3737
"six >= 1.10.0",
38-
"pytz",
3938
'futures >= 3.2.0; python_version < "3.2"',
4039
]
4140
extras = {

tests/unit/test_datetime_helpers.py

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@
1414

1515
import calendar
1616
import datetime
17+
from datetime import timezone, timedelta
1718

1819
import pytest
19-
import pytz
2020

2121
from google.api_core import datetime_helpers
2222
from google.protobuf import timestamp_pb2
2323

2424

25+
UTC = timezone.utc
2526
ONE_MINUTE_IN_MICROSECONDS = 60 * 1e6
2627

2728

@@ -31,7 +32,7 @@ def test_utcnow():
3132

3233

3334
def test_to_milliseconds():
34-
dt = datetime.datetime(1970, 1, 1, 0, 0, 1, tzinfo=pytz.utc)
35+
dt = datetime.datetime(1970, 1, 1, 0, 0, 1, tzinfo=UTC)
3536
assert datetime_helpers.to_milliseconds(dt) == 1000
3637

3738

@@ -42,7 +43,7 @@ def test_to_microseconds():
4243

4344

4445
def test_to_microseconds_non_utc():
45-
zone = pytz.FixedOffset(-1)
46+
zone = timezone(timedelta(minutes=-1))
4647
dt = datetime.datetime(1970, 1, 1, 0, 0, 0, tzinfo=zone)
4748
assert datetime_helpers.to_microseconds(dt) == ONE_MINUTE_IN_MICROSECONDS
4849

@@ -56,7 +57,7 @@ def test_to_microseconds_naive():
5657
def test_from_microseconds():
5758
five_mins_from_epoch_in_microseconds = 5 * ONE_MINUTE_IN_MICROSECONDS
5859
five_mins_from_epoch_datetime = datetime.datetime(
59-
1970, 1, 1, 0, 5, 0, tzinfo=pytz.utc
60+
1970, 1, 1, 0, 5, 0, tzinfo=UTC
6061
)
6162

6263
result = datetime_helpers.from_microseconds(five_mins_from_epoch_in_microseconds)
@@ -78,28 +79,28 @@ def test_from_iso8601_time():
7879
def test_from_rfc3339():
7980
value = "2009-12-17T12:44:32.123456Z"
8081
assert datetime_helpers.from_rfc3339(value) == datetime.datetime(
81-
2009, 12, 17, 12, 44, 32, 123456, pytz.utc
82+
2009, 12, 17, 12, 44, 32, 123456, UTC
8283
)
8384

8485

8586
def test_from_rfc3339_nanos():
8687
value = "2009-12-17T12:44:32.123456Z"
8788
assert datetime_helpers.from_rfc3339_nanos(value) == datetime.datetime(
88-
2009, 12, 17, 12, 44, 32, 123456, pytz.utc
89+
2009, 12, 17, 12, 44, 32, 123456, UTC
8990
)
9091

9192

9293
def test_from_rfc3339_without_nanos():
9394
value = "2009-12-17T12:44:32Z"
9495
assert datetime_helpers.from_rfc3339(value) == datetime.datetime(
95-
2009, 12, 17, 12, 44, 32, 0, pytz.utc
96+
2009, 12, 17, 12, 44, 32, 0, UTC
9697
)
9798

9899

99100
def test_from_rfc3339_nanos_without_nanos():
100101
value = "2009-12-17T12:44:32Z"
101102
assert datetime_helpers.from_rfc3339_nanos(value) == datetime.datetime(
102-
2009, 12, 17, 12, 44, 32, 0, pytz.utc
103+
2009, 12, 17, 12, 44, 32, 0, UTC
103104
)
104105

105106

@@ -119,7 +120,7 @@ def test_from_rfc3339_nanos_without_nanos():
119120
def test_from_rfc3339_with_truncated_nanos(truncated, micros):
120121
value = "2009-12-17T12:44:32.{}Z".format(truncated)
121122
assert datetime_helpers.from_rfc3339(value) == datetime.datetime(
122-
2009, 12, 17, 12, 44, 32, micros, pytz.utc
123+
2009, 12, 17, 12, 44, 32, micros, UTC
123124
)
124125

125126

@@ -148,7 +149,7 @@ def test_from_rfc3339_nanos_is_deprecated():
148149
def test_from_rfc3339_nanos_with_truncated_nanos(truncated, micros):
149150
value = "2009-12-17T12:44:32.{}Z".format(truncated)
150151
assert datetime_helpers.from_rfc3339_nanos(value) == datetime.datetime(
151-
2009, 12, 17, 12, 44, 32, micros, pytz.utc
152+
2009, 12, 17, 12, 44, 32, micros, UTC
152153
)
153154

154155

@@ -171,20 +172,20 @@ def test_to_rfc3339():
171172

172173

173174
def test_to_rfc3339_with_utc():
174-
value = datetime.datetime(2016, 4, 5, 13, 30, 0, tzinfo=pytz.utc)
175+
value = datetime.datetime(2016, 4, 5, 13, 30, 0, tzinfo=UTC)
175176
expected = "2016-04-05T13:30:00.000000Z"
176177
assert datetime_helpers.to_rfc3339(value, ignore_zone=False) == expected
177178

178179

179180
def test_to_rfc3339_with_non_utc():
180-
zone = pytz.FixedOffset(-60)
181+
zone = timezone(timedelta(minutes=-60))
181182
value = datetime.datetime(2016, 4, 5, 13, 30, 0, tzinfo=zone)
182183
expected = "2016-04-05T14:30:00.000000Z"
183184
assert datetime_helpers.to_rfc3339(value, ignore_zone=False) == expected
184185

185186

186187
def test_to_rfc3339_with_non_utc_ignore_zone():
187-
zone = pytz.FixedOffset(-60)
188+
zone = timezone(timedelta(minutes=-60))
188189
value = datetime.datetime(2016, 4, 5, 13, 30, 0, tzinfo=zone)
189190
expected = "2016-04-05T13:30:00.000000Z"
190191
assert datetime_helpers.to_rfc3339(value, ignore_zone=True) == expected
@@ -283,7 +284,7 @@ def test_from_rfc3339_w_invalid():
283284
def test_from_rfc3339_wo_fraction():
284285
timestamp = "2016-12-20T21:13:47Z"
285286
expected = datetime_helpers.DatetimeWithNanoseconds(
286-
2016, 12, 20, 21, 13, 47, tzinfo=pytz.UTC
287+
2016, 12, 20, 21, 13, 47, tzinfo=UTC
287288
)
288289
stamp = datetime_helpers.DatetimeWithNanoseconds.from_rfc3339(timestamp)
289290
assert stamp == expected
@@ -292,7 +293,7 @@ def test_from_rfc3339_wo_fraction():
292293
def test_from_rfc3339_w_partial_precision():
293294
timestamp = "2016-12-20T21:13:47.1Z"
294295
expected = datetime_helpers.DatetimeWithNanoseconds(
295-
2016, 12, 20, 21, 13, 47, microsecond=100000, tzinfo=pytz.UTC
296+
2016, 12, 20, 21, 13, 47, microsecond=100000, tzinfo=UTC
296297
)
297298
stamp = datetime_helpers.DatetimeWithNanoseconds.from_rfc3339(timestamp)
298299
assert stamp == expected
@@ -301,7 +302,7 @@ def test_from_rfc3339_w_partial_precision():
301302
def test_from_rfc3339_w_full_precision():
302303
timestamp = "2016-12-20T21:13:47.123456789Z"
303304
expected = datetime_helpers.DatetimeWithNanoseconds(
304-
2016, 12, 20, 21, 13, 47, nanosecond=123456789, tzinfo=pytz.UTC
305+
2016, 12, 20, 21, 13, 47, nanosecond=123456789, tzinfo=UTC
305306
)
306307
stamp = datetime_helpers.DatetimeWithNanoseconds.from_rfc3339(timestamp)
307308
assert stamp == expected
@@ -332,7 +333,7 @@ def test_timestamp_pb_wo_nanos_naive():
332333
stamp = datetime_helpers.DatetimeWithNanoseconds(
333334
2016, 12, 20, 21, 13, 47, 123456
334335
)
335-
delta = stamp.replace(tzinfo=pytz.UTC) - datetime_helpers._UTC_EPOCH
336+
delta = stamp.replace(tzinfo=UTC) - datetime_helpers._UTC_EPOCH
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=UTC
345346
)
346347
delta = stamp - datetime_helpers._UTC_EPOCH
347348
timestamp = timestamp_pb2.Timestamp(
@@ -351,7 +352,7 @@ 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(2016, 12, 20, 21, 13, 47, 123456, tzinfo=UTC)
355356
delta = when - datetime_helpers._UTC_EPOCH
356357
seconds = int(delta.total_seconds())
357358
timestamp = timestamp_pb2.Timestamp(seconds=seconds)
@@ -361,11 +362,11 @@ def test_from_timestamp_pb_wo_nanos():
361362
assert _to_seconds(when) == _to_seconds(stamp)
362363
assert stamp.microsecond == 0
363364
assert stamp.nanosecond == 0
364-
assert stamp.tzinfo == pytz.UTC
365+
assert stamp.tzinfo == UTC
365366

366367
@staticmethod
367368
def test_from_timestamp_pb_w_nanos():
368-
when = datetime.datetime(2016, 12, 20, 21, 13, 47, 123456, tzinfo=pytz.UTC)
369+
when = datetime.datetime(2016, 12, 20, 21, 13, 47, 123456, tzinfo=UTC)
369370
delta = when - datetime_helpers._UTC_EPOCH
370371
seconds = int(delta.total_seconds())
371372
timestamp = timestamp_pb2.Timestamp(seconds=seconds, nanos=123456789)
@@ -375,7 +376,7 @@ def test_from_timestamp_pb_w_nanos():
375376
assert _to_seconds(when) == _to_seconds(stamp)
376377
assert stamp.microsecond == 123456
377378
assert stamp.nanosecond == 123456789
378-
assert stamp.tzinfo == pytz.UTC
379+
assert stamp.tzinfo == UTC
379380

380381

381382
def _to_seconds(value):
@@ -387,5 +388,5 @@ def _to_seconds(value):
387388
Returns:
388389
int: Microseconds since the unix epoch.
389390
"""
390-
assert value.tzinfo is pytz.UTC
391+
assert value.tzinfo is UTC
391392
return calendar.timegm(value.timetuple())

0 commit comments

Comments
 (0)