aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--google/api_core/bidi.py10
-rw-r--r--google/api_core/datetime_helpers.py37
-rw-r--r--google/api_core/iam.py3
-rw-r--r--google/api_core/protobuf_helpers.py10
-rw-r--r--google/api_core/retry.py2
-rw-r--r--tests/unit/test_datetime_helpers.py88
6 files changed, 93 insertions, 57 deletions
diff --git a/google/api_core/bidi.py b/google/api_core/bidi.py
index b171a41..be52d97 100644
--- a/google/api_core/bidi.py
+++ b/google/api_core/bidi.py
@@ -172,7 +172,9 @@ class _Throttle(object):
self._time_window = time_window
self._access_limit = access_limit
- self._past_entries = collections.deque(maxlen=access_limit) # least recent first
+ self._past_entries = collections.deque(
+ maxlen=access_limit
+ ) # least recent first
self._entry_lock = threading.Lock()
def __enter__(self):
@@ -198,9 +200,7 @@ class _Throttle(object):
def __repr__(self):
return "{}(access_limit={}, time_window={})".format(
- self.__class__.__name__,
- self._access_limit,
- repr(self._time_window),
+ self.__class__.__name__, self._access_limit, repr(self._time_window)
)
@@ -423,7 +423,7 @@ class ResumableBidiRpc(BidiRpc):
if throttle_reopen:
self._reopen_throttle = _Throttle(
- access_limit=5, time_window=datetime.timedelta(seconds=10),
+ access_limit=5, time_window=datetime.timedelta(seconds=10)
)
else:
self._reopen_throttle = None
diff --git a/google/api_core/datetime_helpers.py b/google/api_core/datetime_helpers.py
index 84c1bb7..e52fb1d 100644
--- a/google/api_core/datetime_helpers.py
+++ b/google/api_core/datetime_helpers.py
@@ -115,20 +115,10 @@ def from_iso8601_time(value):
def from_rfc3339(value):
- """Convert a microsecond-precision timestamp to datetime.
+ """Convert an RFC3339-format timestamp to a native datetime.
- Args:
- value (str): The RFC3339 string to convert.
-
- Returns:
- datetime.datetime: The datetime object equivalent to the timestamp in
- UTC.
- """
- return datetime.datetime.strptime(value, _RFC3339_MICROS).replace(tzinfo=pytz.utc)
-
-
-def from_rfc3339_nanos(value):
- """Convert a nanosecond-precision timestamp to a native datetime.
+ Supported formats include those without fractional seconds, or with
+ any fraction up to nanosecond precision.
.. note::
Python datetimes do not support nanosecond precision; this function
@@ -138,11 +128,11 @@ def from_rfc3339_nanos(value):
value (str): The RFC3339 string to convert.
Returns:
- datetime.datetime: The datetime object equivalent to the timestamp in
- UTC.
+ datetime.datetime: The datetime object equivalent to the timestamp
+ in UTC.
Raises:
- ValueError: If the timestamp does not match the RFC 3339
+ ValueError: If the timestamp does not match the RFC3339
regular expression.
"""
with_nanos = _RFC3339_NANOS.match(value)
@@ -169,6 +159,9 @@ def from_rfc3339_nanos(value):
return bare_seconds.replace(microsecond=micros, tzinfo=pytz.utc)
+from_rfc3339_nanos = from_rfc3339 # from_rfc3339_nanos method was deprecated.
+
+
def to_rfc3339(value, ignore_zone=True):
"""Convert a datetime to an RFC3339 timestamp string.
@@ -215,22 +208,22 @@ class DatetimeWithNanoseconds(datetime.datetime):
return self._nanosecond
def rfc3339(self):
- """Return an RFC 3339-compliant timestamp.
+ """Return an RFC3339-compliant timestamp.
Returns:
- (str): Timestamp string according to RFC 3339 spec.
+ (str): Timestamp string according to RFC3339 spec.
"""
if self._nanosecond == 0:
return to_rfc3339(self)
- nanos = str(self._nanosecond).rjust(9, '0').rstrip("0")
+ nanos = str(self._nanosecond).rjust(9, "0").rstrip("0")
return "{}.{}Z".format(self.strftime(_RFC3339_NO_FRACTION), nanos)
@classmethod
def from_rfc3339(cls, stamp):
- """Parse RFC 3339-compliant timestamp, preserving nanoseconds.
+ """Parse RFC3339-compliant timestamp, preserving nanoseconds.
Args:
- stamp (str): RFC 3339 stamp, with up to nanosecond precision
+ stamp (str): RFC3339 stamp, with up to nanosecond precision
Returns:
:class:`DatetimeWithNanoseconds`:
@@ -280,7 +273,7 @@ class DatetimeWithNanoseconds(datetime.datetime):
@classmethod
def from_timestamp_pb(cls, stamp):
- """Parse RFC 3339-compliant timestamp, preserving nanoseconds.
+ """Parse RFC3339-compliant timestamp, preserving nanoseconds.
Args:
stamp (:class:`~google.protobuf.timestamp_pb2.Timestamp`): timestamp message
diff --git a/google/api_core/iam.py b/google/api_core/iam.py
index 0e108a3..04680eb 100644
--- a/google/api_core/iam.py
+++ b/google/api_core/iam.py
@@ -34,11 +34,12 @@ Example usage:
"""
import collections
+import warnings
+
try:
from collections import abc as collections_abc
except ImportError: # Python 2.7
import collections as collections_abc
-import warnings
# Generic IAM roles
diff --git a/google/api_core/protobuf_helpers.py b/google/api_core/protobuf_helpers.py
index aec6b36..365ef25 100644
--- a/google/api_core/protobuf_helpers.py
+++ b/google/api_core/protobuf_helpers.py
@@ -15,10 +15,6 @@
"""Helpers for :mod:`protobuf`."""
import collections
-try:
- from collections import abc as collections_abc
-except ImportError: # Python 2.7
- import collections as collections_abc
import copy
import inspect
@@ -26,6 +22,12 @@ from google.protobuf import field_mask_pb2
from google.protobuf import message
from google.protobuf import wrappers_pb2
+try:
+ from collections import abc as collections_abc
+except ImportError: # Python 2.7
+ import collections as collections_abc
+
+
_SENTINEL = object()
_WRAPPER_TYPES = (
wrappers_pb2.BoolValue,
diff --git a/google/api_core/retry.py b/google/api_core/retry.py
index 79343ba..5962a68 100644
--- a/google/api_core/retry.py
+++ b/google/api_core/retry.py
@@ -237,7 +237,7 @@ class Retry(object):
maximum=_DEFAULT_MAXIMUM_DELAY,
multiplier=_DEFAULT_DELAY_MULTIPLIER,
deadline=_DEFAULT_DEADLINE,
- on_error=None
+ on_error=None,
):
self._predicate = predicate
self._initial = initial
diff --git a/tests/unit/test_datetime_helpers.py b/tests/unit/test_datetime_helpers.py
index 4d138c8..4ddcf36 100644
--- a/tests/unit/test_datetime_helpers.py
+++ b/tests/unit/test_datetime_helpers.py
@@ -82,18 +82,18 @@ def test_from_rfc3339():
)
-def test_from_rfc3339_with_bad_tz():
- value = "2009-12-17T12:44:32.123456BAD"
-
- with pytest.raises(ValueError):
- datetime_helpers.from_rfc3339(value)
-
+def test_from_rfc3339_nanos():
+ value = "2009-12-17T12:44:32.123456Z"
+ assert datetime_helpers.from_rfc3339_nanos(value) == datetime.datetime(
+ 2009, 12, 17, 12, 44, 32, 123456, pytz.utc
+ )
-def test_from_rfc3339_with_nanos():
- value = "2009-12-17T12:44:32.123456789Z"
- with pytest.raises(ValueError):
- datetime_helpers.from_rfc3339(value)
+def test_from_rfc3339_without_nanos():
+ value = "2009-12-17T12:44:32Z"
+ assert datetime_helpers.from_rfc3339(value) == datetime.datetime(
+ 2009, 12, 17, 12, 44, 32, 0, pytz.utc
+ )
def test_from_rfc3339_nanos_without_nanos():
@@ -103,11 +103,33 @@ def test_from_rfc3339_nanos_without_nanos():
)
-def test_from_rfc3339_nanos_with_bad_tz():
- value = "2009-12-17T12:44:32.123456789BAD"
+@pytest.mark.parametrize(
+ "truncated, micros",
+ [
+ ("12345678", 123456),
+ ("1234567", 123456),
+ ("123456", 123456),
+ ("12345", 123450),
+ ("1234", 123400),
+ ("123", 123000),
+ ("12", 120000),
+ ("1", 100000),
+ ],
+)
+def test_from_rfc3339_with_truncated_nanos(truncated, micros):
+ value = "2009-12-17T12:44:32.{}Z".format(truncated)
+ assert datetime_helpers.from_rfc3339(value) == datetime.datetime(
+ 2009, 12, 17, 12, 44, 32, micros, pytz.utc
+ )
+
+
+def test_from_rfc3339_nanos_is_deprecated():
+ value = "2009-12-17T12:44:32.123456Z"
- with pytest.raises(ValueError):
- datetime_helpers.from_rfc3339_nanos(value)
+ result = datetime_helpers.from_rfc3339(value)
+ result_nanos = datetime_helpers.from_rfc3339_nanos(value)
+
+ assert result == result_nanos
@pytest.mark.parametrize(
@@ -130,6 +152,18 @@ def test_from_rfc3339_nanos_with_truncated_nanos(truncated, micros):
)
+def test_from_rfc3339_wo_nanos_raise_exception():
+ value = "2009-12-17T12:44:32"
+ with pytest.raises(ValueError):
+ datetime_helpers.from_rfc3339(value)
+
+
+def test_from_rfc3339_w_nanos_raise_exception():
+ value = "2009-12-17T12:44:32.123456"
+ with pytest.raises(ValueError):
+ datetime_helpers.from_rfc3339(value)
+
+
def test_to_rfc3339():
value = datetime.datetime(2016, 4, 5, 13, 30, 0)
expected = "2016-04-05T13:30:00.000000Z"
@@ -157,10 +191,11 @@ def test_to_rfc3339_with_non_utc_ignore_zone():
class Test_DateTimeWithNanos(object):
-
@staticmethod
def test_ctor_wo_nanos():
- stamp = datetime_helpers.DatetimeWithNanoseconds(2016, 12, 20, 21, 13, 47, 123456)
+ stamp = datetime_helpers.DatetimeWithNanoseconds(
+ 2016, 12, 20, 21, 13, 47, 123456
+ )
assert stamp.year == 2016
assert stamp.month == 12
assert stamp.day == 20
@@ -200,7 +235,9 @@ class Test_DateTimeWithNanos(object):
@staticmethod
def test_rfc3339_wo_nanos():
- stamp = datetime_helpers.DatetimeWithNanoseconds(2016, 12, 20, 21, 13, 47, 123456)
+ stamp = datetime_helpers.DatetimeWithNanoseconds(
+ 2016, 12, 20, 21, 13, 47, 123456
+ )
assert stamp.rfc3339() == "2016-12-20T21:13:47.123456Z"
@staticmethod
@@ -285,12 +322,16 @@ class Test_DateTimeWithNanos(object):
)
def test_from_rfc3339_test_nanoseconds(fractional, nanos):
value = "2009-12-17T12:44:32.{}Z".format(fractional)
- assert datetime_helpers.DatetimeWithNanoseconds.from_rfc3339(value).nanosecond == nanos
+ assert (
+ datetime_helpers.DatetimeWithNanoseconds.from_rfc3339(value).nanosecond
+ == nanos
+ )
@staticmethod
def test_timestamp_pb_wo_nanos_naive():
stamp = datetime_helpers.DatetimeWithNanoseconds(
- 2016, 12, 20, 21, 13, 47, 123456)
+ 2016, 12, 20, 21, 13, 47, 123456
+ )
delta = stamp.replace(tzinfo=pytz.UTC) - datetime_helpers._UTC_EPOCH
seconds = int(delta.total_seconds())
nanos = 123456000
@@ -304,7 +345,8 @@ class Test_DateTimeWithNanos(object):
)
delta = stamp - datetime_helpers._UTC_EPOCH
timestamp = timestamp_pb2.Timestamp(
- seconds=int(delta.total_seconds()), nanos=123456789)
+ seconds=int(delta.total_seconds()), nanos=123456789
+ )
assert stamp.timestamp_pb() == timestamp
@staticmethod
@@ -314,8 +356,7 @@ class Test_DateTimeWithNanos(object):
seconds = int(delta.total_seconds())
timestamp = timestamp_pb2.Timestamp(seconds=seconds)
- stamp = datetime_helpers.DatetimeWithNanoseconds.from_timestamp_pb(
- timestamp)
+ stamp = datetime_helpers.DatetimeWithNanoseconds.from_timestamp_pb(timestamp)
assert _to_seconds(when) == _to_seconds(stamp)
assert stamp.microsecond == 0
@@ -329,8 +370,7 @@ class Test_DateTimeWithNanos(object):
seconds = int(delta.total_seconds())
timestamp = timestamp_pb2.Timestamp(seconds=seconds, nanos=123456789)
- stamp = datetime_helpers.DatetimeWithNanoseconds.from_timestamp_pb(
- timestamp)
+ stamp = datetime_helpers.DatetimeWithNanoseconds.from_timestamp_pb(timestamp)
assert _to_seconds(when) == _to_seconds(stamp)
assert stamp.microsecond == 123456