From 5b74ba09dc48c734ffeb4414a95a53a046fa45f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Cs=C3=A1rdi?= Date: Mon, 17 Feb 2025 10:49:36 +0100 Subject: [PATCH] Test write_parquet() temporal types w/ Python polars --- .github/workflows/R-CMD-check.yaml | 4 +-- .github/workflows/test-coverage.yaml | 4 +-- tests/testthat/helper.R | 19 ++++++++++++ tests/testthat/test-pypolars.R | 46 ++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 tests/testthat/test-pypolars.R diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 0839064..1a19309 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -58,9 +58,9 @@ jobs: "~/.pip/pip.conf" ) if (Sys.which("pip3") != "") { - system("pip3 install pyarrow pandas") + system("pip3 install pyarrow pandas polars") } else { - system("pip install pyarrow pandas") + system("pip install pyarrow pandas polars") } shell: Rscript {0} diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index 76e2b62..33141a1 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -32,9 +32,9 @@ jobs: "~/.pip/pip.conf" ) if (Sys.which("pip3") != "") { - system("pip3 install pyarrow pandas") + system("pip3 install pyarrow pandas polars") } else { - system("pip install pyarrow pandas") + system("pip install pyarrow pandas polars") } shell: Rscript {0} diff --git a/tests/testthat/helper.R b/tests/testthat/helper.R index 50eff89..7afb624 100644 --- a/tests/testthat/helper.R +++ b/tests/testthat/helper.R @@ -18,6 +18,25 @@ skip_without_pyarrow <- function() { } } +skip_without_polars <- function() { + skip_on_cran() + if (tolower(Sys.getenv("_R_CHECK_FORCE_SUGGESTS_")) != "false") return() + pyscript <- r"[ + import polars + ]" + pytmp <- tempfile(fileext = ".py") + on.exit(unlink(pytmp), add = TRUE) + writeLines(pyscript, pytmp) + py <- if (Sys.which("python3") != "") "python3" else "python" + res <- tryCatch( + processx::run(py, pytmp, stderr = "2>&1"), + error = function(err) err + ) + if (inherits(res, "error")) { + skip("missing polars in Python") + } +} + skip_without <- function(pkgs) { if (any(c("arrow", "duckdb") %in% pkgs)) skip_on_cran() if (tolower(Sys.getenv("_R_CHECK_FORCE_SUGGESTS_")) != "false") return() diff --git a/tests/testthat/test-pypolars.R b/tests/testthat/test-pypolars.R new file mode 100644 index 0000000..ada9947 --- /dev/null +++ b/tests/testthat/test-pypolars.R @@ -0,0 +1,46 @@ +test_that("polars can read temporal types", { + skip_without_polars() + + tmp <- tempfile(fileext = ".parquet") + on.exit(unlink(tmp), add = TRUE) + + do <- function(df, path = tmp) { + write_parquet(df, path) + pyscript <- sprintf(r"[ +import polars as pl +pl.read_parquet("%s") + ]", normalizePath(path, winslash = "/")) + pytmp <- tempfile(fileext = ".py") + on.exit(unlink(pytmp), add = TRUE) + writeLines(pyscript, pytmp) + py <- if (Sys.which("python3") != "") "python3" else "python" + processx::run(py, pytmp, stderr = "2>&1") + } + + # Date + df_date <- data.frame(x = Sys.Date()) + expect_silent(do(df_date)) + + # hms, integer + # it is unclear if this ever comes up in practice + df_hmsi <- data.frame( + x = structure(0L, units = "secs", class = c("hms", "difftime")) + ) + expect_silent(do(df_hmsi)) + + # hms, double + df_hmsd <- data.frame(x = hms::hms(0)) + expect_silent(do(df_hmsd)) + + # difftime + df_difftime <- data.frame(x = as.difftime(1, units = "secs")) + expect_silent(do(df_difftime)) + + # POSIXct + df_posixct <- data.frame(x = Sys.time()) + expect_silent(do(df_posixct)) + + # factor + df_factor <- data.frame(x = as.factor(c("a", "a"))) + expect_silent(do(df_factor)) +})