Skip to content

Commit

Permalink
Merge branch 'main' into renovate/all
Browse files Browse the repository at this point in the history
  • Loading branch information
harshachinta committed Apr 23, 2024
2 parents d750b17 + 5474707 commit d799698
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "3.44.0"
".": "3.45.0"
}
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@

[1]: https://pypi.org/project/google-cloud-spanner/#history

## [3.45.0](https://github.com/googleapis/python-spanner/compare/v3.44.0...v3.45.0) (2024-04-17)


### Features

* Add support for PG.OID in parameterized queries ([#1035](https://github.com/googleapis/python-spanner/issues/1035)) ([ea5efe4](https://github.com/googleapis/python-spanner/commit/ea5efe4d0bc2790b5172e43e1b66fa3997190adf))


### Bug Fixes

* Dates before 1000AD should use 4-digit years ([#1132](https://github.com/googleapis/python-spanner/issues/1132)) ([0ef6565](https://github.com/googleapis/python-spanner/commit/0ef65657de631d876636d11756237496b7713e22)), closes [#1131](https://github.com/googleapis/python-spanner/issues/1131)

## [3.44.0](https://github.com/googleapis/python-spanner/compare/v3.43.0...v3.44.0) (2024-03-13)


Expand Down
2 changes: 1 addition & 1 deletion google/cloud/spanner_admin_database_v1/gapic_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
__version__ = "3.44.0" # {x-release-please-version}
__version__ = "3.45.0" # {x-release-please-version}
2 changes: 1 addition & 1 deletion google/cloud/spanner_admin_instance_v1/gapic_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
__version__ = "3.44.0" # {x-release-please-version}
__version__ = "3.45.0" # {x-release-please-version}
39 changes: 36 additions & 3 deletions google/cloud/spanner_v1/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@

from google.api_core import datetime_helpers
from google.cloud._helpers import _date_from_iso8601_date
from google.cloud._helpers import _datetime_to_rfc3339
from google.cloud.spanner_v1 import TypeCode
from google.cloud.spanner_v1 import ExecuteSqlRequest
from google.cloud.spanner_v1 import JsonObject
Expand Down Expand Up @@ -122,6 +121,40 @@ def _assert_numeric_precision_and_scale(value):
raise ValueError(NUMERIC_MAX_PRECISION_ERR_MSG.format(precision + scale))


def _datetime_to_rfc3339(value):
"""Format the provided datatime in the RFC 3339 format.
:type value: datetime.datetime
:param value: value to format
:rtype: str
:returns: RFC 3339 formatted datetime string
"""
# Convert to UTC and then drop the timezone so we can append "Z" in lieu of
# allowing isoformat to append the "+00:00" zone offset.
value = value.astimezone(datetime.timezone.utc).replace(tzinfo=None)
return value.isoformat(sep="T", timespec="microseconds") + "Z"


def _datetime_to_rfc3339_nanoseconds(value):
"""Format the provided datatime in the RFC 3339 format.
:type value: datetime_helpers.DatetimeWithNanoseconds
:param value: value to format
:rtype: str
:returns: RFC 3339 formatted datetime string
"""

if value.nanosecond == 0:
return _datetime_to_rfc3339(value)
nanos = str(value.nanosecond).rjust(9, "0").rstrip("0")
# Convert to UTC and then drop the timezone so we can append "Z" in lieu of
# allowing isoformat to append the "+00:00" zone offset.
value = value.astimezone(datetime.timezone.utc).replace(tzinfo=None)
return "{}.{}Z".format(value.isoformat(sep="T", timespec="seconds"), nanos)


def _make_value_pb(value):
"""Helper for :func:`_make_list_value_pbs`.
Expand Down Expand Up @@ -150,9 +183,9 @@ def _make_value_pb(value):
return Value(string_value="-Infinity")
return Value(number_value=value)
if isinstance(value, datetime_helpers.DatetimeWithNanoseconds):
return Value(string_value=value.rfc3339())
return Value(string_value=_datetime_to_rfc3339_nanoseconds(value))
if isinstance(value, datetime.datetime):
return Value(string_value=_datetime_to_rfc3339(value, ignore_zone=False))
return Value(string_value=_datetime_to_rfc3339(value))
if isinstance(value, datetime.date):
return Value(string_value=value.isoformat())
if isinstance(value, bytes):
Expand Down
2 changes: 1 addition & 1 deletion google/cloud/spanner_v1/gapic_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
__version__ = "3.44.0" # {x-release-please-version}
__version__ = "3.45.0" # {x-release-please-version}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
],
"language": "PYTHON",
"name": "google-cloud-spanner-admin-database",
"version": "3.44.0"
"version": "3.45.0"
},
"snippets": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
],
"language": "PYTHON",
"name": "google-cloud-spanner-admin-instance",
"version": "3.44.0"
"version": "3.45.0"
},
"snippets": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
],
"language": "PYTHON",
"name": "google-cloud-spanner",
"version": "3.44.0"
"version": "3.45.0"
},
"snippets": [
{
Expand Down
49 changes: 44 additions & 5 deletions tests/unit/test__helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,15 @@ def test_w_date(self):
self.assertIsInstance(value_pb, Value)
self.assertEqual(value_pb.string_value, today.isoformat())

def test_w_date_pre1000ad(self):
import datetime
from google.protobuf.struct_pb2 import Value

when = datetime.date(800, 2, 25)
value_pb = self._callFUT(when)
self.assertIsInstance(value_pb, Value)
self.assertEqual(value_pb.string_value, "0800-02-25")

def test_w_timestamp_w_nanos(self):
import datetime
from google.protobuf.struct_pb2 import Value
Expand All @@ -200,7 +209,19 @@ def test_w_timestamp_w_nanos(self):
)
value_pb = self._callFUT(when)
self.assertIsInstance(value_pb, Value)
self.assertEqual(value_pb.string_value, when.rfc3339())
self.assertEqual(value_pb.string_value, "2016-12-20T21:13:47.123456789Z")

def test_w_timestamp_w_nanos_pre1000ad(self):
import datetime
from google.protobuf.struct_pb2 import Value
from google.api_core import datetime_helpers

when = datetime_helpers.DatetimeWithNanoseconds(
850, 12, 20, 21, 13, 47, nanosecond=123456789, tzinfo=datetime.timezone.utc
)
value_pb = self._callFUT(when)
self.assertIsInstance(value_pb, Value)
self.assertEqual(value_pb.string_value, "0850-12-20T21:13:47.123456789Z")

def test_w_listvalue(self):
from google.protobuf.struct_pb2 import Value
Expand All @@ -214,12 +235,20 @@ def test_w_listvalue(self):
def test_w_datetime(self):
import datetime
from google.protobuf.struct_pb2 import Value
from google.api_core import datetime_helpers

now = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)
value_pb = self._callFUT(now)
when = datetime.datetime(2021, 2, 8, 0, 0, 0, tzinfo=datetime.timezone.utc)
value_pb = self._callFUT(when)
self.assertIsInstance(value_pb, Value)
self.assertEqual(value_pb.string_value, "2021-02-08T00:00:00.000000Z")

def test_w_datetime_pre1000ad(self):
import datetime
from google.protobuf.struct_pb2 import Value

when = datetime.datetime(916, 2, 8, 0, 0, 0, tzinfo=datetime.timezone.utc)
value_pb = self._callFUT(when)
self.assertIsInstance(value_pb, Value)
self.assertEqual(value_pb.string_value, datetime_helpers.to_rfc3339(now))
self.assertEqual(value_pb.string_value, "0916-02-08T00:00:00.000000Z")

def test_w_timestamp_w_tz(self):
import datetime
Expand All @@ -231,6 +260,16 @@ def test_w_timestamp_w_tz(self):
self.assertIsInstance(value_pb, Value)
self.assertEqual(value_pb.string_value, "2021-02-07T23:00:00.000000Z")

def test_w_timestamp_w_tz_pre1000ad(self):
import datetime
from google.protobuf.struct_pb2 import Value

zone = datetime.timezone(datetime.timedelta(hours=+1), name="CET")
when = datetime.datetime(721, 2, 8, 0, 0, 0, tzinfo=zone)
value_pb = self._callFUT(when)
self.assertIsInstance(value_pb, Value)
self.assertEqual(value_pb.string_value, "0721-02-07T23:00:00.000000Z")

def test_w_unknown_type(self):
with self.assertRaises(ValueError):
self._callFUT(object())
Expand Down

0 comments on commit d799698

Please sign in to comment.