From dd6c8de3787cf9238fd6bcb8d654452a55288519 Mon Sep 17 00:00:00 2001 From: Tomasz Kalinowski Date: Fri, 7 Mar 2025 08:28:52 -0500 Subject: [PATCH] fix coerce in `py_slice()` --- src/python.cpp | 28 ++++++++++++++------ tests/testthat/test-python-base-r-generics.R | 2 +- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/python.cpp b/src/python.cpp index cbdd0242..fccded54 100644 --- a/src/python.cpp +++ b/src/python.cpp @@ -4619,22 +4619,34 @@ PyObjectRef py_capsule(SEXP x) { PyObjectRef py_slice(SEXP start = R_NilValue, SEXP stop = R_NilValue, SEXP step = R_NilValue) { GILScope _gil; - PyObjectPtr start_, stop_, step_; + auto coerce_slice_arg = [](SEXP x) -> PyObject* { + if (x == R_NilValue) { + return NULL; + } + if (TYPEOF(x) == INTSXP || TYPEOF(x) == REALSXP) { + return PyLong_FromLong(Rf_asInteger(x)); + } + if (is_py_object(x)) { + PyObject* pyobj = PyObjectRef(x, false).get(); + Py_IncRef(pyobj); + return pyobj; + } + return r_to_py(x, false); + }; - if (start != R_NilValue) - start_.assign(PyLong_FromLong(Rf_asInteger(start))); - if (stop != R_NilValue) - stop_.assign(PyLong_FromLong(Rf_asInteger(stop))); - if (step != R_NilValue) - step_.assign(PyLong_FromLong(Rf_asInteger(step))); + PyObjectPtr start_(coerce_slice_arg(start)); + PyObjectPtr stop_(coerce_slice_arg(stop)); + PyObjectPtr step_(coerce_slice_arg(step)); - PyObject* out(PySlice_New(start_, stop_, step_)); + PyObject* out = PySlice_New(start_, stop_, step_); if (out == NULL) throw PythonException(py_fetch_error()); + return py_ref(out, false); } + //' @rdname iterate //' @export // [[Rcpp::export]] diff --git a/tests/testthat/test-python-base-r-generics.R b/tests/testthat/test-python-base-r-generics.R index c2858786..c011d492 100644 --- a/tests/testthat/test-python-base-r-generics.R +++ b/tests/testthat/test-python-base-r-generics.R @@ -173,7 +173,7 @@ test_that("[ can infer slices, multiple args", { test_that("[ passes through python objects", { - skip_if_no_numpy("numpy") + skip_if_no_numpy() np <- import("numpy", convert = FALSE)