]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Fix WeakSequence.__getitem__ catching KeyError instead of IndexError
authorKadir Can Ozden <101993364+bysiber@users.noreply.github.com>
Sat, 21 Feb 2026 11:35:38 +0000 (06:35 -0500)
committerFederico Caselli <cfederico87@gmail.com>
Mon, 23 Feb 2026 21:12:46 +0000 (22:12 +0100)
### 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

lib/sqlalchemy/util/_collections.py
test/base/test_utils.py

index e81d1a62d4cb8f9970df7a0385796bc156cf9554..432d68e3f31a844fcbd4a58e9bdb11a1e9451655 100644 (file)
@@ -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
index cd130d0c27896bf57c17c54045b1a8fd71c88aad..2a45059384cf54a88715cfa29fa197a1168c87b3 100644 (file)
@@ -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(