temporalio/sdk-python
TypedSearchAttributes.__contains__ returns False for existing keys with falsy values
Summary
Context: The
TypedSearchAttributesclass intemporalio/common.pyimplements a collection-like interface for managing workflow search attributes with type-safe key-value pairs.Bug: The
__contains__method incorrectly returnsFalsewhen checking for keys that have falsy values (0, False, 0.0).Actual vs. expected: The method evaluates the truthiness of the value instead of checking for key existence, violating Python’s
inoperator semantics which should returnTruewhenever a key exists regardless of its value.Impact: In
temporalio/client.py, this causes attributes with falsy values to be incorrectly duplicated in both typed and untyped search attribute collections, leading to potential data corruption and query failures.
Code with bug
The expression any(v for k, v in self if k == key) yields the value v for matching keys, then evaluates any() on those values. When a matching key has a falsy value, any() returns False despite the key existing.
Test demonstration
A simple test demonstrates the bug across all falsy value types:
Test results:
The bug manifests consistently: when a key exists with a falsy value, the buggy implementation returns False while the correct implementation returns True.
Recommended fix
Change the implementation to check for key existence rather than value truthiness:
This ensures the method returns True whenever a matching key is found, regardless of the associated value.
The bug affects production code in temporalio/client.py where the following logic depends on correct __contains__ behavior:
After the fix, this code will correctly exclude attributes that exist in typed search attributes, even when they have falsy values.