-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Raise Python exceptions as Lisp (pyerror) errors and guard numpy import #3
base: master
Are you sure you want to change the base?
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 |
The big change with this pull request is to raise a Lisp
pyerror
when 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).