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