From 0366d1d6d9ecc299eca53fa5c1f33334e217e72e Mon Sep 17 00:00:00 2001 From: Dirk Kulawiak Date: Wed, 3 Dec 2025 09:13:55 +0100 Subject: [PATCH 1/4] Fix boolean filters --- integration/test_collection_filter.py | 9 ++++++++- weaviate/collections/filters.py | 25 +++++++++++++++++++++---- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/integration/test_collection_filter.py b/integration/test_collection_filter.py index 089258da1..5d88c4936 100644 --- a/integration/test_collection_filter.py +++ b/integration/test_collection_filter.py @@ -278,13 +278,14 @@ def test_filters_comparison( ], ) def test_filters_contains( + recwarn: pytest.WarningsRecorder, collection_factory: CollectionFactory, weaviate_filter: _FilterValue, results: List[int], require_version: Optional[tuple[int, int, int]], ) -> None: collection = collection_factory( - vectorizer_config=Configure.Vectorizer.none(), + vector_config=Configure.Vectors.self_provided(), properties=[ Property(name="text", data_type=DataType.TEXT), Property(name="texts", data_type=DataType.TEXT_ARRAY), @@ -380,6 +381,12 @@ def test_filters_contains( uuids = [uuids[result] for result in results] assert all(obj.uuid in uuids for obj in objects) + # Check for warnings to make sure booleans are handled as their correct type and are not send as ints + if len(recwarn) != 0: + for rwarning in recwarn.list: + print(rwarning.message) + assert len(recwarn) == 0 + @pytest.mark.parametrize( "weaviate_filter,results", diff --git a/weaviate/collections/filters.py b/weaviate/collections/filters.py index 40b50e1f7..a658e0603 100644 --- a/weaviate/collections/filters.py +++ b/weaviate/collections/filters.py @@ -40,16 +40,28 @@ def convert(weav_filter: Optional[_Filters]) -> Optional[base_pb2.Filters]: @staticmethod def __value_filter(weav_filter: _FilterValue) -> base_pb2.Filters: + operator = weav_filter.operator._to_grpc() + target = _FilterToGRPC.__to_target(weav_filter.target) + if isinstance(weav_filter.value, bool): + # bool is a subclass of int in Python, so we need to handle it before the int check. Also for whatever reason + # the generated code from the proto files does not accept None for value_boolean, while it does for all other types. + return base_pb2.Filters( + operator=operator, + value_boolean=weav_filter.value, + target=target, + ) + return base_pb2.Filters( operator=weav_filter.operator._to_grpc(), value_text=_FilterToGRPC.__filter_to_text(weav_filter.value), - value_int=weav_filter.value if isinstance(weav_filter.value, int) else None, - value_boolean=weav_filter.value if isinstance(weav_filter.value, bool) else None, # type: ignore + value_int=weav_filter.value + if isinstance(weav_filter.value, int) and not isinstance(weav_filter.value, bool) + else None, value_number=(weav_filter.value if isinstance(weav_filter.value, float) else None), + value_boolean_array=_FilterToGRPC.__filter_to_bool_list(weav_filter.value), value_int_array=_FilterToGRPC.__filter_to_int_list(weav_filter.value), value_number_array=_FilterToGRPC.__filter_to_float_list(weav_filter.value), value_text_array=_FilterToGRPC.__filter_to_text_list(weav_filter.value), - value_boolean_array=_FilterToGRPC.__filter_to_bool_list(weav_filter.value), value_geo=_FilterToGRPC.__filter_to_geo(weav_filter.value), target=_FilterToGRPC.__to_target(weav_filter.target), ) @@ -137,7 +149,12 @@ def __filter_to_float_list(value: FilterValues) -> Optional[base_pb2.NumberArray @staticmethod def __filter_to_int_list(value: FilterValues) -> Optional[base_pb2.IntArray]: - if not isinstance(value, list) or not isinstance(value[0], int): + # bool is a subclass of int in Python, so the check must ensure it's not a bool + if ( + not isinstance(value, list) + or not isinstance(value[0], int) + or isinstance(value[0], bool) + ): return None return base_pb2.IntArray(values=cast(List[int], value)) From 4ccc269ea603ca8955bdf523ff237a1bf87ae32f Mon Sep 17 00:00:00 2001 From: Dirk Kulawiak Date: Wed, 3 Dec 2025 09:21:16 +0100 Subject: [PATCH 2/4] Update weaviate/collections/filters.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- weaviate/collections/filters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weaviate/collections/filters.py b/weaviate/collections/filters.py index a658e0603..f8dded912 100644 --- a/weaviate/collections/filters.py +++ b/weaviate/collections/filters.py @@ -52,7 +52,7 @@ def __value_filter(weav_filter: _FilterValue) -> base_pb2.Filters: ) return base_pb2.Filters( - operator=weav_filter.operator._to_grpc(), + operator=operator, value_text=_FilterToGRPC.__filter_to_text(weav_filter.value), value_int=weav_filter.value if isinstance(weav_filter.value, int) and not isinstance(weav_filter.value, bool) From b5eeae3821389912f000c0f6967910aa247288d7 Mon Sep 17 00:00:00 2001 From: Dirk Kulawiak Date: Wed, 3 Dec 2025 09:21:25 +0100 Subject: [PATCH 3/4] Update integration/test_collection_filter.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- integration/test_collection_filter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/test_collection_filter.py b/integration/test_collection_filter.py index 5d88c4936..f3916d83a 100644 --- a/integration/test_collection_filter.py +++ b/integration/test_collection_filter.py @@ -381,7 +381,7 @@ def test_filters_contains( uuids = [uuids[result] for result in results] assert all(obj.uuid in uuids for obj in objects) - # Check for warnings to make sure booleans are handled as their correct type and are not send as ints + # Check for warnings to make sure booleans are handled as their correct type and are not sent as ints if len(recwarn) != 0: for rwarning in recwarn.list: print(rwarning.message) From 2f7aa46de1d7d0a64997211eb77049ec2b841ba1 Mon Sep 17 00:00:00 2001 From: Dirk Kulawiak Date: Wed, 3 Dec 2025 09:25:08 +0100 Subject: [PATCH 4/4] Reuse computed value Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- weaviate/collections/filters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weaviate/collections/filters.py b/weaviate/collections/filters.py index f8dded912..41aebf95c 100644 --- a/weaviate/collections/filters.py +++ b/weaviate/collections/filters.py @@ -63,7 +63,7 @@ def __value_filter(weav_filter: _FilterValue) -> base_pb2.Filters: value_number_array=_FilterToGRPC.__filter_to_float_list(weav_filter.value), value_text_array=_FilterToGRPC.__filter_to_text_list(weav_filter.value), value_geo=_FilterToGRPC.__filter_to_geo(weav_filter.value), - target=_FilterToGRPC.__to_target(weav_filter.target), + target=target, ) @staticmethod