@@ -1558,6 +1558,62 @@ def assertSameSet(self, s1, s2):
15581558 # coerce both to a real set then check equality
15591559 self .assertSetEqual (set (s1 ), set (s2 ))
15601560
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+
15611617 def test_Set_interoperability_with_real_sets (self ):
15621618 # Issue: 8743
15631619 class ListSet (Set ):
0 commit comments