@@ -1619,7 +1619,13 @@ def save_cell(pickler, obj):
16191619 log .info ("# Ce3" )
16201620 return
16211621 if is_dill (pickler , child = True ):
1622- postproc = next (iter (pickler ._postproc .values ()), None )
1622+ if id (f ) in pickler ._postproc :
1623+ # Already seen. Add to its postprocessing.
1624+ postproc = pickler ._postproc [id (f )]
1625+ else :
1626+ # Haven't seen it. Add to the highest possible object and set its
1627+ # value as late as possible to prevent cycle.
1628+ postproc = next (iter (pickler ._postproc .values ()), None )
16231629 if postproc is not None :
16241630 log .info ("Ce2: %s" % obj )
16251631 # _CELL_REF is defined in _shims.py to support older versions of
@@ -1830,7 +1836,7 @@ def _get_typedict_type(cls, clsdict, postproc_list):
18301836 return clsdict
18311837 # return _dict_from_dictproxy(cls.__dict__)
18321838
1833- def _get_typedict_abc (obj , _dict , state , postproc_list ):
1839+ def _get_typedict_abc (obj , _dict , attrs , postproc_list ):
18341840 log .info ("ABC: %s" % obj )
18351841 if hasattr (abc , '_get_dump' ):
18361842 (registry , _ , _ , _ ) = abc ._get_dump (obj )
@@ -1851,9 +1857,9 @@ def _get_typedict_abc(obj, _dict, state, postproc_list):
18511857 else :
18521858 del _dict ['_abc_impl' ]
18531859 log .info ("# ABC" )
1854- return _dict , state
1860+ return _dict , attrs
18551861
1856- def _get_typedict_enum (obj , _dict , state , postproc_list ):
1862+ def _get_typedict_enum (obj , _dict , attrs , postproc_list ):
18571863 log .info ("E: %s" % obj )
18581864 metacls = type (obj )
18591865 original_dict = {}
@@ -1866,8 +1872,12 @@ def _get_typedict_enum(obj, _dict, state, postproc_list):
18661872 _dict .pop ('_value2member_map_' , None )
18671873 _dict .pop ('_generate_next_value_' , None )
18681874
1875+ if attrs is not None :
1876+ attrs .update (_dict )
1877+ _dict = attrs
1878+
18691879 log .info ("# E" )
1870- return original_dict , ( None , _dict )
1880+ return original_dict , _dict
18711881
18721882@register (TypeType )
18731883def save_type (pickler , obj , postproc_list = None ):
@@ -1912,7 +1922,6 @@ def save_type(pickler, obj, postproc_list=None):
19121922 log .info ("# T7" )
19131923
19141924 else :
1915- obj_name = getattr (obj , '__qualname__' , getattr (obj , '__name__' , None ))
19161925 _byref = getattr (pickler , '_byref' , None )
19171926 obj_recursive = id (obj ) in getattr (pickler , '_postproc' , ())
19181927 incorrectly_named = not _locate_function (obj , pickler )
@@ -1923,25 +1932,30 @@ def save_type(pickler, obj, postproc_list=None):
19231932 # thanks to Tom Stepleton pointing out pickler._session unneeded
19241933 _t = 'T3'
19251934 _dict = _get_typedict_type (obj , obj .__dict__ .copy (), postproc_list ) # copy dict proxy to a dict
1926- state = None
1935+ attrs = None
19271936
19281937 for name in _dict .get ("__slots__" , []):
19291938 del _dict [name ]
19301939
1931- if PY3 and obj_name != obj .__name__ :
1932- postproc_list .append ((setattr , (obj , '__qualname__' , obj_name )))
1933-
19341940 if isinstance (obj , abc .ABCMeta ):
1935- _dict , state = _get_typedict_abc (obj , _dict , state , postproc_list )
1941+ _dict , attrs = _get_typedict_abc (obj , _dict , attrs , postproc_list )
19361942
19371943 if EnumMeta and isinstance (obj , EnumMeta ):
1938- _dict , state = _get_typedict_enum (obj , _dict , state , postproc_list )
1939-
1940- #print (_dict)
1941- #print ("%s\n%s" % (type(obj), obj.__name__))
1942- #print ("%s\n%s" % (obj.__bases__, obj.__dict__))
1943-
1944- if PY3 and type (obj ) is not type or hasattr (obj , '__orig_bases__' ):
1944+ _dict , attrs = _get_typedict_enum (obj , _dict , attrs , postproc_list )
1945+
1946+ qualname = getattr (obj , '__qualname__' , None )
1947+ if attrs is not None :
1948+ if qualname is not None :
1949+ attrs ['__qualname__' ] = qualname
1950+ for k , v in attrs .items ():
1951+ postproc_list .append ((setattr , (obj , k , v )))
1952+ state = _dict , attrs
1953+ elif qualname is not None :
1954+ postproc_list .append ((setattr , (obj , '__qualname__' , qualname )))
1955+ state = _dict
1956+
1957+ if True : # PY3 and type(obj) is not type or hasattr(obj, '__orig_bases__'):
1958+ # This case will always work, but might be overkill.
19451959 from types import new_class
19461960 _metadict = {
19471961 'metaclass' : type (obj )
@@ -1962,6 +1976,7 @@ def save_type(pickler, obj, postproc_list=None):
19621976 )), state , obj = obj , postproc_list = postproc_list )
19631977 log .info ("# %s" % _t )
19641978 else :
1979+ obj_name = getattr (obj , '__qualname__' , getattr (obj , '__name__' , None ))
19651980 log .info ("T4: %s" % obj )
19661981 if incorrectly_named :
19671982 warnings .warn ('Cannot locate reference to %r.' % (obj ,), PicklingWarning )
0 commit comments