From 563342ed821e2d8e6355683d88c7299b43caa3ca Mon Sep 17 00:00:00 2001 From: pfackeldey Date: Sun, 15 Dec 2024 12:09:54 -0500 Subject: [PATCH 1/8] fix stacktraces for custom exception handling --- src/awkward/_errors.py | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/src/awkward/_errors.py b/src/awkward/_errors.py index a6efa8f04b..9cd5891607 100644 --- a/src/awkward/_errors.py +++ b/src/awkward/_errors.py @@ -75,25 +75,18 @@ def __enter__(self): self._slate.__dict__["__primary_context__"] = self def __exit__(self, exception_type, exception_value, traceback): - try: + if ( + exception_type is not None + and issubclass(exception_type, Exception) + and self.primary() is self + ): # Handle caught exception - if ( - exception_type is not None - and issubclass(exception_type, Exception) - and self.primary() is self - ): - self.handle_exception(exception_type, exception_value) - finally: + raise self.decorate_exception(exception_type, exception_value) from exception_value + else: # Step out of the way so that another ErrorContext can become primary. if self.primary() is self: self._slate.__dict__.clear() - def handle_exception(self, cls: type[E], exception: E): - if sys.version_info >= (3, 11, 0, "final"): - self.decorate_exception(cls, exception) - else: - raise self.decorate_exception(cls, exception) - def decorate_exception(self, cls: type[E], exception: E) -> Exception: if sys.version_info >= (3, 11, 0, "final"): if issubclass(cls, (NotImplementedError, AssertionError)): @@ -111,13 +104,10 @@ def decorate_exception(self, cls: type[E], exception: E) -> Exception: str(exception) + "\n\nSee if this has been reported at https://github.com/scikit-hep/awkward/issues" ) - new_exception.__cause__ = exception elif issubclass(cls, builtins.KeyError): new_exception = KeyError(self.format_exception(exception)) - new_exception.__cause__ = exception else: new_exception = cls(self.format_exception(exception)) - new_exception.__cause__ = exception return new_exception def format_argument(self, width, value): From 7de3767d6d48ca71d2fd6870e5361fe234bd4dfc Mon Sep 17 00:00:00 2001 From: pfackeldey Date: Sun, 15 Dec 2024 12:20:10 -0500 Subject: [PATCH 2/8] reset _slate in __exit__ in any case --- src/awkward/_errors.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/awkward/_errors.py b/src/awkward/_errors.py index 9cd5891607..e3c630013f 100644 --- a/src/awkward/_errors.py +++ b/src/awkward/_errors.py @@ -80,6 +80,9 @@ def __exit__(self, exception_type, exception_value, traceback): and issubclass(exception_type, Exception) and self.primary() is self ): + # Step out of the way so that another ErrorContext can become primary. + # Is this necessary to do here? (We're about to raise an exception anyway) + self._slate.__dict__.clear() # Handle caught exception raise self.decorate_exception(exception_type, exception_value) from exception_value else: From b3594faedb38cbb3abfbea3efde746917b07d809 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 15 Dec 2024 17:21:24 +0000 Subject: [PATCH 3/8] style: pre-commit fixes --- src/awkward/_errors.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/awkward/_errors.py b/src/awkward/_errors.py index e3c630013f..1a971ab507 100644 --- a/src/awkward/_errors.py +++ b/src/awkward/_errors.py @@ -84,7 +84,9 @@ def __exit__(self, exception_type, exception_value, traceback): # Is this necessary to do here? (We're about to raise an exception anyway) self._slate.__dict__.clear() # Handle caught exception - raise self.decorate_exception(exception_type, exception_value) from exception_value + raise self.decorate_exception( + exception_type, exception_value + ) from exception_value else: # Step out of the way so that another ErrorContext can become primary. if self.primary() is self: From a5b2e5d0f3fbb450ac1524ce9a8cc1a6af000552 Mon Sep 17 00:00:00 2001 From: pfackeldey Date: Sun, 15 Dec 2024 13:22:20 -0500 Subject: [PATCH 4/8] properly use exception notes instead of exception chaining --- src/awkward/_errors.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/awkward/_errors.py b/src/awkward/_errors.py index 1a971ab507..b13e38183e 100644 --- a/src/awkward/_errors.py +++ b/src/awkward/_errors.py @@ -84,9 +84,7 @@ def __exit__(self, exception_type, exception_value, traceback): # Is this necessary to do here? (We're about to raise an exception anyway) self._slate.__dict__.clear() # Handle caught exception - raise self.decorate_exception( - exception_type, exception_value - ) from exception_value + raise self.decorate_exception(exception_type, exception_value) else: # Step out of the way so that another ErrorContext can become primary. if self.primary() is self: @@ -102,18 +100,15 @@ def decorate_exception(self, cls: type[E], exception: E) -> Exception: exception.add_note(self.note) return exception else: - new_exception: Exception if issubclass(cls, (NotImplementedError, AssertionError)): - # Raise modified exception - new_exception = cls( - str(exception) - + "\n\nSee if this has been reported at https://github.com/scikit-hep/awkward/issues" - ) + note = "\n\nSee if this has been reported at https://github.com/scikit-hep/awkward/issues" + exception.__notes__ = [note] elif issubclass(cls, builtins.KeyError): - new_exception = KeyError(self.format_exception(exception)) + exception: Exception = KeyError(self.format_exception(exception)) + exception.__notes__ = [self.note] else: - new_exception = cls(self.format_exception(exception)) - return new_exception + exception.__notes__ = [self.note] + return exception def format_argument(self, width, value): from awkward import contents, highlevel, record From 27f870f017ec0f4a6e685b6e9e9479ac744f6fc9 Mon Sep 17 00:00:00 2001 From: pfackeldey Date: Sun, 15 Dec 2024 13:36:22 -0500 Subject: [PATCH 5/8] simplify; KeyError subclassing not needed anymore with __notes__ usage --- src/awkward/_errors.py | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/src/awkward/_errors.py b/src/awkward/_errors.py index b13e38183e..aeaf3893e1 100644 --- a/src/awkward/_errors.py +++ b/src/awkward/_errors.py @@ -51,11 +51,6 @@ def __call__(self): return self.func(*self.args, **self.kwargs) -class KeyError(builtins.KeyError): - def __str__(self): - return super(Exception, self).__str__() - - class ErrorContext: # Any other threads should get a completely independent _slate. _slate = threading.local() @@ -91,25 +86,18 @@ def __exit__(self, exception_type, exception_value, traceback): self._slate.__dict__.clear() def decorate_exception(self, cls: type[E], exception: E) -> Exception: - if sys.version_info >= (3, 11, 0, "final"): - if issubclass(cls, (NotImplementedError, AssertionError)): - exception.add_note( - "\n\nSee if this has been reported at https://github.com/scikit-hep/awkward/issues" - ) + def _add_note(exception: E, note: str) -> E: + if sys.version_info >= (3, 11, 0, "final"): + exception.add_note(note) else: - exception.add_note(self.note) - return exception - else: - if issubclass(cls, (NotImplementedError, AssertionError)): - note = "\n\nSee if this has been reported at https://github.com/scikit-hep/awkward/issues" exception.__notes__ = [note] - elif issubclass(cls, builtins.KeyError): - exception: Exception = KeyError(self.format_exception(exception)) - exception.__notes__ = [self.note] - else: - exception.__notes__ = [self.note] return exception + note = self.note + if issubclass(cls, (NotImplementedError, AssertionError)): + note = "\n\nSee if this has been reported at https://github.com/scikit-hep/awkward/issues" + return _add_note(exception, note) + def format_argument(self, width, value): from awkward import contents, highlevel, record From d9f4ea2ae575853dbd40aa3ca80ee3933fed3c21 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 15 Dec 2024 18:36:53 +0000 Subject: [PATCH 6/8] style: pre-commit fixes --- src/awkward/_errors.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/awkward/_errors.py b/src/awkward/_errors.py index aeaf3893e1..46a93a3e4d 100644 --- a/src/awkward/_errors.py +++ b/src/awkward/_errors.py @@ -2,7 +2,6 @@ from __future__ import annotations -import builtins import sys import threading import warnings From 33b176379c12bdf87988b7c8977b75e3fab50fa2 Mon Sep 17 00:00:00 2001 From: Peter Fackeldey Date: Mon, 16 Dec 2024 12:37:50 -0500 Subject: [PATCH 7/8] better check for `exception.add_note` availability Co-authored-by: Jim Pivarski --- src/awkward/_errors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/awkward/_errors.py b/src/awkward/_errors.py index 46a93a3e4d..fd97acd9f4 100644 --- a/src/awkward/_errors.py +++ b/src/awkward/_errors.py @@ -86,7 +86,7 @@ def __exit__(self, exception_type, exception_value, traceback): def decorate_exception(self, cls: type[E], exception: E) -> Exception: def _add_note(exception: E, note: str) -> E: - if sys.version_info >= (3, 11, 0, "final"): + if hasattr(exception, "add_note"): exception.add_note(note) else: exception.__notes__ = [note] From b109c939d19289e1d224d53d45f03cf2ae6693cb Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 17:38:14 +0000 Subject: [PATCH 8/8] style: pre-commit fixes --- src/awkward/_errors.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/awkward/_errors.py b/src/awkward/_errors.py index fd97acd9f4..2ce5e3a2c7 100644 --- a/src/awkward/_errors.py +++ b/src/awkward/_errors.py @@ -2,7 +2,6 @@ from __future__ import annotations -import sys import threading import warnings from collections.abc import Callable, Collection, Iterable, Mapping