Skip to content

Commit d4bd53d

Browse files
committed
Merge branch 'main' into shuowei-gbq-delegation-telemetry-mvp
2 parents db0c1b9 + 26d43c1 commit d4bd53d

5 files changed

Lines changed: 28 additions & 23 deletions

File tree

.github/workflows/import-profiler.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ jobs:
2626
with:
2727
python-version: "3.15"
2828
allow-prereleases: true
29+
cache: 'pip'
2930
- name: Run import profiler
3031
env:
3132
BUILD_TYPE: presubmit

packages/google-api-core/google/api_core/gapic_v1/requests.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def setup_request_id(
6565
setattr(request, field_name, str(uuid.uuid4()))
6666
except (AttributeError, ValueError):
6767
# Proto-plus messages or other objects
68-
if not getattr(request, field_name, None):
68+
if getattr(request, field_name, None) is None:
6969
setattr(request, field_name, str(uuid.uuid4()))
7070
else:
7171
if not getattr(request, field_name, None):

packages/google-api-core/tests/unit/gapic/test_requests.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@ def __init__(self, **kwargs):
2727
for k, v in kwargs.items():
2828
setattr(self, k, v)
2929

30-
def __contains__(self, key):
31-
return hasattr(self, key)
32-
3330

3431
class MockProtoRequest:
3532
def __init__(self, **kwargs):
@@ -44,9 +41,6 @@ class MockValueErrorRequest:
4441
def HasField(self, key):
4542
raise ValueError("Mismatched field")
4643

47-
def __contains__(self, key):
48-
return hasattr(self, key)
49-
5044

5145
# --- Parameterized Test ---
5246

@@ -59,6 +53,7 @@ def __contains__(self, key):
5953
# MockRequest cases
6054
(MockRequest(), True, "uuid"),
6155
(MockRequest(request_id="already_set"), True, "already_set"),
56+
(MockRequest(request_id=""), True, ""),
6257
(MockRequest(request_id=""), False, "uuid"),
6358
(MockRequest(request_id="already_set"), False, "already_set"),
6459
# MockProtoRequest cases
@@ -70,6 +65,7 @@ def __contains__(self, key):
7065
({}, True, "uuid"),
7166
({"request_id": None}, True, "uuid"),
7267
({"request_id": "already_set"}, True, "already_set"),
68+
({"request_id": ""}, True, ""),
7369
({"request_id": ""}, False, "uuid"),
7470
({"request_id": None}, False, "uuid"),
7571
({"request_id": "already_set"}, False, "already_set"),
@@ -79,6 +75,7 @@ def __contains__(self, key):
7975
ids=[
8076
"proto3_optional_not_in_request",
8177
"proto3_optional_already_in_request",
78+
"proto3_optional_explicit_empty",
8279
"non_proto3_optional_empty",
8380
"non_proto3_optional_already_set",
8481
"proto3_optional_not_in_request_proto",
@@ -87,6 +84,7 @@ def __contains__(self, key):
8784
"dict_proto3_optional_not_in_request",
8885
"dict_proto3_optional_value_none",
8986
"dict_proto3_optional_already_in_request",
87+
"dict_proto3_optional_explicit_empty",
9088
"dict_non_proto3_optional_empty",
9189
"dict_non_proto3_optional_value_none",
9290
"dict_non_proto3_optional_already_set",
@@ -110,6 +108,20 @@ def test_setup_request_id(request_obj, is_proto3_optional, expected):
110108
)
111109

112110
if expected == "uuid":
113-
assert re.match(UUID_REGEX, value)
111+
assert re.fullmatch(UUID_REGEX, value)
114112
else:
115113
assert value == expected
114+
115+
116+
def test_setup_request_id_assertion_strictness(mocker):
117+
# Mock uuid.uuid4 to return a UUID with trailing characters
118+
mock_uuid = mocker.patch("uuid.uuid4")
119+
mock_uuid.return_value.__str__.return_value = (
120+
"12345678-1234-4123-8123-123456789012-extra"
121+
)
122+
123+
# We expect test_setup_request_id to fail (raise AssertionError) because the UUID is invalid.
124+
# If test_setup_request_id uses re.fullmatch, it will fail (raise AssertionError), so pytest.raises passes.
125+
# If test_setup_request_id uses re.match, it will NOT fail, so pytest.raises fails!
126+
with pytest.raises(AssertionError):
127+
test_setup_request_id(MockRequest(), is_proto3_optional=True, expected="uuid")

packages/sqlalchemy-bigquery/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ def readme():
121121
"sqlalchemy>=1.4.16,<3.0.0",
122122
],
123123
extras_require=extras,
124-
python_requires=">=3.10, <3.15",
124+
python_requires=">=3.10",
125125
tests_require=["packaging", "pytz"],
126126
entry_points={
127127
"sqlalchemy.dialects": ["bigquery = sqlalchemy_bigquery:BigQueryDialect"]

packages/sqlalchemy-bigquery/tests/system/test_geography.py

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
geoalchemy2 = pytest.importorskip("geoalchemy2")
2323

2424

25-
# TODO(http://github.com/googleapis/google-cloud-python/issues/17287): Unskip once bug is resolved.
26-
@pytest.mark.skip(reason="Failing in CI with AssertionError.")
2725
def test_geoalchemy2_core(bigquery_dataset):
2826
"""Make sure GeoAlchemy 2 Core Tutorial works as adapted to only having geography
2927
@@ -44,7 +42,7 @@ def test_geoalchemy2_core(bigquery_dataset):
4442

4543
from sqlalchemy import Column, MetaData, String, Table
4644

47-
from sqlalchemy_bigquery import GEOGRAPHY
45+
from sqlalchemy_bigquery import GEOGRAPHY, WKT
4846

4947
metadata = MetaData()
5048
lake_table = Table(
@@ -86,7 +84,7 @@ def test_geoalchemy2_core(bigquery_dataset):
8684

8785
[[result]] = conn.execute(
8886
select(lake_table.c.name).where(
89-
func.ST_Contains(lake_table.c.geog, "POINT(4 1)")
87+
func.ST_Contains(lake_table.c.geog, WKT("POINT(4 1)"))
9088
)
9189
)
9290
assert result == "Orta"
@@ -119,8 +117,6 @@ def test_geoalchemy2_core(bigquery_dataset):
119117

120118
# and, while we're at it, that we can insert WKTs, although we
121119
# normally wouldn't want to.
122-
from sqlalchemy_bigquery import WKT
123-
124120
conn.execute(
125121
lake_table.insert().values(
126122
name="test2",
@@ -141,8 +137,6 @@ def test_geoalchemy2_core(bigquery_dataset):
141137
)
142138

143139

144-
# TODO(http://github.com/googleapis/google-cloud-python/issues/17287): Unskip once bug is resolved.
145-
@pytest.mark.skip(reason="Failing in CI with AssertionError.")
146140
def test_geoalchemy2_orm(bigquery_dataset):
147141
"""Make sure GeoAlchemy 2 ORM Tutorial works as adapted to only having geometry
148142
@@ -160,7 +154,7 @@ def test_geoalchemy2_orm(bigquery_dataset):
160154
from sqlalchemy import Column, Integer, String
161155
from sqlalchemy.ext.declarative import declarative_base
162156

163-
from sqlalchemy_bigquery import GEOGRAPHY
157+
from sqlalchemy_bigquery import GEOGRAPHY, WKT
164158

165159
Base = declarative_base()
166160

@@ -224,19 +218,19 @@ class Lake(Base):
224218

225219
from sqlalchemy import func
226220

227-
query = session.query(Lake).filter(func.ST_Contains(Lake.geog, "POINT(4 1)"))
221+
query = session.query(Lake).filter(func.ST_Contains(Lake.geog, WKT("POINT(4 1)")))
228222

229223
assert [lake.name for lake in query] == ["Orta"]
230224

231225
query = (
232226
session.query(Lake)
233-
.filter(Lake.geog.ST_Intersects("LINESTRING(2 1,4 1)"))
227+
.filter(Lake.geog.ST_Intersects(WKT("LINESTRING(2 1,4 1)")))
234228
.order_by(Lake.name)
235229
)
236230
assert [lake.name for lake in query] == ["Garde", "Orta"]
237231

238232
lake = session.query(Lake).filter_by(name="Garde").one()
239-
assert session.scalar(lake.geog.ST_Intersects("LINESTRING(2 1,4 1)"))
233+
assert session.scalar(lake.geog.ST_Intersects(WKT("LINESTRING(2 1,4 1)")))
240234

241235
# Use Other Spatial Functions
242236
query = session.query(Lake.name, func.ST_Area(Lake.geog).label("area")).order_by(
@@ -258,8 +252,6 @@ class Lake(Base):
258252
]
259253

260254

261-
# TODO(http://github.com/googleapis/google-cloud-python/issues/17287): Unskip once bug is resolved.
262-
@pytest.mark.skip(reason="Failing in CI with AssertionError.")
263255
def test_geoalchemy2_orm_w_relationship(bigquery_dataset):
264256
from sqlalchemy import create_engine
265257

0 commit comments

Comments
 (0)