@@ -49,12 +49,10 @@ def __str__(self):
4949
5050 def __eq__ (self , other ):
5151 """Default equality method based on the _field_names"""
52- if isinstance (self , type (other )):
53- # self is a subclass of other
52+ try :
5453 return all (getattr (self , k ) == getattr (other , k ) for k in self ._field_names )
55- else :
56- # other is from a subclass of self
57- return super (type (self ), self ).__eq__ (other )
54+ except :
55+ return False
5856
5957 def __repr__ (self ):
6058 """Default repr method based on the _field_names"""
@@ -228,7 +226,7 @@ def __repr__(self):
228226 """Override the inherited method to avoid infinite recursion"""
229227 vals_to_display = (
230228 ('item' , self .item ), # item number first for easier debug
231- ('tuple' , self .host .value ), # lazy value tuple or retrieved tuple
229+ ('tuple' , self .host .value if self . host . retrieved else self . host . valuegetter ), # lazy value tuple or retrieved tuple
232230 )
233231 return "%s(%s)" % (self .__class__ .__name__ , ", " .join ("%s=%r" % (k , v ) for k , v in vals_to_display ))
234232
@@ -243,11 +241,16 @@ class LazyTuple(Lazy):
243241 """
244242 A wrapper representing a lazy_value used as a tuple = for several argvalues at once.
245243
246- -
247- while not calling the lazy value
248- -
244+ Its `.get()` method caches the tuple obtained from the value getter, so that it is not called several times (once
245+ for each LazyTupleItem)
246+
247+ It is only used directly by pytest when a lazy_value is used in a @ parametrize to decorate a fixture.
248+ Indeed in that case pytest does not unpack the tuple, we do it in our custom @fixture.
249+
250+ In all other cases (when @parametrize is used on a test function), pytest unpacks the tuple so it directly
251+ manipulates the underlying LazyTupleItem instances.
249252 """
250- __slots__ = 'value ' , 'theoretical_size' , 'retrieved'
253+ __slots__ = 'valuegetter ' , 'theoretical_size' , 'retrieved' , 'value '
251254 _field_names = __slots__
252255
253256 @classmethod
@@ -256,33 +259,32 @@ def copy_from(cls,
256259 ):
257260 new_obj = cls (valueref = obj .value , theoretical_size = obj .theoretical_size )
258261 new_obj .retrieved = obj .retrieved
262+ if new_obj .retrieved :
263+ new_obj .value = obj .value
259264 return new_obj
260265
261266 # noinspection PyMissingConstructor
262267 def __init__ (self ,
263268 valueref , # type: Union[LazyValue, Sequence]
264269 theoretical_size # type: int
265270 ):
266- self .value = valueref
271+ self .valuegetter = valueref
267272 self .theoretical_size = theoretical_size
268273 self .retrieved = False
274+ self .value = None
269275
270276 def __len__ (self ):
271277 return self .theoretical_size
272278
273279 def get_id (self ):
274280 """return the id to use by pytest"""
275- if self .retrieved :
276- raise ValueError ("id is lost once the tuple has been retrieved, this is ok since at this stage it should "
277- "not be needed anymore..." )
278- else :
279- return self .value .get_id ()
281+ return self .valuegetter .get_id ()
280282
281283 def get (self ):
282284 """ Call the underlying value getter, then return the tuple (not self) """
283285 if not self .retrieved :
284286 # retrieve
285- self .value = self .value .get ()
287+ self .value = self .valuegetter .get ()
286288 self .retrieved = True
287289 return self .value
288290
@@ -303,15 +305,14 @@ def __getitem__(self, item):
303305
304306 def force_getitem (self , item ):
305307 """ Call the underlying value getter, then return self[i]. """
306- getter = self .value
307308 argvalue = self .get ()
308309 try :
309310 return argvalue [item ]
310311 except TypeError as e :
311312 raise ValueError ("(lazy_value) The parameter value returned by `%r` is not compliant with the number"
312313 " of argnames in parametrization (%s). A %s-tuple-like was expected. "
313314 "Returned lazy argvalue is %r and argvalue[%s] raised %s: %s"
314- % (getter .valuegetter , self .theoretical_size , self .theoretical_size ,
315+ % (self .valuegetter , self .theoretical_size , self .theoretical_size ,
315316 argvalue , item , e .__class__ , e ))
316317
317318
0 commit comments