Repository: amaranth-lang/amaranth (python)

Issue:
Views with an array layout should have `len()` applicable to them
Currently this isn't possible:

```python
width = 8
sig = Signal(data.ArrayLayout(1, width))
len(sig) # => TypeError: object of type 'View' has no len()
```

Pull request description:
lib.data: make `len()` work on views of array layout.
Fixes #1403.

Patch:
diff --git a/amaranth/lib/data.py b/amaranth/lib/data.py
index 6135bb0..8c77cc2 100644
--- a/amaranth/lib/data.py
+++ b/amaranth/lib/data.py
@@ -850,6 +850,12 @@ class View(ValueCastable):
                 f"may only be accessed by indexing")
         return item
 
+    def __len__(self):
+        if not isinstance(self.__layout, ArrayLayout):
+            raise TypeError(
+                f"`len()` can only be used on views of array layout, not {self.__layout!r}")
+        return self.__layout.length
+
     def __eq__(self, other):
         if isinstance(other, View) and self.__layout == other.__layout:
             return self.__target == other.__target


Test patch:
diff --git a/tests/test_lib_data.py b/tests/test_lib_data.py
index 697f366..ceafd63 100644
--- a/tests/test_lib_data.py
+++ b/tests/test_lib_data.py
@@ -763,6 +763,14 @@ class ViewTestCase(FHDLTestCase):
                 r"with the same layout, not .*$"):
             s1 != Const(0, 2)
 
+    def test_len(self):
+        s1 = Signal(data.StructLayout({"a": unsigned(2)}))
+        with self.assertRaisesRegex(TypeError,
+                r"^`len\(\)` can only be used on views of array layout, not StructLayout.*$"):
+            len(s1)
+        s2 = Signal(data.ArrayLayout(2, 3))
+        self.assertEqual(len(s2), 3)
+
     def test_operator(self):
         s1 = Signal(data.StructLayout({"a": unsigned(2)}))
         s2 = Signal(unsigned(2))