Skip to content

Commit 69dfe9c

Browse files
Gobot1234nat-n
andauthored
Implement Message.__bool__ (#142)
* Implement Message.__bool__ with similar semantics to a collection, such that any value being set on the message (i.e. having a non-default value) make the Message value truthy . Co-authored-by: nat <[email protected]>
1 parent a8a082e commit 69dfe9c

File tree

3 files changed

+43
-1
lines changed

3 files changed

+43
-1
lines changed

docs/api.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Message
1212

1313
.. autoclass:: betterproto.Message
1414
:members:
15-
:special-members: __bytes__
15+
:special-members: __bytes__, __bool__
1616

1717

1818
.. autofunction:: betterproto.serialized_on_wire

src/betterproto/__init__.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,10 @@ class Message(ABC):
516516
.. describe:: bytes(x)
517517
518518
Calls :meth:`__bytes__`.
519+
520+
.. describe:: bool(x)
521+
522+
Calls :meth:`__bool__`.
519523
"""
520524

521525
_serialized_on_wire: bool
@@ -606,6 +610,14 @@ def __setattr__(self, attr: str, value: Any) -> None:
606610

607611
super().__setattr__(attr, value)
608612

613+
def __bool__(self) -> bool:
614+
"""True if the Message has any fields with non-default values."""
615+
return any(
616+
self.__raw_get(field_name)
617+
not in (PLACEHOLDER, self._get_field_default(field_name))
618+
for field_name in self._betterproto.meta_by_field_name
619+
)
620+
609621
@property
610622
def _betterproto(self) -> ProtoClassMetadata:
611623
"""

tests/test_features.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,3 +365,33 @@ def test_message_repr():
365365

366366
assert repr(Test(name="Loki")) == "Test(name='Loki')"
367367
assert repr(Test(child=Test(), name="Loki")) == "Test(name='Loki', child=Test())"
368+
369+
370+
def test_bool():
371+
"""Messages should evaluate similarly to a collection
372+
>>> test = []
373+
>>> bool(test)
374+
... False
375+
>>> test.append(1)
376+
>>> bool(test)
377+
... True
378+
>>> del test[0]
379+
>>> bool(test)
380+
... False
381+
"""
382+
383+
@dataclass
384+
class Falsy(betterproto.Message):
385+
pass
386+
387+
@dataclass
388+
class Truthy(betterproto.Message):
389+
bar: int = betterproto.int32_field(1)
390+
391+
assert not Falsy()
392+
t = Truthy()
393+
assert not t
394+
t.bar = 1
395+
assert t
396+
t.bar = 0
397+
assert not t

0 commit comments

Comments
 (0)