Repository: ethereum/web3.py

Issue:
Looping through middleware values causes KeyError
### What happened?

When I do:

```
[x for x in web3.middleware_onion.values()]
```

I get:

```
KeyError: "<class 'web3.middleware.gas_price_strategy.GasPriceStrategyMiddleware'><7318129395746595366>"
```

I would assume it was just tell me all the middlewares but I am kinda guessing. Either way, I don't think it should fail with a KeyError.

### Code that produced the error

```python
[x for x in web3.middleware_onion.values()]
```

### Full error output

```shell
*** KeyError: "<class 'web3.middleware.gas_price_strategy.GasPriceStrategyMiddleware'><7318129395746595366>"
```

### Fill this section in if you know how this could or should be fixed

Override `.values()` and make it do something useful

### web3 Version

7.7.0

### Python Version

3.13.1

### Operating System

macOS

### Output from `pip freeze`

```shell
it is long and incredibly embarrassing.
```

Discussion:

Patch:
diff --git a/newsfragments/3596.bugfix.rst b/newsfragments/3596.bugfix.rst
new file mode 100644
index 00000000..ffefffae
--- /dev/null
+++ b/newsfragments/3596.bugfix.rst
@@ -0,0 +1,1 @@
+Fix issue where ``.values()`` raised a ``KeyError`` in ``NamedTupledOnion``
diff --git a/web3/datastructures.py b/web3/datastructures.py
index 2a70f131..5c0c3ad6 100644
--- a/web3/datastructures.py
+++ b/web3/datastructures.py
@@ -17,6 +17,7 @@ from typing import (
     Tuple,
     TypeVar,
     Union,
+    ValuesView,
     cast,
 )
 
@@ -337,3 +338,6 @@ class NamedElementOnion(Mapping[TKey, TValue]):
         # This leads to typing issues, so it's better to use
         # ``as_tuple_of_middleware()`` to achieve the same result.
         return iter(self._reversed_middleware())  # type: ignore
+
+    def values(self) -> ValuesView[TValue]:
+        return ValuesView(self._queue)


Test patch:
diff --git a/tests/core/datastructures/test_datastructures.py b/tests/core/datastructures/test_datastructures.py
index 2be0af60..d72ea466 100644
--- a/tests/core/datastructures/test_datastructures.py
+++ b/tests/core/datastructures/test_datastructures.py
@@ -4,8 +4,12 @@ import re
 
 from web3.datastructures import (
     AttributeDict,
+    NamedElementOnion,
     tupleize_lists_nested,
 )
+from web3.middleware import (
+    GasPriceStrategyMiddleware,
+)
 
 
 def generate_random_value(depth=0, max_depth=3, key_type=None):
@@ -207,3 +211,11 @@ def test_AttributeDict_hashing_backwards_compatibility(input, error):
             assert hash(tuple(sorted(input.items()))) == hash(input)
     else:
         assert hash(tuple(sorted(input.items()))) == hash(input)
+
+
+def test_NamedElementOnion_values():
+    middleware = GasPriceStrategyMiddleware(None)
+    initial_items = [(middleware, "gas_price_strategy")]
+    named_element_onion = NamedElementOnion(initial_items)
+    actual = [x for x in named_element_onion.values()]
+    assert actual == [middleware]