def fkg_allowing_type_hints(
        namespace: Optional[str],
        fn: Callable,
        to_str: Callable[[Any], str] = repr) -> Callable[[Any], str]:
    """
    Replacement for :func:`dogpile.cache.util.function_key_generator` that
    handles type-hinted functions like

    .. code-block:: python

        def testfunc(param: str) -> str:
            return param + "hello"

    ... at which :func:`inspect.getargspec` balks; plus
    :func:`inspect.getargspec` is deprecated in Python 3.

    Used as an argument to e.g. ``@cache_region_static.cache_on_arguments()``.

    Also modified to make the cached function unique per INSTANCE for normal
    methods of a class.

    Args:
        namespace: optional namespace, as per :func:`get_namespace`
        fn: function to generate a key for (usually the function being
            decorated)
        to_str: function to apply to map arguments to a string (to make a
            unique key for a particular call to the function); by default it
            is :func:`repr`

    Returns:
        a function that generates a string key, based on a given function as
        well as arguments to the returned function itself.
    """

    namespace = get_namespace(fn, namespace)

    sig = inspect.signature(fn)
    argnames = [p.name for p in sig.parameters.values()
                if p.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD]
    has_self = bool(argnames and argnames[0] in ('self', 'cls'))

    def generate_key(*args: Any, **kw: Any) -> str:
        """
        Makes the actual key for a specific call to the decorated function,
        with particular ``args``/``kwargs``.
        """
        if kw:
            raise ValueError("This dogpile.cache key function generator, "
                             "fkg_allowing_type_hints, "
                             "does not accept keyword arguments.")
        if has_self:
            # Unlike dogpile's default, make it instance- (or class-) specific
            # by including a representation of the "self" or "cls" argument:
            args = [hex(id(args[0]))] + list(args[1:])
        key = namespace + "|" + " ".join(map(to_str, args))
        if DEBUG_INTERNALS:
            log.debug("fkg_allowing_type_hints.generate_key() -> {!r}", key)
        return key

    return generate_key