from typing import Union, List
from dataclasses import dataclass


class Validations:
    def __post_init__(self):
        """Run validation methods if declared.

        The validation method can be a simple check
        that raises ValueError or a transformation to
        the field value.

        The validation is performed by calling a function named:
            `validate_<field_name>(self, value, field) -> field.type`
        """
        for name, field in self.__dataclass_fields__.items():
            if (method := getattr(self, f"validate_{name}", None)):
                setattr(self, name, method(getattr(self, name), field=field))


@dataclass
class Product(Validations):
    name: str
    tags: Union[str, List[str]]

    def validate_name(self, value, **_) -> str:
        if len(value) < 3 or len(value) > 20:
            raise ValueError("name must have between 3 and 20 chars.")
        return value

    def validate_tags(self, value, **_) -> List[str]:
        """Ensure tags are always List[str] even if "tag1,tag2" is passed"""
        if isinstance(value, str):
            value = [v.strip() for v in value.split(",")]
        return value


if __name__ == "__main__":
    product = Product(name="product", tags="tag1, tag2")
    assert product.tags == ["tag1", "tag2"]  # transformed to List[str]

    try:
        product = Product(name="pr", tags="tag1, tag2, tag3")
    except ValueError as e:
        assert str(e) == "name must have between 3 and 20 chars."