from typing import Iterable
from typing import List
from typing import Any


def flatten(iterable: Iterable, drop_null: bool = False) -> List[Any]:
    """Flatten out a nested iterable.

    Flatten a nested iterable, even with multiple nesting levels and
    different data types. It is also possible to drop null values (None)
    from the resulting list.

    Args:
        iterable: nested iterable to flatten
        drop_null: filter out None from the flattened list (default: False)

    Returns:
        flat list
    """
    def flattenator(element):
        for el in element:
            if isinstance(el, Iterable) and not isinstance(el, (str, bytes)):
                yield from flattenator(el)
            else:
                yield el

    if drop_null:
        return list(filter(None.__ne__, list(flattenator(iterable))))
    return list(flattenator(iterable))