### 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
)
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
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_
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(