code: def get_type(type_: Type) -> 'PredicateType':
          
          if is_callable(type_):
              callable_args = type_.__args__
              argument_types = [PredicateType.get_type(t) for t in callable_args[:-1]]
              return_type = PredicateType.get_type(callable_args[-1])
              return FunctionType(argument_types, return_type)
          elif is_generic(type_):
              # This is something like List[int].  type_.__name__ doesn't do the right thing (and
              # crashes in python 3.7), so we need to do some magic here.
              name = get_generic_name(type_)
          else:
              name = type_.__name__
          return BasicType(name)
docs: Converts a python ``Type`` (as you might get from a type annotation) into a
          ``PredicateType``.  If the ``Type`` is callable, this will return a ``FunctionType``;
          otherwise, it will return a ``BasicType``.
  
          ``BasicTypes`` have a single ``name`` parameter - we typically get this from
          ``type_.__name__``.  This doesn't work for generic types (like ``List[str]``), so we handle
          those specially, so that the ``name`` for the ``BasicType`` remains ``List[str]``, as you
          would expect.