@@ -49,12 +49,10 @@ def __str__(self):
49
49
50
50
def __eq__ (self , other ):
51
51
"""Default equality method based on the _field_names"""
52
- if isinstance (self , type (other )):
53
- # self is a subclass of other
52
+ try :
54
53
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
58
56
59
57
def __repr__ (self ):
60
58
"""Default repr method based on the _field_names"""
@@ -228,7 +226,7 @@ def __repr__(self):
228
226
"""Override the inherited method to avoid infinite recursion"""
229
227
vals_to_display = (
230
228
('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
232
230
)
233
231
return "%s(%s)" % (self .__class__ .__name__ , ", " .join ("%s=%r" % (k , v ) for k , v in vals_to_display ))
234
232
@@ -243,11 +241,16 @@ class LazyTuple(Lazy):
243
241
"""
244
242
A wrapper representing a lazy_value used as a tuple = for several argvalues at once.
245
243
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.
249
252
"""
250
- __slots__ = 'value ' , 'theoretical_size' , 'retrieved'
253
+ __slots__ = 'valuegetter ' , 'theoretical_size' , 'retrieved' , 'value '
251
254
_field_names = __slots__
252
255
253
256
@classmethod
@@ -256,33 +259,32 @@ def copy_from(cls,
256
259
):
257
260
new_obj = cls (valueref = obj .value , theoretical_size = obj .theoretical_size )
258
261
new_obj .retrieved = obj .retrieved
262
+ if new_obj .retrieved :
263
+ new_obj .value = obj .value
259
264
return new_obj
260
265
261
266
# noinspection PyMissingConstructor
262
267
def __init__ (self ,
263
268
valueref , # type: Union[LazyValue, Sequence]
264
269
theoretical_size # type: int
265
270
):
266
- self .value = valueref
271
+ self .valuegetter = valueref
267
272
self .theoretical_size = theoretical_size
268
273
self .retrieved = False
274
+ self .value = None
269
275
270
276
def __len__ (self ):
271
277
return self .theoretical_size
272
278
273
279
def get_id (self ):
274
280
"""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 ()
280
282
281
283
def get (self ):
282
284
""" Call the underlying value getter, then return the tuple (not self) """
283
285
if not self .retrieved :
284
286
# retrieve
285
- self .value = self .value .get ()
287
+ self .value = self .valuegetter .get ()
286
288
self .retrieved = True
287
289
return self .value
288
290
@@ -303,15 +305,14 @@ def __getitem__(self, item):
303
305
304
306
def force_getitem (self , item ):
305
307
""" Call the underlying value getter, then return self[i]. """
306
- getter = self .value
307
308
argvalue = self .get ()
308
309
try :
309
310
return argvalue [item ]
310
311
except TypeError as e :
311
312
raise ValueError ("(lazy_value) The parameter value returned by `%r` is not compliant with the number"
312
313
" of argnames in parametrization (%s). A %s-tuple-like was expected. "
313
314
"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 ,
315
316
argvalue , item , e .__class__ , e ))
316
317
317
318
0 commit comments