docs: def supports_kwargs(module_or_fn, kwargs_list):
    """Determines whether the provided callable supports all the kwargs.
  
    This is useful when you have a module that might or might not support a
    kwarg such as `is_training`. Rather than calling the module and catching the
    error, risking the potential modification of underlying state, this function
    introspects the module to see what kwargs are actually supported, using
    the python `inspect` module.
  
    Note that many TF functions do not export a valid argspec object, rather they
    have a generic *args, **kwargs signature due to various layers of wrapping
    (deprecation decorators, etc). In those circumstances we return
    MAYBE_SUPPORTED, and users will have to use another method to tell whether
    the kwargs are supported (e.g. by just calling the function).
  
    Args:
      module_or_fn: some callable, generally an object or a method of some object.
        If an object is provided, we check wither `module_or_fn.__call__` supports
        the provided kwargs, which for a Sonnet module will automatically check
        the signature of _build. If `module_or_fn` is a function/method, then
        we check its signature directly, so non-Sonnet functions can be used.
      kwargs_list: string or iterable of strings of keyword arg names to test for.
        If an empty iterable is provided this function will always return True.
  
    Raises:
      ValueError: if a non-string is provided in `kwargs_list`.
  
    Returns:
      a string, one of 'supported', 'not_supported' or 'maybe_supported'.
    """
    if isinstance(kwargs_list, six.string_types):
      kwargs_list = [kwargs_list]
  
    # If it's not a function or method, then assume it's a module, so introspect
    # the __call__ method. wrapt ensures that for Sonnet modules the _build
    # signature is available here.
    if not (inspect.isfunction(module_or_fn) or inspect.ismethod(module_or_fn)):
      module_or_fn = module_or_fn.__call__
  
    arg_spec = inspect.getargspec(module_or_fn)
  
    # If there is a keywords element, then an arbitrary kwargs will work, as far
    # as we can tell from here.
    takes_arbitrary_kwargs = (arg_spec.keywords is not None)
  
    for kwarg in kwargs_list:
      if not isinstance(kwarg, six.string_types):
        raise ValueError("kwargs should be strings, instead got {}".format(
            kwarg))
      if kwarg not in arg_spec.args:
        if not takes_arbitrary_kwargs:
          # The function doesn't take **kwargs, and this name is not in the
          # regular args, so it would definitely cause an error to call this.
          return NOT_SUPPORTED
        else:
          # The function may accept the kwarg, but we can't say for sure. Even
          # though this is only one kwarg, we can't be certain about the whole
          # lot, so the combined answer is now "maybe".
          return MAYBE_SUPPORTED
    # All the kwargs must actually be present in the specific args list
    return SUPPORTED