from typing import get_origin
from typing import get_args


def has_origin(typ, origin, num_args=None):
    """
    Determines if a concrete class (a generic class with arguments) matches an origin
    and has a specified number of arguments.

    This does a direct match rather than a subclass check.

    The typing classes use dunder properties such that ``__origin__`` is the generic
    class and ``__args__`` are the type arguments.

    Note: in python3.7, the ``__origin__`` attribute changed to reflect native types.
    This call attempts to work around that so that 3.5 and 3.6 "just work."
    """
    t_origin = get_origin(typ)
    if not isinstance(origin, tuple):
        origin = (origin,)
    return t_origin in origin and (num_args is None or len(get_args(typ)) == num_args)