Python 3.7 was released a while ago, and I wanted to test some of the fancy new `dataclass`+typing features. Getting hints to work right is easy enough, with both native types and those from the `typing` module:

```
>>> import dataclasses
>>> import typing as ty
>>> 
... @dataclasses.dataclass
... class Structure:
...     a_str: str
...     a_str_list: ty.List[str]
...
>>> my_struct = Structure(a_str='test', a_str_list=['t', 'e', 's', 't'])
>>> my_struct.a_str_list[0].  # IDE suggests all the string methods :)

```

But one other thing that I wanted to try was forcing the type hints as conditions during runtime, i.e. it should not be possible for a `dataclass` with incorrect types to exist. It can be implemented nicely with [`__post_init__`](https://www.python.org/dev/peps/pep-0557/#post-init-processing):

```
>>> @dataclasses.dataclass
... class Structure:
...     a_str: str
...     a_str_list: ty.List[str]
...     
...     def validate(self):
...         ret = True
...         for field_name, field_def in self.__dataclass_fields__.items():
...             actual_type = type(getattr(self, field_name))
...             if actual_type != field_def.type:
...                 print(f"\t{field_name}: '{actual_type}' instead of '{field_def.type}'")
...                 ret = False
...         return ret
...     
...     def __post_init__(self):
...         if not self.validate():
...             raise ValueError('Wrong types')

```

This kind of `validate` function works for native types and custom classes, but not those specified by the `typing` module:

```
>>> my_struct = Structure(a_str='test', a_str_list=['t', 'e', 's', 't'])
Traceback (most recent call last):
  a_str_list: '<class 'list'>' instead of 'typing.List[str]'
  ValueError: Wrong types

```

Is there a better approach to validate an untyped list with a `typing`-typed one? Preferably one that doesn't include checking the types of all elements in any `list`, `dict`, `tuple`, or `set` that is a `dataclass`' attribute.

---

Revisiting this question after a couple of years, I've now moved to use [`pydantic`](https://pydantic-docs.helpmanual.io/) in cases where I want to validate classes that I'd normally just define a dataclass for. I'll leave my mark with the currently accepted answer though, since it correctly answers the original question and has outstanding educational value.