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

Issue:
Mypy: 'No overload variant of "instantiate" matches argument type "OptimizerConf"'
I'm getting an error with mypy using hydra-zen's overloaded `instantiate` on a hand-coded dataclass:

```python
# repro.py
from dataclasses import dataclass

from hydra_zen import instantiate


@dataclass
class OptimizerConf:
    _target_: str
    _partial_: bool = True


optimizer_conf = OptimizerConf(_target_="torch.optim.SGD")
partial_optimizer = instantiate(optimizer_conf)
```

Here is the full mypy output:
```text
$ mypy --version
mypy 0.931
$ mypy repro.py
repro.py:14: error: No overload variant of "instantiate" matches argument type "OptimizerConf"
repro.py:14: note: Possible overload variants:
repro.py:14: note:     def [T] instantiate(config: Union[Just[T], Type[Just[T]]], *args: Any, **kwargs: Any) -> T
repro.py:14: note:     def [T] instantiate(config: Union[HydraPartialBuilds[Callable[..., T]], Type[HydraPartialBuilds[Callable[..., T]]]], *args: Any, **kwargs: Any) -> Partial[T]
repro.py:14: note:     def [T] instantiate(config: Union[HydraPartialBuilds[Type[T]], Type[HydraPartialBuilds[Type[T]]]], *args: Any, **kwargs: Any) -> Partial[T]
repro.py:14: note:     def [T] instantiate(config: Union[Union[ZenPartialBuilds[Callable[..., T]], HydraPartialBuilds[Callable[..., T]]], Type[ZenPartialBuilds[Callable[..., T]]], Type[HydraPartialBuilds[Callable[..., T]]]], *args: Any, **kwargs: Any) -> Partial[T]
repro.py:14: note:     def [T] instantiate(config: Union[Union[ZenPartialBuilds[Type[T]], HydraPartialBuilds[Type[T]]], Type[ZenPartialBuilds[Type[T]]], Type[HydraPartialBuilds[Type[T]]]], *args: Any, **kwargs: Any) -> Partial[T]
repro.py:14: note:     def [T] instantiate(config: Union[Builds[Callable[..., T]], Type[Builds[Callable[..., T]]]], *args: Any, **kwargs: Any) -> T
repro.py:14: note:     def [T] instantiate(config: Callable[..., Builds[Type[T]]], *args: Any, **kwargs: Any) -> T
repro.py:14: note:     def [T] instantiate(config: Union[Builds[Type[T]], Type[Builds[Type[T]]]], *args: Any, **kwargs: Any) -> T
repro.py:14: note:     def instantiate(config: Union[ListConfig, DictConfig, DataClass_, Type[DataClass_]], *args: Any, **kwargs: Any) -> Any
Found 1 error in 1 file (checked 1 source file)
```


Discussion:
Thanks for bringing my attention to this, and for the simple repro. It looks like mypy doesn't provide the same level of support for dataclasses as does pyright. In pyright, `instantiate(optimizer_conf)` reveals the type `Any`.

I'll add a simple fix for this.

Resolving patch:
diff --git a/src/hydra_zen/_hydra_overloads.py b/src/hydra_zen/_hydra_overloads.py
--- a/src/hydra_zen/_hydra_overloads.py
+++ b/src/hydra_zen/_hydra_overloads.py
@@ -26,7 +26,7 @@
 from omegaconf import MISSING, DictConfig, ListConfig, OmegaConf
 
 from .typing import Builds, Just, Partial, PartialBuilds
-from .typing._implementations import DataClass_, HydraPartialBuilds
+from .typing._implementations import DataClass_, HasTarget, HydraPartialBuilds
 
 __all__ = ["instantiate", "to_yaml", "save_as_yaml", "load_from_yaml", "MISSING"]
 
@@ -106,7 +106,7 @@ def instantiate(
 
 @overload
 def instantiate(
-    config: Union[ListConfig, DictConfig, DataClass_, Type[DataClass_]],
+    config: Union[HasTarget, ListConfig, DictConfig, DataClass_, Type[DataClass_]],
     *args: Any,
     **kwargs: Any
 ) -> Any:  # pragma: no cover


Test patch:
diff --git a/tests/annotations/declarations.py b/tests/annotations/declarations.py
--- a/tests/annotations/declarations.py
+++ b/tests/annotations/declarations.py
@@ -136,8 +136,8 @@ class SomeDataClass:
 def f6():
     some_dataclass = SomeDataClass()
 
-    out1 = instantiate(SomeDataClass)
-    out2 = instantiate(some_dataclass)
+    reveal_type(instantiate(SomeDataClass), expected_text="Any")
+    reveal_type(instantiate(some_dataclass), expected_text="Any")
 
 
 def f7():
@@ -168,6 +168,8 @@ def f8():
     class A:
         x: List[int] = mutable_value([1, 2])
 
+    reveal_type(A().x, expected_text="List[int]")
+
 
 def zen_wrappers():
     def f(obj):
@@ -718,3 +720,13 @@ def f(x: int):
     f_partial(b)  # type: ignore
     f_partial(pb)
     f_partial(bs)  # type: ignore
+
+
+def check_targeted_dataclass():
+    @dataclass
+    class OptimizerConf:
+        _target_: str
+        _partial_: bool = True
+
+    optimizer_conf = OptimizerConf(_target_="torch.optim.SGD")
+    reveal_type(instantiate(optimizer_conf), expected_text="Any")