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 = "", |
| 112 | cls: type | None = None, |
| 113 | ) -> tuple[str, ...]: |
| 114 | """Return the names of a function's mandatory arguments. |
| 115 | |
| 116 | Should return the names of all function arguments that: |
| 117 | * Aren't bound to an instance or type as in instance or class methods. |
| 118 | * Don't have default values. |
| 119 | * Aren't bound with functools.partial. |
| 120 | * Aren't replaced with mocks. |
| 121 | |
| 122 | The cls arguments indicate that the function should be treated as a bound |
| 123 | method even though it'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 | """ |
| 127 | # TODO(RonnyPfannschmidt): This function should be refactored when we |
| 128 | # revisit fixtures. The fixture mechanism should ask the node for |
| 129 | # the fixture names, and not try to obtain directly from the |
| 130 | # function object well after collection has occurred. |
| 131 | |
| 132 | # The parameters attribute of a Signature object contains an |
| 133 | # ordered mapping of parameter names to Parameter instances. This |
| 134 | # creates a tuple of the names of the parameters that don't have |
| 135 | # 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 | f"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 | # If this function should be treated as a bound method even though |
| 159 | # it's passed as an unbound method or function, and its first parameter |
| 160 | # 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 | # Not using `getattr` because we don't want to resolve the staticmethod. |
| 163 | # Not using `cls.__dict__` because we want to check the entire MRO. |
| 164 | cls |
| 165 | and not isinstance( |
searching dependent graphs…