@@ -264,6 +264,84 @@ def test_match_args_with_unnamed_fields(self):
264264 self .assertEqual (os .stat_result .n_unnamed_fields , 3 )
265265 self .assertEqual (os .stat_result .__match_args__ , expected_args )
266266
267+ def test_copy_replace_all_fields_visible (self ):
268+ assert os .times_result .n_unnamed_fields == 0
269+ assert os .times_result .n_sequence_fields == os .times_result .n_fields
270+
271+ t = os .times ()
272+
273+ # visible fields
274+ self .assertEqual (copy .replace (t ), t )
275+ self .assertIsInstance (copy .replace (t ), os .times_result )
276+ self .assertEqual (copy .replace (t , user = 1.5 ), (1.5 , * t [1 :]))
277+ self .assertEqual (copy .replace (t , system = 2.5 ), (t [0 ], 2.5 , * t [2 :]))
278+ self .assertEqual (copy .replace (t , user = 1.5 , system = 2.5 ), (1.5 , 2.5 , * t [2 :]))
279+
280+ # unknown fields
281+ with self .assertRaisesRegex (TypeError , 'unexpected field name' ):
282+ copy .replace (t , error = - 1 )
283+ with self .assertRaisesRegex (TypeError , 'unexpected field name' ):
284+ copy .replace (t , user = 1 , error = - 1 )
285+
286+ def test_copy_replace_with_invisible_fields (self ):
287+ assert time .struct_time .n_unnamed_fields == 0
288+ assert time .struct_time .n_sequence_fields < time .struct_time .n_fields
289+
290+ t = time .gmtime (0 )
291+
292+ # visible fields
293+ t2 = copy .replace (t )
294+ self .assertEqual (t2 , (1970 , 1 , 1 , 0 , 0 , 0 , 3 , 1 , 0 ))
295+ self .assertIsInstance (t2 , time .struct_time )
296+ t3 = copy .replace (t , tm_year = 2000 )
297+ self .assertEqual (t3 , (2000 , 1 , 1 , 0 , 0 , 0 , 3 , 1 , 0 ))
298+ self .assertEqual (t3 .tm_year , 2000 )
299+ t4 = copy .replace (t , tm_mon = 2 )
300+ self .assertEqual (t4 , (1970 , 2 , 1 , 0 , 0 , 0 , 3 , 1 , 0 ))
301+ self .assertEqual (t4 .tm_mon , 2 )
302+ t5 = copy .replace (t , tm_year = 2000 , tm_mon = 2 )
303+ self .assertEqual (t5 , (2000 , 2 , 1 , 0 , 0 , 0 , 3 , 1 , 0 ))
304+ self .assertEqual (t5 .tm_year , 2000 )
305+ self .assertEqual (t5 .tm_mon , 2 )
306+
307+ # named invisible fields
308+ self .assertTrue (hasattr (t , 'tm_zone' ), f"{ t } has no attribute 'tm_zone'" )
309+ with self .assertRaisesRegex (AttributeError , 'readonly attribute' ):
310+ t .tm_zone = 'some other zone'
311+ self .assertEqual (t2 .tm_zone , t .tm_zone )
312+ self .assertEqual (t3 .tm_zone , t .tm_zone )
313+ self .assertEqual (t4 .tm_zone , t .tm_zone )
314+ t6 = copy .replace (t , tm_zone = 'some other zone' )
315+ self .assertEqual (t , t6 )
316+ self .assertEqual (t6 .tm_zone , 'some other zone' )
317+ t7 = copy .replace (t , tm_year = 2000 , tm_zone = 'some other zone' )
318+ self .assertEqual (t7 , (2000 , 1 , 1 , 0 , 0 , 0 , 3 , 1 , 0 ))
319+ self .assertEqual (t7 .tm_year , 2000 )
320+ self .assertEqual (t7 .tm_zone , 'some other zone' )
321+
322+ # unknown fields
323+ with self .assertRaisesRegex (TypeError , 'unexpected field name' ):
324+ copy .replace (t , error = 2 )
325+ with self .assertRaisesRegex (TypeError , 'unexpected field name' ):
326+ copy .replace (t , tm_year = 2000 , error = 2 )
327+ with self .assertRaisesRegex (TypeError , 'unexpected field name' ):
328+ copy .replace (t , tm_zone = 'some other zone' , error = 2 )
329+
330+ def test_copy_replace_with_unnamed_fields (self ):
331+ assert os .stat_result .n_unnamed_fields > 0
332+
333+ r = os .stat_result (range (os .stat_result .n_sequence_fields ))
334+
335+ error_message = re .escape ('__replace__() is not supported' )
336+ with self .assertRaisesRegex (TypeError , error_message ):
337+ copy .replace (r )
338+ with self .assertRaisesRegex (TypeError , error_message ):
339+ copy .replace (r , st_mode = 1 )
340+ with self .assertRaisesRegex (TypeError , error_message ):
341+ copy .replace (r , error = 2 )
342+ with self .assertRaisesRegex (TypeError , error_message ):
343+ copy .replace (r , st_mode = 1 , error = 2 )
344+
267345
268346if __name__ == "__main__" :
269347 unittest .main ()
0 commit comments