Test whether an function or a class should be pickled by reference Pickling by reference means by that the object (typically a function or a class) is an attribute of a module that is assumed to be importable in the target Python environment. Loading will therefore rely on importing the
(obj, name=None)
| 235 | |
| 236 | |
| 237 | def _should_pickle_by_reference(obj, name=None): |
| 238 | """Test whether an function or a class should be pickled by reference |
| 239 | |
| 240 | Pickling by reference means by that the object (typically a function or a |
| 241 | class) is an attribute of a module that is assumed to be importable in the |
| 242 | target Python environment. Loading will therefore rely on importing the |
| 243 | module and then calling `getattr` on it to access the function or class. |
| 244 | |
| 245 | Pickling by reference is the only option to pickle functions and classes |
| 246 | in the standard library. In cloudpickle the alternative option is to |
| 247 | pickle by value (for instance for interactively or locally defined |
| 248 | functions and classes or for attributes of modules that have been |
| 249 | explicitly registered to be pickled by value. |
| 250 | """ |
| 251 | if isinstance(obj, types.FunctionType) or issubclass(type(obj), type): |
| 252 | module_and_name = _lookup_module_and_qualname(obj, name=name) |
| 253 | if module_and_name is None: |
| 254 | return False |
| 255 | module, name = module_and_name |
| 256 | return not _is_registered_pickle_by_value(module) |
| 257 | |
| 258 | elif isinstance(obj, types.ModuleType): |
| 259 | # We assume that sys.modules is primarily used as a cache mechanism for |
| 260 | # the Python import machinery. Checking if a module has been added in |
| 261 | # is sys.modules therefore a cheap and simple heuristic to tell us |
| 262 | # whether we can assume that a given module could be imported by name |
| 263 | # in another Python process. |
| 264 | if _is_registered_pickle_by_value(obj): |
| 265 | return False |
| 266 | return obj.__name__ in sys.modules |
| 267 | else: |
| 268 | raise TypeError( |
| 269 | "cannot check importability of {} instances".format(type(obj).__name__) |
| 270 | ) |
| 271 | |
| 272 | |
| 273 | def _lookup_module_and_qualname(obj, name=None): |
searching dependent graphs…