Generic getter for environment variables. Handles defaults,
    required-ness, and what type to expect.

    :param name: The name of the environment variable be pulled
    :type name: str

    :param required: Whether the environment variable is required. If ``True``
    and the variable is not present, a ``KeyError`` is raised.
    :type required: bool

    :param default: The value to return if the environment variable is not
    present. (Providing a default alongside setting ``required=True`` will raise
    a ``ValueError``)
    :type default: bool

    :param type: The type of variable expected.
    :param type: str or type

def get(name: str,
        required: bool=False,
        default: Union[Type[empty], T]=empty,
        type: Type[T]=None) -> T:
    """Generic getter for environment variables. Handles defaults,
    required-ness, and what type to expect.

    :param name: The name of the environment variable be pulled
    :type name: str

    :param required: Whether the environment variable is required. If ``True``
    and the variable is not present, a ``KeyError`` is raised.
    :type required: bool

    :param default: The value to return if the environment variable is not
    present. (Providing a default alongside setting ``required=True`` will raise
    a ``ValueError``)
    :type default: bool

    :param type: The type of variable expected.
    :param type: str or type
    """
    fns = {
        'int': env_int,
        int: env_int,

        # 'float': env_float,
        # float: env_float,

        'bool': env_bool,
        bool: env_bool,

        'string': env_string,
        str: env_string,

        'list': env_list,
        list: env_list,
    }  # type: Dict[Union[str, Type[Any]], Callable[..., Any]]

    fn = fns.get(type, env_string)
    return fn(name, default=default, required=required)