diff --git a/google/cloud/firestore_v1/field_path.py b/google/cloud/firestore_v1/field_path.py index c3383cbb8..048eb64d0 100644 --- a/google/cloud/firestore_v1/field_path.py +++ b/google/cloud/firestore_v1/field_path.py @@ -31,7 +31,7 @@ _ESCAPED_BACKTICK = _BACKSLASH + _BACKTICK _SIMPLE_FIELD_NAME = re.compile("^[_a-zA-Z][_a-zA-Z0-9]*$") -_LEADING_ALPHA_INVALID = re.compile("^[_a-zA-Z][_a-zA-Z0-9]*[^_a-zA-Z0-9]") +_LEADING_ALPHA_INVALID = re.compile(r"^[_a-zA-Z][_a-zA-Z0-9]*[~*/\[\]]") PATH_ELEMENT_TOKENS = [ ("SIMPLE", r"[_a-zA-Z][_a-zA-Z0-9]*"), # unquoted elements ("QUOTED", r"`(?:\\`|[^`])*?`"), # quoted elements, unquoted @@ -311,9 +311,7 @@ def from_string(cls, path_string: str): raise ValueError("Empty element") if _LEADING_ALPHA_INVALID.match(element): raise ValueError( - "Non-alphanum char in element with leading alpha: {}".format( - element - ) + "Invalid char in element with leading alpha: {}".format(element) ) return FieldPath(*elements) diff --git a/tests/system/test_system.py b/tests/system/test_system.py index b8adebb6b..d82d5113f 100644 --- a/tests/system/test_system.py +++ b/tests/system/test_system.py @@ -3151,6 +3151,28 @@ def in_transaction(transaction): assert inner_fn_ran is True +@pytest.mark.parametrize("database", [None, FIRESTORE_OTHER_DB], indirect=True) +def test_transaction_w_uuid(client, cleanup, database): + """ + https://github.com/googleapis/python-firestore/issues/1012 + """ + collection_id = "uuid_collection" + UNIQUE_RESOURCE_ID + doc_ref = client.document(collection_id, "doc") + cleanup(doc_ref.delete) + key = "b7992822-eacb-40be-8af6-559b9e2fb0b7" + doc_ref.create({key: "I'm a UUID!"}) + + @firestore.transactional + def update_doc(tx, doc_ref, key, value): + tx.update(doc_ref, {key: value}) + + expected = "UPDATED VALUE" + update_doc(client.transaction(), doc_ref, key, expected) + # read updated doc + snapshot = doc_ref.get() + assert snapshot.to_dict()[key] == expected + + @pytest.mark.skipif( FIRESTORE_EMULATOR, reason="Query profile not supported in emulator." ) @@ -3206,6 +3228,24 @@ def in_transaction(transaction): assert inner_fn_ran is True +@pytest.mark.parametrize("database", [None, FIRESTORE_OTHER_DB], indirect=True) +def test_update_w_uuid(client, cleanup, database): + """ + https://github.com/googleapis/python-firestore/issues/1012 + """ + collection_id = "uuid_collection" + UNIQUE_RESOURCE_ID + doc_ref = client.document(collection_id, "doc") + cleanup(doc_ref.delete) + key = "b7992822-eacb-40be-8af6-559b9e2fb0b7" + doc_ref.create({key: "I'm a UUID!"}) + + expected = "UPDATED VALUE" + doc_ref.update({key: expected}) + # read updated doc + snapshot = doc_ref.get() + assert snapshot.to_dict()[key] == expected + + @pytest.mark.parametrize("with_rollback,expected", [(True, 2), (False, 3)]) @pytest.mark.parametrize("database", [None, FIRESTORE_OTHER_DB], indirect=True) def test_transaction_rollback(client, cleanup, database, with_rollback, expected):