def getfuncargnames(function, is_method=False, cls=None):
<EOL>try:<EOL><INDENT>parameters = signature(function).parameters<EOL><DEDENT>except (ValueError, TypeError) as e:<EOL><INDENT>fail(<EOL>"<STR_LIT>".format(function, e),<EOL>pytrace=False,<EOL>)<EOL><DEDENT>arg_names = tuple(<EOL>p.name<EOL>for p in parameters.values()<EOL>if (<EOL>p.kind is Parameter.POSITIONAL_OR_KEYWORD<EOL>or p.kind is Parameter.KEYWORD_ONLY<EOL>)<EOL>and p.default is Parameter.empty<EOL>)<EOL>if is_method or (<EOL>cls and not isinstance(cls.__dict__.get(function.__name__, None), staticmethod)<EOL>):<EOL><INDENT>arg_names = arg_names[<NUM_LIT:1>:]<EOL><DEDENT>if hasattr(function, "<STR_LIT>"):<EOL><INDENT>arg_names = arg_names[num_mock_patch_args(function) :]<EOL><DEDENT>return arg_names<EOL>
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.