Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion integration/test_collection_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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 sent as ints
if len(recwarn) != 0:
for rwarning in recwarn.list:
print(rwarning.message)
assert len(recwarn) == 0


@pytest.mark.parametrize(
"weaviate_filter,results",
Expand Down
29 changes: 23 additions & 6 deletions weaviate/collections/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,30 @@ 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(),
operator=operator,
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),
target=target,
)

@staticmethod
Expand Down Expand Up @@ -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))
Expand Down