r"""Wraps an exception plus traceback to communicate across threads
| 26 | |
| 27 | |
| 28 | class ExceptionWrapper(object): |
| 29 | r"""Wraps an exception plus traceback to communicate across threads""" |
| 30 | |
| 31 | def __init__(self, exc_info=None, where="in background"): |
| 32 | # It is important that we don't store exc_info, see |
| 33 | # NOTE [ Python Traceback Reference Cycle Problem ] |
| 34 | if exc_info is None: |
| 35 | exc_info = sys.exc_info() |
| 36 | self.exc_type = exc_info[0] |
| 37 | self.exc_msg = "".join(traceback.format_exception(*exc_info)) |
| 38 | self.where = where |
| 39 | |
| 40 | def reraise(self): |
| 41 | r"""Reraises the wrapped exception in the current thread""" |
| 42 | # Format a message such as: "Caught ValueError in DataLoader worker |
| 43 | # process 2. Original Traceback:", followed by the traceback. |
| 44 | msg = "Caught {} {}.\nOriginal {}".format( |
| 45 | self.exc_type.__name__, self.where, self.exc_msg |
| 46 | ) |
| 47 | if self.exc_type == KeyError: |
| 48 | # KeyError calls repr() on its argument (usually a dict key). This |
| 49 | # makes stack traces unreadable. It will not be changed in Python |
| 50 | # (https://bugs.python.org/issue2651), so we work around it. |
| 51 | msg = KeyErrorMessage(msg) |
| 52 | elif getattr(self.exc_type, "message", None): |
| 53 | # Some exceptions have first argument as non-str but explicitly |
| 54 | # have message field |
| 55 | raise self.exc_type(message=msg) |
| 56 | raise self.exc_type(msg) |
| 57 | |
| 58 | |
| 59 | def _flatten_dense_tensors(tensors): |
no outgoing calls
no test coverage detected