""" Module defining the "complete" version of typed iterable classes

(i) All typed iterables are extending from a built-in iterable:
list, tuple, set or frozenset.

Specificities
-------------
The "complete" version ensures the type safety of the current instance, 
and type safety of new instances generated from it.

- Mutating methods that could insert incompatible items are overridden,
they perform type checks, and will fail instead of inserting an incompatible item.

- Non-Mutating methods that used to return an instance of the same class
are overridden to return an instance of the current typed iterable,
for example, list addition returns a new list, so TypedList addition
returns a new TypedList.
So those operations will perform type checks and fail instead of inserting an 
incompatible item in the result.

The aim is too be coherent with the built-in iterables the classes are based on.
The downside is that it makes those operations heavier and less permissive.

Exported Classes
----------------
- **TypedList**
- **TypedTuple**
- **TypedSet**
- **TypedFrozenset**

Usage Exemple
-------------
>>> # importing 'complete' version of typed list class
>>> from typediter import TypedList
>>>
>>> # creating an instance
>>> string_list = TypedList( ('A', 'B', 'C'), i_type=str )
>>>
>>> # supports all the operations of the base built-in iterable
>>> string_list.append( 'D' )
>>> string_list[2] = 'Z'
>>>
>>> # new instances generated by non-mutating
>>> # operations are also type-safe
>>> new_list = string_list + ['E', 'F']
>>> type( new_list ) # -> TypedList
>>>
>>> # Remark:
>>> # if the operation is handled by the built-in, a built-in is returned
>>> builtin_addition_result = [ 'E', 'F' ] + string_list
>>> type( builtin_addition_result ) # -> list
>>>
>>> # trying to insert an incompatible item in the instance,
>>> # or in a typed iterable instance generated by an operation,
>>> # will raise a TypeRestrictionError
>>> invalid_instance = TypedList( ( 1, 2, 3 ), i_type=str ) # will raise TypeRestrictionError
>>> string_list.append( 12 ) # will raise TypeRestrictionError
>>> invalid_operation_result = string_list + [ 1, 2, 3 ] # will raise TypeRestrictionError
"""
from .list import TypedList
from .tuple import TypedTuple
from .set import TypedSet
from .frozenset import TypedFrozenset

__all__ = [
    "TypedList",
    "TypedTuple",
    "TypedSet",
    "TypedFrozenset"
]