code: def getfuncargnames(function, is_method=False, cls=None):
      """Returns the names of a function's mandatory arguments.
  
      This should return the names of all function arguments that:
          * Aren't bound to an instance or type as in instance or class methods.
          * Don't have default values.
          * Aren't bound with functools.partial.
          * Aren't replaced with mocks.
  
      The is_method and cls arguments indicate that the function should
      be treated as a bound method even though it's not unless, only in
      the case of cls, the function is a static method.
  
      @RonnyPfannschmidt: This function should be refactored when we
      revisit fixtures. The fixture mechanism should ask the node for
      the fixture names, and not try to obtain directly from the
      function object well after collection has occurred.
  
      """
      # The parameters attribute of a Signature object contains an
      # ordered mapping of parameter names to Parameter instances.  This
      # creates a tuple of the names of the parameters that don't have
      # defaults.
      try:
          parameters = signature(function).parameters
      except (ValueError, TypeError) as e:
          fail(
              "Could not determine arguments of {!r}: {}".format(
                  function, e
              ),
              pytrace=False,
          )
  
      arg_names = tuple(
          p.name
          for p in parameters.values()
          if (
              p.kind is Parameter.POSITIONAL_OR_KEYWORD
              or p.kind is Parameter.KEYWORD_ONLY
          )
          and p.default is Parameter.empty
      )
      # If this function should be treated as a bound method even though
      # it's passed as an unbound method or function, remove the first
      # parameter name.
      if is_method or (
          cls
          and not isinstance(
              cls.__dict__.get(function.__name__, None), staticmethod
          )
      ):
          arg_names = arg_names[1:]
      # Remove any names that will be replaced with mocks.
      if hasattr(function, "__wrapped__"):
          arg_names = arg_names[num_mock_patch_args(function) :]
      return arg_names
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import codecs
  import functools
  import inspect
  import re
  import sys
  from contextlib import contextmanager
  import attr
  import py
  import six
  from six import text_type
  import _pytest
  from _pytest._io.saferepr import saferepr
  from _pytest.outcomes import fail
  from _pytest.outcomes import TEST_OUTCOME
label_desc: Use image node_id 6 for calling a global function with example usage: getfuncargnames(function, is_method, cls) and returns: arg_names