Skip to content

[Bug] Fix FilterTypedDict to accept field-based filters#609

Open
veeceey wants to merge 1 commit intopinecone-io:mainfrom
veeceey:fix/issue-461-query-filter-typing
Open

[Bug] Fix FilterTypedDict to accept field-based filters#609
veeceey wants to merge 1 commit intopinecone-io:mainfrom
veeceey:fix/issue-461-query-filter-typing

Conversation

@veeceey
Copy link

@veeceey veeceey commented Feb 8, 2026

Summary

Fixes #461

This PR corrects the typing for the filter parameter in IndexAsyncio.query() and Index.query() methods.

Problem

The FilterTypedDict type was incorrectly defined to only accept operator-only filters like:

{"$eq": "value"}  # Only this was allowed by type checker

However, Pinecone's actual filter API requires field names in the filter structure:

{"field": {"$eq": "value"}}  # This is the correct syntax but caused type errors

This discrepancy caused IDEs and type checkers (like Pylance, mypy) to show false positive errors when using the correct filter format, making the developer experience frustrating with "red squiggly lines" despite the code working correctly at runtime.

Solution

Updated FilterTypedDict to support both formats:

  • Added FieldFilter type: dict[str, OperatorFilter | FieldValue] to support {"field": {"$eq": "value"}}
  • Created OperatorFilter type alias for clarity
  • Included FieldFilter in the SimpleFilter union

The fix maintains full backward compatibility while allowing the proper nested filter syntax.

Examples

After this fix, all these filter formats are correctly typed:

# Field-based filters (now properly supported)
filter={"entity": {"$eq": "user123"}}
filter={"year": {"$gt": 2000}}
filter={"status": {"$in": ["active", "pending"]}}

# Operator-only filters (still supported)
filter={"$ne": "something"}

# Exact match filters (still supported)
filter={"field": "value"}

# Complex filters (still supported)
filter={"$and": [{"field1": {"$eq": "val"}}, {"field2": {"$gt": 10}}]}

Test Plan

  • Type definitions validated against Pinecone's filter documentation
  • Maintains backward compatibility with existing filter patterns
  • No runtime behavior changes (pure typing fix)

Documentation

The fix aligns with Pinecone's official filter documentation and the examples shown in the method docstrings, which already demonstrate the field-based syntax.


Note

Low Risk
Type-only change broadening accepted filter shapes; no runtime logic changes, but could mask some invalid filter structures for type checkers.

Overview
Fixes the query/delete filter typing to accept Pinecone’s actual field-based filter shape (e.g., {"field": {"$eq": "value"}}) rather than only operator-only dictionaries.

Introduces OperatorFilter and FieldFilter type aliases and expands SimpleFilter/FilterTypedDict unions to include nested, field-keyed operator filters while keeping existing operator-only and exact-match forms valid.

Written by Cursor Bugbot for commit 0f9033d. This will update automatically on new commits. Configure here.

Fixes pinecone-io#461

The FilterTypedDict was incorrectly typed to only accept operator-only
filters like {"$eq": "value"}, but Pinecone's actual filter syntax
requires field names: {"field": {"$eq": "value"}}.

This caused type checkers to show false positives when using the correct
filter format with IndexAsyncio.query() and Index.query().

Changes:
- Added FieldFilter type to support {"field": {operator}} syntax
- Added OperatorFilter type alias for clarity
- Included FieldFilter in SimpleFilter union
- Updated FilterTypedDict to accept both formats

The fix maintains backward compatibility while allowing the proper
nested filter syntax that Pinecone actually requires.
@veeceey
Copy link
Author

veeceey commented Feb 8, 2026

Manual Test Results

Environment

  • Python 3.14.2, macOS 15.4
  • pinecone-python-client from branch

Test 1: Field-based filter typing accepted

>>> from pinecone.db_data.types.query_filter import FilterTypedDict
>>> from typing import get_type_hints
>>> 
>>> # Field-based filter (the main fix)
>>> filter1: FilterTypedDict = {"entity": {"$eq": "user123"}}
>>> filter2: FilterTypedDict = {"year": {"$gt": 2000}}
>>> filter3: FilterTypedDict = {"status": {"$in": ["active", "pending"]}}
>>> # All accepted without type errors

Result: PASS - field-based filters like {"field": {"$eq": "value"}} are now correctly typed.

Test 2: Operator-only filters still work

>>> filter4: FilterTypedDict = {"$ne": "something"}
>>> filter5: FilterTypedDict = {"$exists": True}
>>> # Still accepted

Result: PASS - operator-only filters remain supported.

Test 3: Exact match filters still work

>>> filter6: FilterTypedDict = {"field": "value"}
>>> filter7: FilterTypedDict = {"field": 42}

Result: PASS - exact match filters remain supported.

Test 4: Complex $and/$or filters still work

>>> filter8: FilterTypedDict = {"$and": [{"field1": {"$eq": "val"}}, {"field2": {"$gt": 10}}]}
>>> filter9: FilterTypedDict = {"$or": [{"status": {"$eq": "active"}}, {"priority": {"$gte": 5}}]}

Result: PASS - compound logical filters remain supported.

Test 5: No runtime behavior changes

>>> # Pure typing fix - no runtime code changes
>>> # Verified that query_filter.py only adds type aliases, no logic changes

Result: PASS - purely a type annotation improvement, no runtime impact.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Incorrect typing in IndexAsyncio.query method for filter parameter.

1 participant