Get the object wrapped by *func*. Follows the chain of :attr:`__wrapped__` attributes returning the last object in the chain. *stop* is an optional callback accepting an object in the wrapper chain as its sole argument that allows the unwrapping to be terminated early if the callbac
(func, *, stop=None)
| 661 | # -------------------------------------------------------- function helpers |
| 662 | |
| 663 | def unwrap(func, *, stop=None): |
| 664 | """Get the object wrapped by *func*. |
| 665 | |
| 666 | Follows the chain of :attr:`__wrapped__` attributes returning the last |
| 667 | object in the chain. |
| 668 | |
| 669 | *stop* is an optional callback accepting an object in the wrapper chain |
| 670 | as its sole argument that allows the unwrapping to be terminated early if |
| 671 | the callback returns a true value. If the callback never returns a true |
| 672 | value, the last object in the chain is returned as usual. For example, |
| 673 | :func:`signature` uses this to stop unwrapping if any object in the |
| 674 | chain has a ``__signature__`` attribute defined. |
| 675 | |
| 676 | :exc:`ValueError` is raised if a cycle is encountered. |
| 677 | |
| 678 | """ |
| 679 | f = func # remember the original func for error reporting |
| 680 | # Memoise by id to tolerate non-hashable objects, but store objects to |
| 681 | # ensure they aren't destroyed, which would allow their IDs to be reused. |
| 682 | memo = {id(f): f} |
| 683 | recursion_limit = sys.getrecursionlimit() |
| 684 | while not isinstance(func, type) and hasattr(func, '__wrapped__'): |
| 685 | if stop is not None and stop(func): |
| 686 | break |
| 687 | func = func.__wrapped__ |
| 688 | id_func = id(func) |
| 689 | if (id_func in memo) or (len(memo) >= recursion_limit): |
| 690 | raise ValueError('wrapper loop when unwrapping {!r}'.format(f)) |
| 691 | memo[id_func] = func |
| 692 | return func |
| 693 | |
| 694 | # -------------------------------------------------- source code extraction |
| 695 | def indentsize(line): |
no test coverage detected
searching dependent graphs…