nodes: 0, module; 1, function_definition; 2, function_name:get_fn_args; 3, parameters; 4, block; 5, identifier:fn; 6, typed_parameter; 7, typed_default_parameter; 8, expression_statement; 9, expression_statement; 10, expression_statement; 11, expression_statement; 12, expression_statement; 13, if_statement; 14, return_statement; 15, identifier:kwargs; 16, type; 17, identifier:prefix; 18, type; 19, None; 20, comment:"""
      Given function and a dict of kwargs return a dict containing only the args
      used by the function.
  
      If prefix is specified, also search for args that begin with '{prefix}__'.
      Removes prefix in returned dict.
  
      Raises ValueError if a required arg is missing from the kwargs.
  
      Raises ValueError if both prefixed and unprefixed arg are given in kwargs.
  
      >>> from pprint import pprint as p # Use pprint to sort dict keys
      >>> kwargs = {'a': 1, 'b': 2, 'c': 3, 'x__d': 4}
      >>> def foo(a, b=10): return a + b
      >>> p(get_fn_args(foo, kwargs))
      {'a': 1, 'b': 2}
  
      >>> def bar(a, b, d): return a + b + d
      >>> p(get_fn_args(bar, kwargs, prefix='x'))
      {'a': 1, 'b': 2, 'd': 4}
  
      >>> p(get_fn_args(bar, kwargs))
      Traceback (most recent call last):
      ValueError: The following args are missing for the function bar: ['d']
      """; 21, assignment; 22, assignment; 23, assignment; 24, assignment; 25, identifier:missing_args; 26, block; 27, identifier:fn_kwargs; 28, identifier:dict; 29, identifier:str; 30, identifier:all_args; 31, call; 32, identifier:required_args; 33, call; 34, identifier:fn_kwargs; 35, call; 36, identifier:missing_args; 37, list_comprehension; 38, raise_statement; 39, identifier:get_all_args; 40, argument_list; 41, identifier:get_required_args; 42, argument_list; 43, identifier:pick_kwargs; 44, argument_list; 45, identifier:arg; 46, for_in_clause; 47, if_clause; 48, call; 49, identifier:fn; 50, identifier:fn; 51, identifier:kwargs; 52, identifier:all_args; 53, identifier:prefix; 54, identifier:arg; 55, identifier:required_args; 56, comparison_operator:arg not in fn_kwargs; 57, identifier:ValueError; 58, argument_list; 59, identifier:arg; 60, identifier:fn_kwargs; 61, call; 62, attribute; 63, argument_list; 64, concatenated_string; 65, identifier:format; 66, attribute; 67, identifier:missing_args; 68, string; 69, string; 70, identifier:fn; 71, identifier:__name__; 72, string_content:The following args are missing for the function; 73, string_content:{}: {}.
code: def get_fn_args(fn, kwargs: dict, prefix: str = None):
      """
      Given function and a dict of kwargs return a dict containing only the args
      used by the function.
  
      If prefix is specified, also search for args that begin with '{prefix}__'.
      Removes prefix in returned dict.
  
      Raises ValueError if a required arg is missing from the kwargs.
  
      Raises ValueError if both prefixed and unprefixed arg are given in kwargs.
  
      >>> from pprint import pprint as p # Use pprint to sort dict keys
      >>> kwargs = {'a': 1, 'b': 2, 'c': 3, 'x__d': 4}
      >>> def foo(a, b=10): return a + b
      >>> p(get_fn_args(foo, kwargs))
      {'a': 1, 'b': 2}
  
      >>> def bar(a, b, d): return a + b + d
      >>> p(get_fn_args(bar, kwargs, prefix='x'))
      {'a': 1, 'b': 2, 'd': 4}
  
      >>> p(get_fn_args(bar, kwargs))
      Traceback (most recent call last):
      ValueError: The following args are missing for the function bar: ['d']
      """
      all_args = get_all_args(fn)
      required_args = get_required_args(fn)
      fn_kwargs = pick_kwargs(kwargs, all_args, prefix)
  
      missing_args = [arg for arg in required_args if arg not in fn_kwargs]
      if missing_args:
          raise ValueError(
              'The following args are missing for the function '
              '{}: {}.'.format(fn.__name__, missing_args)
          )
  
      return fn_kwargs