@@ -786,78 +786,68 @@ class Grouper:
786786 """
787787
788788 def __init__ (self , init = ()):
789- self ._mapping = {weakref .ref (x ): [weakref .ref (x )] for x in init }
789+ self ._mapping = weakref .WeakKeyDictionary (
790+ {x : weakref .WeakSet ([x ]) for x in init })
790791
791792 def __getstate__ (self ):
792793 return {
793794 ** vars (self ),
794795 # Convert weak refs to strong ones.
795- "_mapping" : {k (): [ v ( ) for v in vs ] for k , vs in self ._mapping .items ()},
796+ "_mapping" : {k : set ( v ) for k , v in self ._mapping .items ()},
796797 }
797798
798799 def __setstate__ (self , state ):
799800 vars (self ).update (state )
800801 # Convert strong refs to weak ones.
801- self ._mapping = { weakref .ref ( k ): [ * map ( weakref . ref , vs )]
802- for k , vs in self ._mapping .items ()}
802+ self ._mapping = weakref .WeakKeyDictionary (
803+ { k : weakref . WeakSet ( v ) for k , v in self ._mapping .items ()})
803804
804805 def __contains__ (self , item ):
805- return weakref . ref ( item ) in self ._mapping
806+ return item in self ._mapping
806807
808+ @_api .deprecated ("3.8" , alternative = "none, you no longer need to clean a Grouper" )
807809 def clean (self ):
808810 """Clean dead weak references from the dictionary."""
809- mapping = self ._mapping
810- to_drop = [key for key in mapping if key () is None ]
811- for key in to_drop :
812- val = mapping .pop (key )
813- val .remove (key )
814811
815812 def join (self , a , * args ):
816813 """
817814 Join given arguments into the same set. Accepts one or more arguments.
818815 """
819816 mapping = self ._mapping
820- set_a = mapping .setdefault (weakref . ref ( a ), [ weakref .ref ( a )] )
817+ set_a = mapping .setdefault (a , weakref .WeakSet ([ a ]) )
821818
822819 for arg in args :
823- set_b = mapping .get (weakref . ref ( arg ), [ weakref .ref ( arg )] )
820+ set_b = mapping .get (arg , weakref .WeakSet ([ arg ]) )
824821 if set_b is not set_a :
825822 if len (set_b ) > len (set_a ):
826823 set_a , set_b = set_b , set_a
827- set_a .extend (set_b )
824+ set_a .update (set_b )
828825 for elem in set_b :
829826 mapping [elem ] = set_a
830827
831- self .clean ()
832-
833828 def joined (self , a , b ):
834829 """Return whether *a* and *b* are members of the same set."""
835- self .clean ()
836- return (self ._mapping .get (weakref .ref (a ), object ())
837- is self ._mapping .get (weakref .ref (b )))
830+ return (self ._mapping .get (a , object ()) is self ._mapping .get (b ))
838831
839832 def remove (self , a ):
840- self .clean ()
841- set_a = self ._mapping .pop (weakref .ref (a ), None )
833+ set_a = self ._mapping .pop (a , None )
842834 if set_a :
843- set_a .remove (weakref . ref ( a ) )
835+ set_a .remove (a )
844836
845837 def __iter__ (self ):
846838 """
847839 Iterate over each of the disjoint sets as a list.
848840
849841 The iterator is invalid if interleaved with calls to join().
850842 """
851- self .clean ()
852843 unique_groups = {id (group ): group for group in self ._mapping .values ()}
853844 for group in unique_groups .values ():
854- yield [x () for x in group ]
845+ yield [x for x in group ]
855846
856847 def get_siblings (self , a ):
857848 """Return all of the items joined with *a*, including itself."""
858- self .clean ()
859- siblings = self ._mapping .get (weakref .ref (a ), [weakref .ref (a )])
860- return [x () for x in siblings ]
849+ siblings = self ._mapping .get (a , [a ])
850+ return [x for x in siblings ]
861851
862852
863853class GrouperView :
0 commit comments