Skip to content

Commit c24dfe2

Browse files
authored
Merge pull request #1902 from weaviate/fix_bool_filters
Fix boolean filters
2 parents fd52f50 + 2f7aa46 commit c24dfe2

File tree

2 files changed

+31
-7
lines changed

2 files changed

+31
-7
lines changed

integration/test_collection_filter.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,13 +278,14 @@ def test_filters_comparison(
278278
],
279279
)
280280
def test_filters_contains(
281+
recwarn: pytest.WarningsRecorder,
281282
collection_factory: CollectionFactory,
282283
weaviate_filter: _FilterValue,
283284
results: List[int],
284285
require_version: Optional[tuple[int, int, int]],
285286
) -> None:
286287
collection = collection_factory(
287-
vectorizer_config=Configure.Vectorizer.none(),
288+
vector_config=Configure.Vectors.self_provided(),
288289
properties=[
289290
Property(name="text", data_type=DataType.TEXT),
290291
Property(name="texts", data_type=DataType.TEXT_ARRAY),
@@ -380,6 +381,12 @@ def test_filters_contains(
380381
uuids = [uuids[result] for result in results]
381382
assert all(obj.uuid in uuids for obj in objects)
382383

384+
# Check for warnings to make sure booleans are handled as their correct type and are not sent as ints
385+
if len(recwarn) != 0:
386+
for rwarning in recwarn.list:
387+
print(rwarning.message)
388+
assert len(recwarn) == 0
389+
383390

384391
@pytest.mark.parametrize(
385392
"weaviate_filter,results",

weaviate/collections/filters.py

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,30 @@ def convert(weav_filter: Optional[_Filters]) -> Optional[base_pb2.Filters]:
4040

4141
@staticmethod
4242
def __value_filter(weav_filter: _FilterValue) -> base_pb2.Filters:
43+
operator = weav_filter.operator._to_grpc()
44+
target = _FilterToGRPC.__to_target(weav_filter.target)
45+
if isinstance(weav_filter.value, bool):
46+
# bool is a subclass of int in Python, so we need to handle it before the int check. Also for whatever reason
47+
# the generated code from the proto files does not accept None for value_boolean, while it does for all other types.
48+
return base_pb2.Filters(
49+
operator=operator,
50+
value_boolean=weav_filter.value,
51+
target=target,
52+
)
53+
4354
return base_pb2.Filters(
44-
operator=weav_filter.operator._to_grpc(),
55+
operator=operator,
4556
value_text=_FilterToGRPC.__filter_to_text(weav_filter.value),
46-
value_int=weav_filter.value if isinstance(weav_filter.value, int) else None,
47-
value_boolean=weav_filter.value if isinstance(weav_filter.value, bool) else None, # type: ignore
57+
value_int=weav_filter.value
58+
if isinstance(weav_filter.value, int) and not isinstance(weav_filter.value, bool)
59+
else None,
4860
value_number=(weav_filter.value if isinstance(weav_filter.value, float) else None),
61+
value_boolean_array=_FilterToGRPC.__filter_to_bool_list(weav_filter.value),
4962
value_int_array=_FilterToGRPC.__filter_to_int_list(weav_filter.value),
5063
value_number_array=_FilterToGRPC.__filter_to_float_list(weav_filter.value),
5164
value_text_array=_FilterToGRPC.__filter_to_text_list(weav_filter.value),
52-
value_boolean_array=_FilterToGRPC.__filter_to_bool_list(weav_filter.value),
5365
value_geo=_FilterToGRPC.__filter_to_geo(weav_filter.value),
54-
target=_FilterToGRPC.__to_target(weav_filter.target),
66+
target=target,
5567
)
5668

5769
@staticmethod
@@ -137,7 +149,12 @@ def __filter_to_float_list(value: FilterValues) -> Optional[base_pb2.NumberArray
137149

138150
@staticmethod
139151
def __filter_to_int_list(value: FilterValues) -> Optional[base_pb2.IntArray]:
140-
if not isinstance(value, list) or not isinstance(value[0], int):
152+
# bool is a subclass of int in Python, so the check must ensure it's not a bool
153+
if (
154+
not isinstance(value, list)
155+
or not isinstance(value[0], int)
156+
or isinstance(value[0], bool)
157+
):
141158
return None
142159

143160
return base_pb2.IntArray(values=cast(List[int], value))

0 commit comments

Comments
 (0)