Closed t-kalinowski closed 10 months ago
purrr::map(1:2, \(i) reticulate::py_eval("raise Exception()")) #> Error in `cnd_type()`: #> ! `cnd` is not a condition object. #> Backtrace: #> ▆ #> 1. ├─purrr::map(1:2, function(i) reticulate::py_eval("raise Exception()")) #> 2. │ └─purrr:::map_("list", .x, .f, ..., .progress = .progress) #> 3. │ ├─purrr:::with_indexed_errors(...) #> 4. │ │ └─base::withCallingHandlers(...) #> 5. │ ├─purrr:::call_with_cleanup(...) #> 6. │ └─global .f(.x[[i]], ...) #> 7. │ └─reticulate::py_eval("raise Exception()") #> 8. │ └─reticulate:::py_eval_impl(code, convert) at reticulate/R/python.R:1319:3 #> 9. ├─base::stop(`<python.builtin.SyntaxError>`) at reticulate/R/RcppExports.R:226:5 #> 10. ├─purrr (local) `<fn>`(`<python.builtin.SyntaxError>`) #> 11. │ └─cli::cli_abort(...) #> 12. │ └─rlang::abort(...) #> 13. │ └─rlang:::signal_abort(cnd, .file) #> 14. │ └─base::signalCondition(cnd) #> 15. │ ├─base::conditionMessage(cond) #> 16. │ └─rlang:::conditionMessage.rlang_error(cond) #> 17. │ └─rlang::cnd_message(c) #> 18. │ └─rlang:::cnd_message_format_prefixed(cnd, parent = TRUE, warning = warning) #> 19. │ └─rlang::cnd_type(cnd) #> 20. └─rlang::abort(message = message)
Compare w/ base lapply
lapply(1:2, \(i) reticulate::py_eval("raise Exception()")) #> invalid syntax (reticulate_eval, line 1)
Actually, reprex appears to change the way exceptions are presented, this is what I actually see in Console:
> lapply(1:2, \(i) reticulate::py_eval("raise Exception()")) Error in py_eval_impl(code, convert) : File "reticulate_eval", line 1 raise Exception() ^^^^^ SyntaxError: invalid syntax Run `reticulate::py_last_error()` for details.
The exception object from reticulate is a valid condition, it fulfills the condition contract, it just has more stuff.
condition
e <- tryCatch(reticulate::py_eval("raise Exception()"), error = identity) class(e) #> [1] "python.builtin.SyntaxError" "python.builtin.Exception" #> [3] "python.builtin.BaseException" "python.builtin.object" #> [5] "error" "condition" conditionMessage(e) #> [1] " File \"reticulate_eval\", line 1\n raise Exception()\n ^^^^^\nSyntaxError: invalid syntax\nRun `reticulate::py_last_error()` for details." e$message #> [1] " File \"reticulate_eval\", line 1\n raise Exception()\n ^^^^^\nSyntaxError: invalid syntax\nRun `reticulate::py_last_error()` for details." conditionCall(e) #> py_eval_impl(code, convert) e$call #> py_eval_impl(code, convert) e #> SyntaxError('invalid syntax', ('reticulate_eval', 1, 1, 'raise Exception()', 1, 6)) typeof(e) #> [1] "environment" names(e) #> [1] "args" "call" "end_lineno" #> [4] "end_offset" "filename" "lineno" #> [7] "msg" "offset" "print_file_and_line" #> [10] "text" "trace" "with_traceback" # The actual error comes from rlang::cnd_type() rlang::cnd_type(e) #> Error in `rlang::cnd_type()`: #> ! `cnd` is not a condition object. #> Backtrace: #> ▆ #> 1. ├─rlang::cnd_type(e) #> 2. └─rlang::abort(message = message)
Created on 2023-10-13 with reprex v2.0.2
https://github.com/r-lib/rlang/blob/7a78dc3f0d5b2fb73289f820e39afb5c4d665802/src/internal/exported.c#L28-L38
Moving to rlang since it looks like the fix is needed there.
...
Oh I can't move it automatically; moving manually instead.
Compare w/ base lapply
Actually, reprex appears to change the way exceptions are presented, this is what I actually see in Console:
The exception object from reticulate is a valid
condition
, it fulfills the condition contract, it just has more stuff.Created on 2023-10-13 with reprex v2.0.2
https://github.com/r-lib/rlang/blob/7a78dc3f0d5b2fb73289f820e39afb5c4d665802/src/internal/exported.c#L28-L38