Skip to content

Commit 21ce008

Browse files
Merge branch 'main' into owl-bot-update-lock-58dd193e1be3f5f02276cdf222ed7f8dfc3be1f163488aea767bcf35a0e2b0cd
2 parents caa121c + 62f7c5b commit 21ce008

File tree

5 files changed

+58
-9
lines changed

5 files changed

+58
-9
lines changed

README.rst

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,8 @@ A logging scope is a period-separated namespace that begins with :code:`google`,
132132

133133
**NOTE**: If the logging scope is invalid, the library does not set up any logging handlers.
134134

135-
Examples
136-
^^^^^^^^
137-
135+
Environment-Based Examples
136+
^^^^^^^^^^^^^^^^^^^^^^^^^^
138137
- Enabling the default handler for all Google-based loggers
139138

140139
.. code-block:: console
@@ -153,8 +152,8 @@ Advanced, code-based configuration
153152

154153
You can also configure a valid logging scope using Python's standard `logging` mechanism.
155154

156-
Examples
157-
^^^^^^^^
155+
Code-Based Examples
156+
^^^^^^^^^^^^^^^^^^^
158157

159158
- Configuring a handler for all Google-based loggers
160159

google/cloud/firestore_v1/field_path.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
_ESCAPED_BACKTICK = _BACKSLASH + _BACKTICK
3232

3333
_SIMPLE_FIELD_NAME = re.compile("^[_a-zA-Z][_a-zA-Z0-9]*$")
34-
_LEADING_ALPHA_INVALID = re.compile("^[_a-zA-Z][_a-zA-Z0-9]*[^_a-zA-Z0-9]")
34+
_LEADING_ALPHA_INVALID = re.compile(r"^[_a-zA-Z][_a-zA-Z0-9]*[~*/\[\]]")
3535
PATH_ELEMENT_TOKENS = [
3636
("SIMPLE", r"[_a-zA-Z][_a-zA-Z0-9]*"), # unquoted elements
3737
("QUOTED", r"`(?:\\`|[^`])*?`"), # quoted elements, unquoted
@@ -311,9 +311,7 @@ def from_string(cls, path_string: str):
311311
raise ValueError("Empty element")
312312
if _LEADING_ALPHA_INVALID.match(element):
313313
raise ValueError(
314-
"Non-alphanum char in element with leading alpha: {}".format(
315-
element
316-
)
314+
"Invalid char in element with leading alpha: {}".format(element)
317315
)
318316
return FieldPath(*elements)
319317

google/cloud/firestore_v1/watch.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,9 @@ def on_snapshot(self, proto):
440440
proto(`google.cloud.firestore_v1.types.ListenResponse`):
441441
Callback method that receives a object to
442442
"""
443+
if self._closing.locked():
444+
# don't process on_snapshot responses while spinning down, to prevent deadlock
445+
return
443446
if proto is None:
444447
self.close()
445448
return

tests/system/test_system.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3151,6 +3151,28 @@ def in_transaction(transaction):
31513151
assert inner_fn_ran is True
31523152

31533153

3154+
@pytest.mark.parametrize("database", [None, FIRESTORE_OTHER_DB], indirect=True)
3155+
def test_transaction_w_uuid(client, cleanup, database):
3156+
"""
3157+
https://github.com/googleapis/python-firestore/issues/1012
3158+
"""
3159+
collection_id = "uuid_collection" + UNIQUE_RESOURCE_ID
3160+
doc_ref = client.document(collection_id, "doc")
3161+
cleanup(doc_ref.delete)
3162+
key = "b7992822-eacb-40be-8af6-559b9e2fb0b7"
3163+
doc_ref.create({key: "I'm a UUID!"})
3164+
3165+
@firestore.transactional
3166+
def update_doc(tx, doc_ref, key, value):
3167+
tx.update(doc_ref, {key: value})
3168+
3169+
expected = "UPDATED VALUE"
3170+
update_doc(client.transaction(), doc_ref, key, expected)
3171+
# read updated doc
3172+
snapshot = doc_ref.get()
3173+
assert snapshot.to_dict()[key] == expected
3174+
3175+
31543176
@pytest.mark.skipif(
31553177
FIRESTORE_EMULATOR, reason="Query profile not supported in emulator."
31563178
)
@@ -3206,6 +3228,24 @@ def in_transaction(transaction):
32063228
assert inner_fn_ran is True
32073229

32083230

3231+
@pytest.mark.parametrize("database", [None, FIRESTORE_OTHER_DB], indirect=True)
3232+
def test_update_w_uuid(client, cleanup, database):
3233+
"""
3234+
https://github.com/googleapis/python-firestore/issues/1012
3235+
"""
3236+
collection_id = "uuid_collection" + UNIQUE_RESOURCE_ID
3237+
doc_ref = client.document(collection_id, "doc")
3238+
cleanup(doc_ref.delete)
3239+
key = "b7992822-eacb-40be-8af6-559b9e2fb0b7"
3240+
doc_ref.create({key: "I'm a UUID!"})
3241+
3242+
expected = "UPDATED VALUE"
3243+
doc_ref.update({key: expected})
3244+
# read updated doc
3245+
snapshot = doc_ref.get()
3246+
assert snapshot.to_dict()[key] == expected
3247+
3248+
32093249
@pytest.mark.parametrize("with_rollback,expected", [(True, 2), (False, 3)])
32103250
@pytest.mark.parametrize("database", [None, FIRESTORE_OTHER_DB], indirect=True)
32113251
def test_transaction_rollback(client, cleanup, database, with_rollback, expected):

tests/unit/v1/test_watch.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,15 @@ def test_watch_on_snapshot_target_w_none():
400400
assert inst._rpc is None
401401

402402

403+
def test_watch_on_snapshot_while_closing():
404+
inst = _make_watch()
405+
inst.close = mock.Mock()
406+
with inst._closing:
407+
inst.on_snapshot(mock.Mock())
408+
# close should not be called again when already closing
409+
inst.close.assert_not_called()
410+
411+
403412
def test_watch_on_snapshot_target_no_change_no_target_ids_not_current():
404413
inst = _make_watch()
405414
proto = _make_listen_response()

0 commit comments

Comments
 (0)