From: Kadir Can Ozden <101993364+bysiber@users.noreply.github.com> Date: Sat, 21 Feb 2026 11:35:38 +0000 (-0500) Subject: Fix WeakSequence.__getitem__ catching KeyError instead of IndexError X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0f74af5c339d7f3a6412537571aa60c0180be426;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Fix WeakSequence.__getitem__ catching KeyError instead of IndexError ### Description `WeakSequence.__getitem__` catches `KeyError` but the internal `_storage` is a `list`, which raises `IndexError` for out-of-range access. This means the `except KeyError` handler never executes, and the custom error message is never shown. ### Current behavior ```python def __getitem__(self, index): try: obj = self._storage[index] # _storage is a list except KeyError: # lists don't raise KeyError raise IndexError("Index %s out of range" % index) else: return obj() ``` On an out-of-range index, the raw `IndexError` from list access propagates directly (e.g., `list index out of range`) instead of the intended custom message. ### Fix Changed `except KeyError` to `except IndexError` so the handler actually catches the exception raised by list indexing. Closes: #13136 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/13136 Pull-request-sha: ceb8f9fe46590ec69686769f6736686789c88986 Change-Id: Ia36c2b9b0f3aec97624bcd2a9e49f43b9ed786d9 --- diff --git a/lib/sqlalchemy/util/_collections.py b/lib/sqlalchemy/util/_collections.py index e81d1a62d4..432d68e3f3 100644 --- a/lib/sqlalchemy/util/_collections.py +++ b/lib/sqlalchemy/util/_collections.py @@ -295,12 +295,7 @@ class WeakSequence(Sequence[_T]): ) def __getitem__(self, index): - try: - obj = self._storage[index] - except KeyError: - raise IndexError("Index %s out of range" % index) - else: - return obj() + return self._storage[index]() OrderedIdentitySet = IdentitySet diff --git a/test/base/test_utils.py b/test/base/test_utils.py index cd130d0c27..2a45059384 100644 --- a/test/base/test_utils.py +++ b/test/base/test_utils.py @@ -15,6 +15,7 @@ from sqlalchemy.testing import assert_raises from sqlalchemy.testing import assert_raises_message from sqlalchemy.testing import combinations from sqlalchemy.testing import eq_ +from sqlalchemy.testing import expect_raises from sqlalchemy.testing import expect_raises_message from sqlalchemy.testing import fixtures from sqlalchemy.testing import in_ @@ -73,6 +74,19 @@ class WeakSequenceTest(fixtures.TestBase): eq_(len(w), 2) eq_(len(w._storage), 2) + def test_index_error(self): + class Foo: + pass + + f1, f2, f3 = Foo(), Foo(), Foo() + + w = WeakSequence() + w.append(f1) + w.append(f2) + w.append(f3) + with expect_raises(IndexError): + w[4] + class MergeListsWOrderingTest(fixtures.TestBase): @testing.combinations(