Repository: pydantic/pydantic

Issue:
Inherited dataclasses don't resolve forward refs
# Bug

```
pydantic version: 1.5.1
python version: 3.8.2
```

a.py:
```py
from __future__ import annotations
from uuid import UUID
from pydantic.dataclasses import dataclass

@dataclass
class A:
    uuid: UUID

    # workaround
    # def __post_init__(self):
    #     self.__pydantic_model__.update_forward_refs(**globals())
```

b.py:
```py
from __future__ import annotations
from uuid import uuid4
from pydantic.dataclasses import dataclass
from a import A

@dataclass
class B(A):
    pass

B(uuid=uuid4())
```

`B(uuid=uuid4())` throws `field "uuid" not yet prepared so type is still a ForwardRef, you might need to call B.update_forward_refs()`.


Discussion:
Hello @laevilgenius
I can't reproduce with your example. See https://repl.it/@EricJ1/pydantic-issue-1668.
Could you please give us more information on how to reproduce the bug please?
@PrettyWood it fails only when `from __future__ import annotations` is present: https://repl.it/repls/WaterySlimDehardwarization.
I can duplicate this bug in a single file

```py
from __future__ import annotations

from dataclasses import dataclass
from typing import Literal

from pydantic import BaseModel


@dataclass
class Base:
    literal: Literal[1, 2]


class What(BaseModel):
    base: Base


What(base=Base(literal=1))
```

I guess this is using stdlib dataclasses though
Hello guys
Sorry I forgot to come back on this issue.
So yes the issue is related to [this](https://docs.python.org/3/library/typing.html#typing.TYPE_CHECKING)

> If from __future__ import annotations is used in Python 3.7 or later, annotations are not evaluated at function definition time. Instead, they are stored as strings in __annotations__, This makes it unnecessary to use quotes around the annotation. (see PEP 563). 

So it's not really a bug but more a feature to support new behaviour of annotations.
And I reckon we'll probably need to dig into it quite soon!

Resolving patch:
diff --git a/pydantic/dataclasses.py b/pydantic/dataclasses.py
--- a/pydantic/dataclasses.py
+++ b/pydantic/dataclasses.py
@@ -5,6 +5,7 @@
 from .errors import DataclassTypeError
 from .fields import Required
 from .main import create_model, validate_model
+from .typing import resolve_annotations
 from .utils import ClassAttribute
 
 if TYPE_CHECKING:
@@ -128,7 +129,7 @@ def _pydantic_post_init(self: 'Dataclass', *initvars: Any) -> None:
             _cls.__name__,
             (_cls,),
             {
-                '__annotations__': _cls.__annotations__,
+                '__annotations__': resolve_annotations(_cls.__annotations__, _cls.__module__),
                 '__post_init__': _pydantic_post_init,
                 # attrs for pickle to find this class
                 '__module__': __name__,


Test patch:
diff --git a/tests/test_forward_ref.py b/tests/test_forward_ref.py
--- a/tests/test_forward_ref.py
+++ b/tests/test_forward_ref.py
@@ -4,6 +4,7 @@
 import pytest
 
 from pydantic import BaseModel, ConfigError, ValidationError
+from pydantic.typing import Literal
 
 skip_pre_37 = pytest.mark.skipif(sys.version_info < (3, 7), reason='testing >= 3.7 behaviour only')
 
@@ -480,6 +481,32 @@ def module():
         assert instance.sub.dict() == {'foo': 'bar'}
 
 
+@skip_pre_37
+@pytest.mark.skipif(not Literal, reason='typing_extensions not installed')
+def test_resolve_forward_ref_dataclass(create_module):
+    module = create_module(
+        # language=Python
+        """
+from __future__ import annotations
+
+from dataclasses import dataclass
+
+from pydantic import BaseModel
+from pydantic.typing import Literal
+
+@dataclass
+class Base:
+    literal: Literal[1, 2]
+
+class What(BaseModel):
+    base: Base
+        """
+    )
+
+    m = module.What(base=module.Base(literal=1))
+    assert m.base.literal == 1
+
+
 def test_nested_forward_ref():
     class NestedTuple(BaseModel):
         x: Tuple[int, Optional['NestedTuple']]  # noqa: F821