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