traceback.py 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import traceback
  2. from contextlib import contextmanager
  3. from typing import List, Any, Dict
  4. from ._compatibility import compatibility
  5. __all__ = ['preserve_node_meta', 'has_preserved_node_meta',
  6. 'set_stack_trace', 'format_stack',
  7. 'set_current_meta', 'get_current_meta']
  8. current_meta: Dict[str, Any] = {}
  9. should_preserve_node_meta = False
  10. @compatibility(is_backward_compatible=False)
  11. @contextmanager
  12. def preserve_node_meta():
  13. global should_preserve_node_meta
  14. saved_should_preserve_node_meta = should_preserve_node_meta
  15. try:
  16. should_preserve_node_meta = True
  17. yield
  18. finally:
  19. should_preserve_node_meta = saved_should_preserve_node_meta
  20. @compatibility(is_backward_compatible=False)
  21. def set_stack_trace(stack : List[str]):
  22. global current_meta
  23. if should_preserve_node_meta and stack:
  24. current_meta["stack_trace"] = "".join(stack)
  25. @compatibility(is_backward_compatible=False)
  26. def format_stack() -> List[str]:
  27. if should_preserve_node_meta:
  28. return [current_meta.get("stack_trace", "")]
  29. else:
  30. # fallback to traceback.format_stack()
  31. return traceback.format_list(traceback.extract_stack()[:-1])
  32. @compatibility(is_backward_compatible=False)
  33. def has_preserved_node_meta() -> bool:
  34. return should_preserve_node_meta
  35. @compatibility(is_backward_compatible=False)
  36. @contextmanager
  37. def set_current_meta(meta : Dict[str, Any]):
  38. global current_meta
  39. if should_preserve_node_meta and meta:
  40. saved_meta = current_meta
  41. try:
  42. current_meta = meta
  43. yield
  44. finally:
  45. current_meta = saved_meta
  46. else:
  47. yield
  48. @compatibility(is_backward_compatible=False)
  49. def get_current_meta() -> Dict[str, Any]:
  50. return current_meta.copy()