from typing import Any


def serialise(obj: Any, no_head: bool = False) -> dict:
    """Takes any non-primitive object and serialises it into a dict.
    Arguments:
        obj(Any): Any non primitive object.
        no_head(bool): Will not specify the module and class of the object when True.
    Returns:
        dict: A serialised dictionary of all the values of an object. May also contain the module and class.
    Raises:
         TypeError: Raised when a built in object is given.

    """
    if obj.__class__.__module__ == '__builtin__':
        raise TypeError("Can't serialise a builtin type.")

    cls = obj.__class__
    if no_head:
        dct = {"values": {}}
    else:
        dct = {"__module__": cls.__module__,
               "__name__": cls.__name__,
               "values": {}}
    for i in dir(obj):
        try:
            val = getattr(obj, i)
        except AttributeError:
            val = None
        if i.startswith("_") or callable(val) or i in vars(cls):
            continue
        elif not isinstance(val, (str, int, bool, dict)) and val is not None:
            try:
                val = serialise(val)
                print(val)
            except RecursionError:
                val = str(val)
        dct["values"][i] = val
    if no_head:
        return dct["values"]
    else:
        return dct