Skip to content

fix(python-sdk): harden OQL parser for incomplete filters, negatives, and unclosed quotes - #7510

Merged
petrotiurin merged 5 commits into
comet-ml:mainfrom
baiyuxi930826:fix/oql-incomplete-negative-quotes
Jul 23, 2026
Merged

fix(python-sdk): harden OQL parser for incomplete filters, negatives, and unclosed quotes#7510
petrotiurin merged 5 commits into
comet-ml:mainfrom
baiyuxi930826:fix/oql-incomplete-negative-quotes

Conversation

@baiyuxi930826

Copy link
Copy Markdown
Contributor

Summary

Fixes three OQL parser issues reported in #7508:

  1. Incomplete filters (duration >, name =, trailing and) raised bare IndexError - now raise ValueError with a clear incomplete-filter message.
  2. Negative numbers (duration > -5) failed with trailing-characters errors - leading minus is now consumed correctly.
  3. Unterminated quoted values (name = "hello) were silently accepted - now raise missing-closing-quote ValueError (aligned with quoted keys).

Test plan

  • Direct module verification of the three cases + happy path
  • Added unit tests in test_opik_query_language.py (incomplete / negative / unclosed quote)
  • CI unit suite for sdks/python

Closes #7508

… quotes

- Raise ValueError instead of IndexError on incomplete filter strings
- Parse negative numeric literals correctly
- Reject unterminated double-quoted values
- Add unit tests covering the three cases from comet-ml#7508

Fixes comet-ml#7508
@baiyuxi930826
baiyuxi930826 requested a review from a team as a code owner July 17, 2026 13:52
@github-actions github-actions Bot added python Pull requests that update Python code tests Including test files, or tests related like configuration. Python SDK 🟢 size/S labels Jul 17, 2026
Comment on lines 671 to 672
):
self._cursor += 1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate quote scanner in parser

The new quoted-value path duplicates the cursor-walk and closing-quote checks already in _check_escaped_key() + _is_valid_escaped_key_char(), so quote-handling fixes now have to stay in sync in two places and it's easy to drift on boundary checks or error wording — should we factor a shared quoted-token helper and reuse it here?

Severity

Want Baz to fix this for you? Activate Fixer

@baiyuxi930826

Copy link
Copy Markdown
Contributor Author

Addressed the review note: quoted values now go through a shared _parse_quoted_string helper that reuses _is_valid_escaped_key_char (same doubled-quote escape rules as field keys). Also tightened the missing-close check so end-of-string quoted values work (cursor+1 instead of cursor+2).

Comment on lines 630 to +635
if parsed_field not in supported_operators:
parsed_field = "default"

if self._cursor >= len(self.query_string):
raise ValueError("Incomplete filter string: unexpected end of input")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incomplete filter end-of-input error

_parse_operator now raises ValueError("Incomplete filter string: unexpected end of input") at end-of-input, but sdks/python/tests/unit/api_objects/test_opik_query_language.py only covers for_traces(), so the sibling public APIs that share this parser still lack malformed-input coverage — should we add matching cases there?

Severity

Want Baz to fix this for you? Activate Fixer You can also update your AI coding guidelines based on this comment by apply pr to [branch name]

Other fix methods

Fix in Cursor

Prompt for AI Agents
Before applying, verify this suggestion against the current code. In
`sdks/python/src/opik/api_objects/opik_query_language.py` around lines 624-635,
`_parse_operator` raises `ValueError("Incomplete filter string: unexpected end of
input")` when `self._cursor >= len(self.query_string)`. Update
`sdks/python/tests/unit/api_objects/test_opik_query_language.py` so that malformed-input
coverage for the sibling public factory APIs (e.g., `for_spans`, `for_threads`,
`for_dataset_items`, `for_prompt_versions`), not just `for_traces`, asserts the same
exception and message for a query that ends after a valid field (no operator). Refactor
the test into a parametrized/looped structure over the constructors to avoid duplicating
cases and to keep the coverage aligned across all configs.

Extend malformed-input coverage beyond for_traces so for_spans,
for_threads, for_dataset_items, and for_prompt_versions also assert
Incomplete filter string and missing-close quote errors (Baz review).
Also align the for_traces unterminated-value expectation with the
shared quote-scanner message.
@baiyuxi930826

Copy link
Copy Markdown
Contributor Author

Addressed the latest Baz review note:

  • Added parametrized tests that run incomplete-filter and unterminated-quote cases through all public factories (for_traces / for_spans / for_threads / for_dataset_items / for_prompt_versions), not only for_traces.
  • Aligned the existing for_traces unterminated-value expectation with the shared quote-scanner message (Missing closing quote for: ...).

Happy to take any further maintainer feedback.

…ase tests

_parse_field's quoted-key loop let an alnum char at end-of-string satisfy the
field-char branch before ever checking quote closure, so an unterminated key
ending in an alnum char silently overflowed the cursor instead of raising
"Missing closing quote". Also fixes ruff-format failure and adds test
coverage for escaped quotes in values, decimal/negative-sign edge cases, and
whitespace-only queries.

@petrotiurin petrotiurin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, thanks for enhancing the parser! I've added some additional tests to ensure the edge-case coverage.

@petrotiurin
petrotiurin merged commit 50df4db into comet-ml:main Jul 23, 2026
47 of 50 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Python SDK python Pull requests that update Python code 🟡 size/M tests Including test files, or tests related like configuration.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug][Python SDK]: OQL parser mishandles incomplete filters, negative numbers, and unclosed quotes

4 participants