Raise Python exceptions as Lisp (pyerror) errors and guard numpy import#3
Raise Python exceptions as Lisp (pyerror) errors and guard numpy import#3plandes wants to merge 3 commits into
Conversation
fec1f35 to
0172782
Compare
|
Let me think if there's a better way to do this.
|
|
@digikar99 Sounds good. Maybe using a monitor on the Python side is a consideration, or even adding C code to catch Python syntax issues. Also, since I created the pull request I have noticed other methods silently discard Python side issues such as class Invoker(object):
def __init__(self, class_name: str, *args, **kwargs):
try:
ci = ClassImporter(class_name, False)
self._instance = ci.instance(class_name, *args, **kwargs)
self._args = (args, kwargs)
self._error = None
except Exception as e:
self._instance = None
self._args = None
self._error = e
def invoke(self, method_name: str, *args, **kwargs):
try:
meth: Callable = getattr(self._instance, method_name)
return meth(*args, **kwargs)
except Exception as e:
return ExecutionFailure(e)
def __str__(self):
return f'{self._instance.__class__}({self._args}), err: {self._error}'Then check the type and raise as a Lisp error: (defun python-maybe-raise-error (val)
(if (and (eq (type-of val) 'python-object)
(equal (slot-value val 'type)
"<class '__main__.ExecutionFailure'>"))
(error 'pyerror
:format-control (format nil "Python raised an exception:~%~a"
(pyslot-value val "stack"))
:exception-type (pyslot-value val "exception_type")
:exception-message (pyslot-value val "exception_message"))
val)) |
I can confirm that there definitely seems to be some bug. I will try to get it fixed soon. Thanks for reporting! |
|
9c65f0e should fix the pymethod not raising exceptions issue. |
|
ed6f6f8 should add support for capturing the python error even when raised in raw-py. I have incorporated your commit about importing sys and traceback before numpy, but I felt it better to capture the error output rather than modify how the output is sent to pyrun_simplestring. Modifying how the output is sent to pyrun_simplestring also requires guessing the indentation of the supplied code. |
|
@digikar99 OK I will test it soon. Regarding the indentation in Python: I do not believe it matters as long as it is consistent for the respective block. I also tested with different indentations. That said, I respect your decision in the change. Then I would argue for breaking out the handling of low level Python communication in a separate function, or even class, so it can be overridden. I might be missing something, but it appears these changes do not address error handling and recovery from raised Python exceptions. |
As long as we can detect it correctly, it should indeed be okay; but detection/guess-work would indeed be necessary.
Here I'm restricting the low level to whatever is provided by the Python's C-API. We can certainly subclass
Ah, okay! So, a big part of the most recent changes was restructuring how the output is read asynchronously from python, so that As for the errors that should be raised through |
e9ea92a to
e9b48b0
Compare
The big change with this pull request is to raise a Lisp
pyerrorwhen a Python error is raised. It does this by wrapping all evaluated code in a try catch that looks something like:Both the stack trace and the error are retained and available in the (modified)
pyerror. Example:produces:
For some unknown reason, I was not able to merge in the changes you made last night so I recreated my fork for this pull request (in case you were wondering or if there's any other git weirdness).