Repository: numba/numba

Issue:
`ListType` needs to implement `key`
- [x] I have tried using the latest released version of Numba (most recent is
 visible in the change log (https://github.com/numba/numba/blob/master/CHANGE_LOG).
- [x] I have included below a minimal working reproducer (if you are unsure how
 to write one see http://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports).

Currently `ListType` cannot cope with parametrized types that do not have unique names because `ListType.key` is not implemented. The example below fails with `TypingError` when it tries to reuse the implementation of `l1.append` for `l2.append`:
```python
from numba import jit, types
from numba.core.datamodel.models import IntegerModel
from numba.extending import register_model
from numba.typed import List

class MyParametrizedType(types.Type):
    def __init__(self, n):
        super(MyParametrizedType, self).__init__('MyParametrizedType')  # <- type name does not contain n
        self.n = n
        self.bitwidth = 64

    @property
    def key(self):
        return self.n

register_model(MyParametrizedType)(IntegerModel)

xty, yty = MyParametrizedType(1), MyParametrizedType(2)

@jit(types.void(xty, yty), nopython=True, no_cpython_wrapper=True)  # <- fails with TypingError
def get_unit_system_data(x, y):
    l1 = List.empty_list(xty)
    l2 = List.empty_list(yty)

    l1.append(x)
    l2.append(y)
```
This likely affects the corresponding iterable and iterator types as well. `ListType.key` should probably look like:
```python
@property
def key(self):
    return self.item_type
```




Discussion:
Many thanks for the report, and suggested fix!

I can reproduce the issue using the above code, and that adding the `key` property above to `ListType` does allow the example to compile. 

(I have not looked into whether this is the correct fix)

Resolving patch:
diff --git a/numba/core/types/containers.py b/numba/core/types/containers.py
--- a/numba/core/types/containers.py
+++ b/numba/core/types/containers.py
@@ -627,6 +627,10 @@ def __init__(self, itemty):
         name = "{}[{}]".format(self.__class__.__name__, itemty,)
         super(ListType, self).__init__(name)
 
+    @property
+    def key(self):
+        return self.item_type
+
     def is_precise(self):
         return not isinstance(self.item_type, Undefined)
 


Test patch:
diff --git a/numba/tests/test_types.py b/numba/tests/test_types.py
--- a/numba/tests/test_types.py
+++ b/numba/tests/test_types.py
@@ -874,6 +874,27 @@ def key(self):
                 self.assertIs(
                     types.TypeRef(ty1) == types.TypeRef(ty2), ty1 == ty2)
 
+    def test_issue_list_type_key(self):
+        # https://github.com/numba/numba/issues/6397
+        class NoUniqueNameType(types.Dummy):
+            def __init__(self, param):
+                super(NoUniqueNameType, self).__init__('NoUniqueNameType')
+                self.param = param
+
+            @property
+            def key(self):
+                return self.param
+
+        no_unique_name_type_1 = NoUniqueNameType(1)
+        no_unique_name_type_2 = NoUniqueNameType(2)
+
+        for ty1 in (no_unique_name_type_1, no_unique_name_type_2):
+            for ty2 in (no_unique_name_type_1, no_unique_name_type_2):
+                self.assertIs(
+                    types.ListType(ty1) == types.ListType(ty2),  # noqa: E721
+                    ty1 == ty2
+                )
+
 
 if __name__ == '__main__':
     unittest.main()