@@ -1110,11 +1110,35 @@ def save_global(self, obj, name=None):
11101110 self .save (module_name )
11111111 self .save (name )
11121112 write (STACK_GLOBAL )
1113- elif parent is not module :
1114- self .save_reduce (getattr , (parent , lastname ))
1115- elif self .proto >= 3 :
1116- write (GLOBAL + bytes (module_name , "utf-8" ) + b'\n ' +
1117- bytes (name , "utf-8" ) + b'\n ' )
1113+ elif '.' in name :
1114+ # In protocol < 4, objects with multi-part __qualname__
1115+ # are represented as
1116+ # getattr(getattr(..., attrname1), attrname2).
1117+ dotted_path = name .split ('.' )
1118+ name = dotted_path .pop (0 )
1119+ save = self .save
1120+ for attrname in dotted_path :
1121+ save (getattr )
1122+ if self .proto < 2 :
1123+ write (MARK )
1124+ self ._save_toplevel_by_name (module_name , name )
1125+ for attrname in dotted_path :
1126+ save (attrname )
1127+ if self .proto < 2 :
1128+ write (TUPLE )
1129+ else :
1130+ write (TUPLE2 )
1131+ write (REDUCE )
1132+ else :
1133+ self ._save_toplevel_by_name (module_name , name )
1134+
1135+ self .memoize (obj )
1136+
1137+ def _save_toplevel_by_name (self , module_name , name ):
1138+ if self .proto >= 3 :
1139+ # Non-ASCII identifiers are supported only with protocols >= 3.
1140+ self .write (GLOBAL + bytes (module_name , "utf-8" ) + b'\n ' +
1141+ bytes (name , "utf-8" ) + b'\n ' )
11181142 else :
11191143 if self .fix_imports :
11201144 r_name_mapping = _compat_pickle .REVERSE_NAME_MAPPING
@@ -1124,14 +1148,12 @@ def save_global(self, obj, name=None):
11241148 elif module_name in r_import_mapping :
11251149 module_name = r_import_mapping [module_name ]
11261150 try :
1127- write (GLOBAL + bytes (module_name , "ascii" ) + b'\n ' +
1128- bytes (name , "ascii" ) + b'\n ' )
1151+ self . write (GLOBAL + bytes (module_name , "ascii" ) + b'\n ' +
1152+ bytes (name , "ascii" ) + b'\n ' )
11291153 except UnicodeEncodeError :
11301154 raise PicklingError (
11311155 "can't pickle global identifier '%s.%s' using "
1132- "pickle protocol %i" % (module , name , self .proto )) from None
1133-
1134- self .memoize (obj )
1156+ "pickle protocol %i" % (module_name , name , self .proto )) from None
11351157
11361158 def save_type (self , obj ):
11371159 if obj is type (None ):
0 commit comments