Find the module an object belong to.
(obj, name)
| 334 | return obj |
| 335 | |
| 336 | def whichmodule(obj, name): |
| 337 | """Find the module an object belong to.""" |
| 338 | dotted_path = name.split('.') |
| 339 | module_name = getattr(obj, '__module__', None) |
| 340 | if '<locals>' in dotted_path: |
| 341 | raise PicklingError(f"Can't pickle local object {obj!r}") |
| 342 | if module_name is None: |
| 343 | # Protect the iteration by using a list copy of sys.modules against dynamic |
| 344 | # modules that trigger imports of other modules upon calls to getattr. |
| 345 | for module_name, module in sys.modules.copy().items(): |
| 346 | if (module_name == '__main__' |
| 347 | or module_name == '__mp_main__' # bpo-42406 |
| 348 | or module is None): |
| 349 | continue |
| 350 | try: |
| 351 | if _getattribute(module, dotted_path) is obj: |
| 352 | return module_name |
| 353 | except AttributeError: |
| 354 | pass |
| 355 | module_name = '__main__' |
| 356 | |
| 357 | try: |
| 358 | __import__(module_name, level=0) |
| 359 | module = sys.modules[module_name] |
| 360 | except (ImportError, ValueError, KeyError) as exc: |
| 361 | raise PicklingError(f"Can't pickle {obj!r}: {exc!s}") |
| 362 | try: |
| 363 | if _getattribute(module, dotted_path) is obj: |
| 364 | return module_name |
| 365 | except AttributeError: |
| 366 | raise PicklingError(f"Can't pickle {obj!r}: " |
| 367 | f"it's not found as {module_name}.{name}") |
| 368 | |
| 369 | raise PicklingError( |
| 370 | f"Can't pickle {obj!r}: it's not the same object as {module_name}.{name}") |
| 371 | |
| 372 | def encode_long(x): |
| 373 | r"""Encode a long to a two's complement little-endian binary string. |
no test coverage detected
searching dependent graphs…