@@ -1558,6 +1558,62 @@ def assertSameSet(self, s1, s2):
1558
1558
# coerce both to a real set then check equality
1559
1559
self .assertSetEqual (set (s1 ), set (s2 ))
1560
1560
1561
+ def test_Set_from_iterable (self ):
1562
+ """Verify _from_iterable overriden to an instance method works."""
1563
+ class SetUsingInstanceFromIterable (MutableSet ):
1564
+ def __init__ (self , values , created_by ):
1565
+ if not created_by :
1566
+ raise ValueError (f'created_by must be specified' )
1567
+ self .created_by = created_by
1568
+ self ._values = set (values )
1569
+
1570
+ def _from_iterable (self , values ):
1571
+ return type (self )(values , 'from_iterable' )
1572
+
1573
+ def __contains__ (self , value ):
1574
+ return value in self ._values
1575
+
1576
+ def __iter__ (self ):
1577
+ yield from self ._values
1578
+
1579
+ def __len__ (self ):
1580
+ return len (self ._values )
1581
+
1582
+ def add (self , value ):
1583
+ self ._values .add (value )
1584
+
1585
+ def discard (self , value ):
1586
+ self ._values .discard (value )
1587
+
1588
+ impl = SetUsingInstanceFromIterable ([1 , 2 , 3 ], 'test' )
1589
+
1590
+ actual = impl - {1 }
1591
+ self .assertIsInstance (actual , SetUsingInstanceFromIterable )
1592
+ self .assertEqual ('from_iterable' , actual .created_by )
1593
+ self .assertEqual ({2 , 3 }, actual )
1594
+
1595
+ actual = impl | {4 }
1596
+ self .assertIsInstance (actual , SetUsingInstanceFromIterable )
1597
+ self .assertEqual ('from_iterable' , actual .created_by )
1598
+ self .assertEqual ({1 , 2 , 3 , 4 }, actual )
1599
+
1600
+ actual = impl & {2 }
1601
+ self .assertIsInstance (actual , SetUsingInstanceFromIterable )
1602
+ self .assertEqual ('from_iterable' , actual .created_by )
1603
+ self .assertEqual ({2 }, actual )
1604
+
1605
+ actual = impl ^ {3 , 4 }
1606
+ self .assertIsInstance (actual , SetUsingInstanceFromIterable )
1607
+ self .assertEqual ('from_iterable' , actual .created_by )
1608
+ self .assertEqual ({1 , 2 , 4 }, actual )
1609
+
1610
+ # NOTE: ixor'ing with a list is important here: internally, __ixor__
1611
+ # only calls _from_iterable if the other value isn't already a Set.
1612
+ impl ^= [3 , 4 ]
1613
+ self .assertIsInstance (impl , SetUsingInstanceFromIterable )
1614
+ self .assertEqual ('test' , impl .created_by )
1615
+ self .assertEqual ({1 , 2 , 4 }, impl )
1616
+
1561
1617
def test_Set_interoperability_with_real_sets (self ):
1562
1618
# Issue: 8743
1563
1619
class ListSet (Set ):
0 commit comments