Nothing
context("exceptions")
test_that("py_last_error() returns R strings", {
skip_if_no_python()
tryCatch(py_eval("range(3)[3]"), error = identity)
er <- py_last_error()
expect_identical(er$type, "IndexError")
expect_type(er$value, "character")
expect_type(er$traceback, "character")
expect_type(er$message, "character")
})
test_that("py_last_error() returns the R error condition object", {
skip_if_no_python()
signal_simple_error <- function() {
stop("Hello signal_simple_error")
}
raise_py_exception <- function() {
py_run_string("raise RuntimeError('Hello raise_py_exception')")
}
signal_py_exception <- function() {
stop(import_builtins()$RuntimeError("Hello signal_py_exception"))
}
f1 <- py_func(signal_simple_error)
f2 <- py_func(function() f1())
f3 <- py_func(function() f2())
f4 <- py_func(function() f3())
g1 <- py_func(raise_py_exception)
g2 <- py_func(function() g1())
g3 <- py_func(function() g2())
g4 <- py_func(function() g3())
h1 <- py_func(signal_py_exception)
h2 <- py_func(function() h1())
h3 <- py_func(function() h2())
h4 <- py_func(function() h3())
for (fn in list(f1, f2, f3, f4,
g1, g2, g3, g4,
h1, h2, h3, h4)) {
e <- tryCatch( fn(), error = function(e) e )
for (cls in c("python.builtin.Exception",
"python.builtin.BaseException",
"python.builtin.object",
"error", "condition"))
expect_s3_class(e, cls)
expect_identical(conditionMessage(e), e$message)
expect_identical(conditionCall(e), e$call)
expect_match(conditionMessage(e), "Hello")
expect_type(conditionCall(e), "language")
expect_s3_class(e$trace, "data.frame")
expect_s3_class(e$trace, "rlang_trace")
}
# test that py_last_error() reports full r_trace
# even if python discards the exception object
catch_and_replace_exception <- py_run_string("
def catch_and_replace_exception(fn):
try:
fn()
except:
raise RuntimeError('''It's a mystery!''')
")$catch_and_replace_exception
catch_clear_errstatus_then_raise_new_exception <- py_run_string("
def catch_clear_errstatus_then_raise_new_exception(fn):
failed = False
try:
res = fn()
except:
failed = True
if failed:
raise RuntimeError('''It's a mystery!''')
return res
")$catch_clear_errstatus_then_raise_new_exception
expect_match2 <- expect_match
formals(expect_match2)$fixed <- TRUE
formals(expect_match2)$all <- FALSE
for (erroring_fn in list(signal_simple_error,
raise_py_exception,
signal_py_exception)) {
f1 <- py_func(erroring_fn)
f2 <- py_func(function() f1())
f3 <- py_func(function() catch_and_replace_exception(f2))
f4 <- py_func(function() f3())
f5 <- py_func(function() f4())
e <- tryCatch(f5(), error = identity)
expect_s3_class(e$trace, "data.frame")
expect_s3_class(e$trace, "rlang_trace")
output <- suppressMessages(capture.output(print(reticulate::py_last_error())))
expect_match2(output, "Hello")
expect_match2(output, "It's a mystery!")
expect_match2(output, "f1()")
expect_match2(output, "catch_and_replace_exception(f2)")
expect_match2(output, "f3()")
expect_match2(output, "f4()")
expect_match2(output, "f5()")
f1 <- py_func(erroring_fn)
f2 <- py_func(function() f1())
f3 <- py_func(function() catch_clear_errstatus_then_raise_new_exception(f2))
f4 <- py_func(function() f3())
f5 <- py_func(function() f4())
e <- tryCatch(f5(), error = identity)
expect_s3_class(e$trace, "data.frame")
expect_s3_class(e$trace, "rlang_trace")
output <- suppressMessages(capture.output(print(reticulate::py_last_error())))
expect_match2(output, "It's a mystery!") # python code made it a mystery
expect_match2(output, "Hello") # we make it not a mystery by providing the R trace
expect_match2(output, "f1()")
expect_match2(output, "catch_clear_errstatus_then_raise_new_exception(f2)")
expect_match2(output, "f3()")
expect_match2(output, "f4()")
expect_match2(output, "f5()")
}
})
test_that("confirm rlang/purrr can catch the exception", {
skip_if_no_python()
cnd <- tryCatch(
py_run_string("raise ZeroDivisionError"),
error = identity
)
# we already Suggests on rlang
expect_equal(rlang::cnd_type(cnd), "error")
# don't want to Suggests on purrr
requireNamespace_ <- requireNamespace
if (requireNamespace_("purrr", quietly = TRUE)) {
expect_error({
map <- yoink("purrr", "map")
map(1:3, function(i)
if (i == 2)
reticulate::py_run_string("raise Exception('fooobaar')"))
}, regexp = "In index: 2.*fooobaar")
}
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.