(self, obj, name=None)
| 1168 | dispatch[frozenset] = save_frozenset |
| 1169 | |
| 1170 | def save_global(self, obj, name=None): |
| 1171 | write = self.write |
| 1172 | |
| 1173 | if name is None: |
| 1174 | name = getattr(obj, '__qualname__', None) |
| 1175 | if name is None: |
| 1176 | name = obj.__name__ |
| 1177 | |
| 1178 | if '.__' in name: |
| 1179 | # Mangle names of private attributes. |
| 1180 | dotted_path = name.split('.') |
| 1181 | for i, subpath in enumerate(dotted_path): |
| 1182 | if i and subpath.startswith('__') and not subpath.endswith('__'): |
| 1183 | prev = prev.lstrip('_') |
| 1184 | if prev: |
| 1185 | dotted_path[i] = f"_{prev.lstrip('_')}{subpath}" |
| 1186 | prev = subpath |
| 1187 | name = '.'.join(dotted_path) |
| 1188 | |
| 1189 | module_name = whichmodule(obj, name) |
| 1190 | if self.proto >= 2: |
| 1191 | code = _extension_registry.get((module_name, name), _NoValue) |
| 1192 | if code is not _NoValue: |
| 1193 | if code <= 0xff: |
| 1194 | data = pack("<B", code) |
| 1195 | if data == b'\0': |
| 1196 | # Should never happen in normal circumstances, |
| 1197 | # since the type and the value of the code are |
| 1198 | # checked in copyreg.add_extension(). |
| 1199 | raise RuntimeError("extension code 0 is out of range") |
| 1200 | write(EXT1 + data) |
| 1201 | elif code <= 0xffff: |
| 1202 | write(EXT2 + pack("<H", code)) |
| 1203 | else: |
| 1204 | write(EXT4 + pack("<i", code)) |
| 1205 | return |
| 1206 | |
| 1207 | if self.proto >= 4: |
| 1208 | self.save(module_name) |
| 1209 | self.save(name) |
| 1210 | write(STACK_GLOBAL) |
| 1211 | elif '.' in name: |
| 1212 | # In protocol < 4, objects with multi-part __qualname__ |
| 1213 | # are represented as |
| 1214 | # getattr(getattr(..., attrname1), attrname2). |
| 1215 | dotted_path = name.split('.') |
| 1216 | name = dotted_path.pop(0) |
| 1217 | save = self.save |
| 1218 | for attrname in dotted_path: |
| 1219 | save(getattr) |
| 1220 | if self.proto < 2: |
| 1221 | write(MARK) |
| 1222 | self._save_toplevel_by_name(module_name, name) |
| 1223 | for attrname in dotted_path: |
| 1224 | save(attrname) |
| 1225 | if self.proto < 2: |
| 1226 | write(TUPLE) |
| 1227 | else: |
no test coverage detected