Skip to content

Commit 4b24553

Browse files
committed
test(proto-plus): add regression tests and guard descriptor check in marshal
1 parent 8396d8b commit 4b24553

2 files changed

Lines changed: 35 additions & 1 deletion

File tree

packages/proto-plus/proto/marshal/marshal.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,8 @@ def to_proto(self, proto_type, value, *, strict: bool = False):
224224
# annotation. We need to do the conversion based on the `value`
225225
# field's type.
226226
if isinstance(value, dict) and (
227-
proto_type.DESCRIPTOR.has_options
227+
hasattr(proto_type, "DESCRIPTOR")
228+
and proto_type.DESCRIPTOR.has_options
228229
and proto_type.DESCRIPTOR.GetOptions().map_entry
229230
):
230231
recursive_type = type(proto_type().value)

packages/proto-plus/tests/test_message.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,3 +500,36 @@ class Arm(proto.Message):
500500

501501
def test_dir_message_base():
502502
assert set(dir(proto.Message)) == set(dir(type))
503+
504+
505+
def test_invalid_initialization_type_error():
506+
"""Verify that bad types passed to __init__ raise a descriptive TypeError."""
507+
class UserProfile(proto.Message):
508+
username = proto.Field(proto.STRING, number=1)
509+
age = proto.Field(proto.INT32, number=2)
510+
511+
with pytest.raises(TypeError) as excinfo:
512+
# Passing a list where a string is expected
513+
UserProfile(username=["not", "a", "string"])
514+
515+
error_msg = str(excinfo.value)
516+
assert "Failed to initialize UserProfile" in error_msg
517+
assert "Underlying error" in error_msg
518+
assert isinstance(excinfo.value.__cause__, TypeError)
519+
520+
521+
def test_invalid_assignment_type_error():
522+
"""Verify that bad types assigned via __setattr__ raise a descriptive TypeError."""
523+
class UserProfile(proto.Message):
524+
username = proto.Field(proto.STRING, number=1)
525+
age = proto.Field(proto.INT32, number=2)
526+
profile = UserProfile()
527+
528+
with pytest.raises(TypeError) as excinfo:
529+
# Assigning a dictionary where an integer is expected
530+
profile.age = {"invalid": "type"}
531+
532+
error_msg = str(excinfo.value)
533+
assert "Failed to set field 'age' on UserProfile" in error_msg
534+
assert "{'invalid': 'type'}" in error_msg
535+
assert isinstance(excinfo.value.__cause__, TypeError)

0 commit comments

Comments
 (0)