Return the names of a function's mandatory arguments. 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.
(
function: Callable[..., Any],
*,
name: str = "",
is_method: bool = False,
cls: Optional[type] = None,
)
| 117 | |
| 118 | |
| 119 | def getfuncargnames( |
| 120 | function: Callable[..., Any], |
| 121 | *, |
| 122 | name: str = "", |
| 123 | is_method: bool = False, |
| 124 | cls: Optional[type] = None, |
| 125 | ) -> Tuple[str, ...]: |
| 126 | """Return the names of a function's mandatory arguments. |
| 127 | |
| 128 | Should return the names of all function arguments that: |
| 129 | * Aren't bound to an instance or type as in instance or class methods. |
| 130 | * Don't have default values. |
| 131 | * Aren't bound with functools.partial. |
| 132 | * Aren't replaced with mocks. |
| 133 | |
| 134 | The is_method and cls arguments indicate that the function should |
| 135 | be treated as a bound method even though it's not unless, only in |
| 136 | the case of cls, the function is a static method. |
| 137 | |
| 138 | The name parameter should be the original name in which the function was collected. |
| 139 | """ |
| 140 | # TODO(RonnyPfannschmidt): This function should be refactored when we |
| 141 | # revisit fixtures. The fixture mechanism should ask the node for |
| 142 | # the fixture names, and not try to obtain directly from the |
| 143 | # function object well after collection has occurred. |
| 144 | |
| 145 | # The parameters attribute of a Signature object contains an |
| 146 | # ordered mapping of parameter names to Parameter instances. This |
| 147 | # creates a tuple of the names of the parameters that don't have |
| 148 | # defaults. |
| 149 | try: |
| 150 | parameters = signature(function).parameters |
| 151 | except (ValueError, TypeError) as e: |
| 152 | from _pytest.outcomes import fail |
| 153 | |
| 154 | fail( |
| 155 | f"Could not determine arguments of {function!r}: {e}", |
| 156 | pytrace=False, |
| 157 | ) |
| 158 | |
| 159 | arg_names = tuple( |
| 160 | p.name |
| 161 | for p in parameters.values() |
| 162 | if ( |
| 163 | p.kind is Parameter.POSITIONAL_OR_KEYWORD |
| 164 | or p.kind is Parameter.KEYWORD_ONLY |
| 165 | ) |
| 166 | and p.default is Parameter.empty |
| 167 | ) |
| 168 | if not name: |
| 169 | name = function.__name__ |
| 170 | |
| 171 | # If this function should be treated as a bound method even though |
| 172 | # it's passed as an unbound method or function, remove the first |
| 173 | # parameter name. |
| 174 | if is_method or ( |
| 175 | # Not using `getattr` because we don't want to resolve the staticmethod. |
| 176 | # Not using `cls.__dict__` because we want to check the entire MRO. |