Improvement: Base FixtureArgKeys on param values if possible, not param indices#11271
Conversation
bluetech
left a comment
There was a problem hiding this comment.
Thanks @sadra-barikbin, the implementation is very clean :)
This has come up previously in #9350. The main worry is about users using very large parametrize values. Arguably Hashable would exclude such values (such as numpy.array or large dicts) and fall back to the fast param index comparison. But I'm still pretty sure that we'll get "you made pytest slow" complaints from users using big hashable values like tuples etc, which we will now start hashing and comparing by value.
That's why I'm a bit scared to merge this as-is. After discussions in #9350, @haxtibal came up with a refinement of the idea in #9420, which keeps the Hashable business but adds an opt out for users who get hit by the "slow hashable value" problem. The workaround is to add a third comparison method, this one by parameter ID.
Unfortunately I dropped the ball on #9420 but there was fruitful discussion there.
Let me know what you think.
|
@bluetech , how is to compute the hash values only once using this wrapper around param value? class _ParamValue:
def __init__(self, value: Hashable):
self.value = value
@property
def hash(self):
return hash(self.value)
def __hash__(self) -> int:
return self.hash
def __eq__(self, o: "_ParamValue") -> bool:
return self.hash == o.hash
@dataclasses.dataclass(frozen=True)
class FixtureArgKeyByValue:
argname: str
param_value: _ParamValue
scoped_item_path: Optional[Path]
item_cls: Optional[type] |
To base fixture argkeys on param values rather than on indices unless the value isn't hashable in which case we fallback to param index.