Repository: mit-ll-responsible-ai/hydra-zen

Issue:
Inconsistent static analysis via pyright
```python
x = [1, 2, 3]
make_config(a=[1, 2, 3])
make_config(a=x)  # pyright marks this as invalid based on our annotations
```

This seems like a pyright issue, but we might consider revising annotations to accommodate


Discussion:

Resolving patch:
diff --git a/src/hydra_zen/typing/_implementations.py b/src/hydra_zen/typing/_implementations.py
--- a/src/hydra_zen/typing/_implementations.py
+++ b/src/hydra_zen/typing/_implementations.py
@@ -7,21 +7,19 @@
 from typing import (
     Any,
     Callable,
-    Counter,
-    Deque,
     Dict,
     FrozenSet,
     Generic,
-    List,
+    Mapping,
     NewType,
-    Set,
+    Sequence,
     Tuple,
     TypeVar,
     Union,
 )
 
 from omegaconf import DictConfig, ListConfig
-from typing_extensions import Protocol, runtime_checkable
+from typing_extensions import Protocol, TypedDict, runtime_checkable
 
 __all__ = [
     "Just",
@@ -33,6 +31,10 @@
 ]
 
 
+class EmptyDict(TypedDict):
+    pass
+
+
 _T = TypeVar("_T", covariant=True)
 
 
@@ -119,15 +121,21 @@ class HasPartialTarget(Protocol):  # pragma: no cover
     complex,
     Path,
     range,
+    set,
+    EmptyDict,  # not covered by Mapping[..., ...]
 ]
 
 SupportedPrimitive = Union[
     _SupportedPrimitive,
-    Dict[_HydraPrimitive, "SupportedPrimitive"],
-    Counter[_HydraPrimitive],
-    Set["SupportedPrimitive"],
     FrozenSet["SupportedPrimitive"],
-    Deque["SupportedPrimitive"],
-    List["SupportedPrimitive"],
-    Tuple["SupportedPrimitive", ...],
+    # Even thought this is redundant with Sequence, it seems to
+    # be needed for pyright to do proper checking of tuple contents
+    Tuple["SupportedPrimitive"],
+    # Mutable generic containers need to be invariant, so
+    # we have to settle for Sequence/Mapping. While this
+    # is overly permissive in terms of sequence-type, it
+    # at least affords quality checking of sequence content
+    Sequence["SupportedPrimitive"],
+    # Mapping is covariant only in value
+    Mapping[Any, "SupportedPrimitive"],
 ]


Test patch:
diff --git a/tests/annotations/declarations.py b/tests/annotations/declarations.py
--- a/tests/annotations/declarations.py
+++ b/tests/annotations/declarations.py
@@ -37,8 +37,6 @@ def requires_A(x: int):
 
 # test type behaviors
 def f1():
-    # test builds(..., zen_partial=True)
-    # there is something really weird where annotating : PartialBuilds[Type[A]] breaks this..
     a: Literal["Type[PartialBuilds[Type[A]]]"] = reveal_type(
         builds(A, zen_partial=True)
     )
@@ -181,6 +179,10 @@ def f(obj):
         builds(str, zen_partial=True, zen_wrappers=(f, J, B, PB, None))
     )
 
+    # should fail
+    # builds(str, zen_wrappers=(2.0, 1))
+    # builds(str, zen_wrappers=False)
+
 
 def custom_builds_fn():
     _builds = make_custom_builds_fn()
@@ -299,10 +301,40 @@ class AnEnum(Enum):
         olist,
     )
 
+    a_list = [1, 2, [1, 2]]
+    a_dict = {"a": [1, 2, [1, 2]]}
+    a_set = {1, 2.0, (1, 2)}
+
+    # make sure we don't hit this issue again
+    # https://github.com/microsoft/pyright/issues/2659
+    a8 = make_config(x=a_list, y=a_dict, z=a_set)
+
     # The following should be marked as "bad by type-checkers
     # make_config(a=M())
+    # make_config(a={"a": M()})
+    # make_config(a=(1, M()))
+    # make_config(a=[1, M()])
     # builds(dict, a=M())
+
+    # The following *should* be invalid, but we are limited
+    # by mutable invariants being generic
     # make_config(a={1j: 1})
     # make_config(a={M: 1})
     # make_config(a={ADataclass: 1})
-    # make_config(a={ADataclass(): 1})
+
+
+def check_inheritance():
+    P1 = make_config(x=1)
+    P2 = builds(dict)
+
+    @dataclass
+    class P3:
+        pass
+
+    C: Literal["Type[DataClass]"] = reveal_type(make_config(x=1, bases=(P1, P2, P3)))
+    D: Literal["Type[Builds[Type[int]]]"] = reveal_type(builds(int, bases=(P1, P2, P3)))
+
+    # should fail
+    # make_config(x=1, bases=(lambda x: x,))
+    # make_config(x=1, bases=(None,))
+    # make_config(x=1, bases=(A,))