From 01f2d83ddeb16567eb7e8187d36c1ab02ad74ebc Mon Sep 17 00:00:00 2001 From: Sam Dolan Date: Tue, 10 Feb 2026 12:52:03 -0800 Subject: [PATCH] Improve QuerySet integer indexing error guidance --- tests/test_queryset.py | 14 ++++++++++++++ tortoise/queryset.py | 7 +++++++ 2 files changed, 21 insertions(+) diff --git a/tests/test_queryset.py b/tests/test_queryset.py index 513979035..1f564ee4c 100644 --- a/tests/test_queryset.py +++ b/tests/test_queryset.py @@ -129,6 +129,20 @@ def test_slicing_negative_values(db): _ = IntFields.all()[:-1] +def test_integer_indexing_not_supported(db): + with pytest.raises( + ParamsError, + match=( + r"QuerySet indices must be slices, not integers\. " + r"QuerySets are lazy and do not support random access\. " + r"Use await queryset\.first\(\), await queryset\.offset\(n\)\.first\(\), " + r"or await queryset\.all\(\) and index the returned list\." + ), + ): + # Use an index way outside reasonable bounds for the dataset, so we don't accidentally support it. + _ = IntFields.all()[1000] + + def test_slicing_stop_before_start(db): with pytest.raises( ParamsError, diff --git a/tortoise/queryset.py b/tortoise/queryset.py index 0cfd2fc52..5da6ef9f7 100644 --- a/tortoise/queryset.py +++ b/tortoise/queryset.py @@ -554,6 +554,13 @@ def __getitem__(self, key: slice) -> QuerySet[MODEL]: or None. """ if not isinstance(key, slice): + if isinstance(key, int): + raise ParamsError( + "QuerySet indices must be slices, not integers. " + "QuerySets are lazy and do not support random access. " + "Use await queryset.first(), await queryset.offset(n).first(), " + "or await queryset.all() and index the returned list." + ) raise ParamsError("QuerySet indices must be slices.") if not (key.step is None or (isinstance(key.step, int) and key.step == 1)):