validateit 1.0.2
Dataclasses Validators
License: MIT
Requires Python: >=3.6

***********
Validate It
***********

Dataclass Validators.

typeforced decorator
--------------------
Dataclasses module does not control types in runtime. With `validateit` you can force user to give propert date with propert type.
`validateit` provides a class decorator for runtime typecheck. You have to decorate your dataclass with `@typeforced`.

.. code-block:: python

    >>> @typeforced
    ... @dataclass
    ... class Item:
    ...     name: str
    ...     idx : int
    ...     owners : List[str]
    ...
    >>>

Lets try to create a valid Item

.. code-block:: python

    >>> Item("Sword", 1, ["damla"])
    Item(name='Sword', idx=1, owners=['damla'])

Funny part :) Lets give int value to name field. 

.. code-block:: python

    >>> Item(1515, 1, ["damla"])
    TypeError: Unexpected type for 'name' (expected <class 'str'> but found <class 'int'>)

As you can see `typeguard` raised a TypeError because it expects a string but we give it an integer. 

Lets make another example. Give a set object instead of List[str].

.. code-block:: python

    >>> Item("Sword", 1, {"damla"})
    TypeError: Unexpected type for 'owners' (expected typing.List[str] but found <class 'set'>)

TypeValidator
-------------
Validates types for specific fields instead of all fields (if you want to check types of all fields in runtime use `typeforced`).

Lets make an pet. We must force user to give name as string but we dont care type of `idx`.

.. code-block:: python
    
    >>> @dataclass
    ... class Pet:
    ...     idx: int
    ...     name: str = field(default=TypeValidator())
    ... 
    >>> Pet(15, "Minnos")
    Pet(idx=15, name='Minnos')
    >>> Pet(15, 1313)
    TypeError: Unexpected type for 'name' (expected <class 'str'> but found <class 'int'>)
    >>> Pet("fifteen", "Minnos") # No error cuz it is not runtime typevalidated.
    Pet(idx='fifteen', name='Minnos')

IntegerValidator
----------------
Some integer specific validations. Can take `max` , `min` , `max_digits`, `min_digits`

.. code-block:: python
    
    >>> @dataclass
    ... class Integer:
    ...     number : int = field(default=IntegerValidator(min=15, max=150))
    ...     point  : int = field(default=IntegerValidator(min_digits=1, max_digits=10))
    ...     def __str__(self):
    ...         return f"{self.number}.{self.point}"
    ... 
    >>> str(Integer(20, 3333))
    '20.3333'
    >>> Integer(14, 3333)
    ValueError: Integer is not bigger than 15 (minimum limit)
    >>> Integer(160, 3333)
    ValueError: Integer is bigger than 150 (maximum limit)
    >>> Integer(20, 339933993399339)
    ValueError: Integer doesn't capable of having maximum 10 digits.
    
StringValidator
---------------
Some string specific validations. Can take `max_chars` , `max_chars` , `startswith`, `endswith`

.. code-block:: python

    >>> @dataclass
    ... class Person:
    ...     name: str = field(default=StringValidator(min_chars=5, max_chars=10))
    ...     surname: str = field(default=StringValidator(startswith='a', endswith='n'))
    ... 
    >>> Person("damla", "altun")
    Person(name='damla', surname='altun')
    >>> Person("daml", "altun")
    ValueError: String doesn't capable of having minimum 5 chars.
    >>> Person("damlaaaaaaaaa", "altun")
    ValueError: String doesn't capable of having maximum 10 chars.
    >>> Person("damla", "xaltun")
    ValueError: String isn't starts with a
    >>> Person("damla", "altunx")
    ValueError: String isn't ends with n