From b3ca0d33a4339d111f53594946566832e4f7cfdc Mon Sep 17 00:00:00 2001 From: Etienne Bacher <52219252+etiennebacher@users.noreply.github.com> Date: Mon, 15 Apr 2024 11:14:51 +0200 Subject: [PATCH] Add `$is_*()` methods for datatypes (#1036) --- NEWS.md | 2 + R/datatype.R | 142 +++++++++++++++++++++++++++ R/extendr-wrappers.R | 30 ++++++ R/series__series.R | 2 - man/DataType_is_array.Rd | 18 ++++ man/DataType_is_binary.Rd | 18 ++++ man/DataType_is_bool.Rd | 18 ++++ man/DataType_is_float.Rd | 18 ++++ man/DataType_is_integer.Rd | 18 ++++ man/DataType_is_list.Rd | 18 ++++ man/DataType_is_logical.Rd | 14 +++ man/DataType_is_nested.Rd | 19 ++++ man/DataType_is_null.Rd | 18 ++++ man/DataType_is_numeric.Rd | 19 ++++ man/DataType_is_ord.Rd | 18 ++++ man/DataType_is_primitive.Rd | 18 ++++ man/DataType_is_signed_integer.Rd | 18 ++++ man/DataType_is_struct.Rd | 18 ++++ man/DataType_is_temporal.Rd | 18 ++++ man/DataType_is_unsigned_integer.Rd | 18 ++++ src/rust/src/rdatatype.rs | 60 +++++++++++ src/rust/src/rlib.rs | 8 +- tests/testthat/test-datatype.R | 42 ++++++++ tests/testthat/test-lazy_functions.R | 15 ++- 24 files changed, 575 insertions(+), 12 deletions(-) create mode 100644 man/DataType_is_array.Rd create mode 100644 man/DataType_is_binary.Rd create mode 100644 man/DataType_is_bool.Rd create mode 100644 man/DataType_is_float.Rd create mode 100644 man/DataType_is_integer.Rd create mode 100644 man/DataType_is_list.Rd create mode 100644 man/DataType_is_logical.Rd create mode 100644 man/DataType_is_nested.Rd create mode 100644 man/DataType_is_null.Rd create mode 100644 man/DataType_is_numeric.Rd create mode 100644 man/DataType_is_ord.Rd create mode 100644 man/DataType_is_primitive.Rd create mode 100644 man/DataType_is_signed_integer.Rd create mode 100644 man/DataType_is_struct.Rd create mode 100644 man/DataType_is_temporal.Rd create mode 100644 man/DataType_is_unsigned_integer.Rd diff --git a/NEWS.md b/NEWS.md index 84738e5f7..b19a2d9c7 100644 --- a/NEWS.md +++ b/NEWS.md @@ -182,6 +182,8 @@ - `$str$extract_groups()` (#979). - `$str$find()` (#985). - `$write_ipc()` (#1032). + - `RPolarsDataType` gains several methods to check the datatype, such as + `$is_integer()`, `$is_null()` or `$is_list()` (#1036). - New arguments or argument values: diff --git a/R/datatype.R b/R/datatype.R index ff777328a..c90fe24b7 100644 --- a/R/datatype.R +++ b/R/datatype.R @@ -361,3 +361,145 @@ DataType_List = function(datatype = "unknown") { DataType_Categorical = function(ordering = "physical") { .pr$DataType$new_categorical(ordering) |> unwrap() } + +#' Check whether the data type is a temporal type +#' +#' @return A logical value +#' +#' @examples +#' pl$Date$is_temporal() +#' pl$Float32$is_temporal() +DataType_is_temporal = use_extendr_wrapper + +#' Check whether the data type is a logical type +#' +#' @return A logical value +DataType_is_logical = use_extendr_wrapper + +#' Check whether the data type is a float type +#' +#' @inherit DataType_is_temporal return +#' +#' @examples +#' pl$Float32$is_float() +#' pl$Int32$is_float() +DataType_is_float = use_extendr_wrapper + +#' Check whether the data type is a numeric type +#' +#' @inherit DataType_is_temporal return +#' +#' @examples +#' pl$Float32$is_numeric() +#' pl$Int32$is_numeric() +#' pl$String$is_numeric() +DataType_is_numeric = use_extendr_wrapper + +#' Check whether the data type is an integer type +#' +#' @inherit DataType_is_temporal return +#' +#' @examples +#' pl$Int32$is_integer() +#' pl$Float32$is_integer() +DataType_is_integer = use_extendr_wrapper + +#' Check whether the data type is a signed integer type +#' +#' @inherit DataType_is_temporal return +#' +#' @examples +#' pl$Int32$is_signed_integer() +#' pl$UInt32$is_signed_integer() +DataType_is_signed_integer = use_extendr_wrapper + +#' Check whether the data type is an unsigned integer type +#' +#' @inherit DataType_is_temporal return +#' +#' @examples +#' pl$UInt32$is_unsigned_integer() +#' pl$Int32$is_unsigned_integer() +DataType_is_unsigned_integer = use_extendr_wrapper + +#' Check whether the data type is a null type +#' +#' @inherit DataType_is_temporal return +#' +#' @examples +#' pl$Null$is_null() +#' pl$Float32$is_null() +DataType_is_null = use_extendr_wrapper + +#' Check whether the data type is a binary type +#' +#' @inherit DataType_is_temporal return +#' +#' @examples +#' pl$Binary$is_binary() +#' pl$Float32$is_binary() +DataType_is_binary = use_extendr_wrapper + +#' Check whether the data type is a primitive type +#' +#' @inherit DataType_is_temporal return +#' +#' @examples +#' pl$Float32$is_primitive() +#' pl$List()$is_primitive() +DataType_is_primitive = use_extendr_wrapper + +#' Check whether the data type is a boolean type +#' +#' @inherit DataType_is_temporal return +#' +#' @examples +#' pl$Boolean$is_bool() +#' pl$Float32$is_bool() +DataType_is_bool = use_extendr_wrapper + +#' Check whether the data type is an array type +#' +#' @inherit DataType_is_temporal return +#' +#' @examples +#' pl$Array(width = 2)$is_array() +#' pl$Float32$is_array() +DataType_is_array = use_extendr_wrapper + +#' Check whether the data type is a list type +#' +#' @inherit DataType_is_temporal return +#' +#' @examples +#' pl$List()$is_list() +#' pl$Float32$is_list() +DataType_is_list = use_extendr_wrapper + +#' Check whether the data type is a nested type +#' +#' @inherit DataType_is_temporal return +#' +#' @examples +#' pl$List()$is_nested() +#' pl$Array(width = 2)$is_nested() +#' pl$Float32$is_nested() +DataType_is_nested = use_extendr_wrapper + +#' Check whether the data type is a temporal type +#' +#' @inherit DataType_is_temporal return +#' +#' @examples +#' pl$Struct()$is_struct() +#' pl$Float32$is_struct() +DataType_is_struct = use_extendr_wrapper + +#' Check whether the data type is an ordinal type +#' +#' @inherit DataType_is_temporal return +#' +#' @examples +#' pl$String$is_ord() +#' pl$Categorical()$is_ord() +DataType_is_ord = use_extendr_wrapper diff --git a/R/extendr-wrappers.R b/R/extendr-wrappers.R index 80d99652a..f45195176 100644 --- a/R/extendr-wrappers.R +++ b/R/extendr-wrappers.R @@ -302,6 +302,36 @@ RPolarsDataType$get_insides <- function() .Call(wrap__RPolarsDataType__get_insid RPolarsDataType$is_temporal <- function() .Call(wrap__RPolarsDataType__is_temporal, self) +RPolarsDataType$is_logical <- function() .Call(wrap__RPolarsDataType__is_logical, self) + +RPolarsDataType$is_float <- function() .Call(wrap__RPolarsDataType__is_float, self) + +RPolarsDataType$is_numeric <- function() .Call(wrap__RPolarsDataType__is_numeric, self) + +RPolarsDataType$is_integer <- function() .Call(wrap__RPolarsDataType__is_integer, self) + +RPolarsDataType$is_signed_integer <- function() .Call(wrap__RPolarsDataType__is_signed_integer, self) + +RPolarsDataType$is_unsigned_integer <- function() .Call(wrap__RPolarsDataType__is_unsigned_integer, self) + +RPolarsDataType$is_null <- function() .Call(wrap__RPolarsDataType__is_null, self) + +RPolarsDataType$is_binary <- function() .Call(wrap__RPolarsDataType__is_binary, self) + +RPolarsDataType$is_primitive <- function() .Call(wrap__RPolarsDataType__is_primitive, self) + +RPolarsDataType$is_bool <- function() .Call(wrap__RPolarsDataType__is_bool, self) + +RPolarsDataType$is_array <- function() .Call(wrap__RPolarsDataType__is_array, self) + +RPolarsDataType$is_list <- function() .Call(wrap__RPolarsDataType__is_list, self) + +RPolarsDataType$is_nested <- function() .Call(wrap__RPolarsDataType__is_nested, self) + +RPolarsDataType$is_struct <- function() .Call(wrap__RPolarsDataType__is_struct, self) + +RPolarsDataType$is_ord <- function() .Call(wrap__RPolarsDataType__is_ord, self) + #' @export `$.RPolarsDataType` <- function (self, name) { func <- RPolarsDataType[[name]]; environment(func) <- environment(); func } diff --git a/R/series__series.R b/R/series__series.R index ebb496884..45788cd0f 100644 --- a/R/series__series.R +++ b/R/series__series.R @@ -1108,8 +1108,6 @@ Series_item = function(index = NULL) { #' #' s$clear(n = 5) Series_clear = function(n = 0) { - # TODO: check whether n < 0 should be removed when resolved upstream - # https://github.com/pola-rs/polars/issues/15421 if (length(n) > 1 || !is.numeric(n) || n < 0) { Err_plain("`n` must be an integer greater or equal to 0.") |> unwrap("in $clear():") diff --git a/man/DataType_is_array.Rd b/man/DataType_is_array.Rd new file mode 100644 index 000000000..9eefd8b35 --- /dev/null +++ b/man/DataType_is_array.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/datatype.R +\name{DataType_is_array} +\alias{DataType_is_array} +\title{Check whether the data type is an array type} +\usage{ +DataType_is_array() +} +\value{ +A logical value +} +\description{ +Check whether the data type is an array type +} +\examples{ +pl$Array(width = 2)$is_array() +pl$Float32$is_array() +} diff --git a/man/DataType_is_binary.Rd b/man/DataType_is_binary.Rd new file mode 100644 index 000000000..662b61ce7 --- /dev/null +++ b/man/DataType_is_binary.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/datatype.R +\name{DataType_is_binary} +\alias{DataType_is_binary} +\title{Check whether the data type is a binary type} +\usage{ +DataType_is_binary() +} +\value{ +A logical value +} +\description{ +Check whether the data type is a binary type +} +\examples{ +pl$Binary$is_binary() +pl$Float32$is_binary() +} diff --git a/man/DataType_is_bool.Rd b/man/DataType_is_bool.Rd new file mode 100644 index 000000000..3804ea111 --- /dev/null +++ b/man/DataType_is_bool.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/datatype.R +\name{DataType_is_bool} +\alias{DataType_is_bool} +\title{Check whether the data type is a boolean type} +\usage{ +DataType_is_bool() +} +\value{ +A logical value +} +\description{ +Check whether the data type is a boolean type +} +\examples{ +pl$Boolean$is_bool() +pl$Float32$is_bool() +} diff --git a/man/DataType_is_float.Rd b/man/DataType_is_float.Rd new file mode 100644 index 000000000..14d73973d --- /dev/null +++ b/man/DataType_is_float.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/datatype.R +\name{DataType_is_float} +\alias{DataType_is_float} +\title{Check whether the data type is a float type} +\usage{ +DataType_is_float() +} +\value{ +A logical value +} +\description{ +Check whether the data type is a float type +} +\examples{ +pl$Float32$is_float() +pl$Int32$is_float() +} diff --git a/man/DataType_is_integer.Rd b/man/DataType_is_integer.Rd new file mode 100644 index 000000000..d530905d1 --- /dev/null +++ b/man/DataType_is_integer.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/datatype.R +\name{DataType_is_integer} +\alias{DataType_is_integer} +\title{Check whether the data type is an integer type} +\usage{ +DataType_is_integer() +} +\value{ +A logical value +} +\description{ +Check whether the data type is an integer type +} +\examples{ +pl$Int32$is_integer() +pl$Float32$is_integer() +} diff --git a/man/DataType_is_list.Rd b/man/DataType_is_list.Rd new file mode 100644 index 000000000..ce34889b2 --- /dev/null +++ b/man/DataType_is_list.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/datatype.R +\name{DataType_is_list} +\alias{DataType_is_list} +\title{Check whether the data type is a list type} +\usage{ +DataType_is_list() +} +\value{ +A logical value +} +\description{ +Check whether the data type is a list type +} +\examples{ +pl$List()$is_list() +pl$Float32$is_list() +} diff --git a/man/DataType_is_logical.Rd b/man/DataType_is_logical.Rd new file mode 100644 index 000000000..90111c016 --- /dev/null +++ b/man/DataType_is_logical.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/datatype.R +\name{DataType_is_logical} +\alias{DataType_is_logical} +\title{Check whether the data type is a logical type} +\usage{ +DataType_is_logical() +} +\value{ +A logical value +} +\description{ +Check whether the data type is a logical type +} diff --git a/man/DataType_is_nested.Rd b/man/DataType_is_nested.Rd new file mode 100644 index 000000000..d7d339f89 --- /dev/null +++ b/man/DataType_is_nested.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/datatype.R +\name{DataType_is_nested} +\alias{DataType_is_nested} +\title{Check whether the data type is a nested type} +\usage{ +DataType_is_nested() +} +\value{ +A logical value +} +\description{ +Check whether the data type is a nested type +} +\examples{ +pl$List()$is_nested() +pl$Array(width = 2)$is_nested() +pl$Float32$is_nested() +} diff --git a/man/DataType_is_null.Rd b/man/DataType_is_null.Rd new file mode 100644 index 000000000..6c600b003 --- /dev/null +++ b/man/DataType_is_null.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/datatype.R +\name{DataType_is_null} +\alias{DataType_is_null} +\title{Check whether the data type is a null type} +\usage{ +DataType_is_null() +} +\value{ +A logical value +} +\description{ +Check whether the data type is a null type +} +\examples{ +pl$Null$is_null() +pl$Float32$is_null() +} diff --git a/man/DataType_is_numeric.Rd b/man/DataType_is_numeric.Rd new file mode 100644 index 000000000..16046e950 --- /dev/null +++ b/man/DataType_is_numeric.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/datatype.R +\name{DataType_is_numeric} +\alias{DataType_is_numeric} +\title{Check whether the data type is a numeric type} +\usage{ +DataType_is_numeric() +} +\value{ +A logical value +} +\description{ +Check whether the data type is a numeric type +} +\examples{ +pl$Float32$is_numeric() +pl$Int32$is_numeric() +pl$String$is_numeric() +} diff --git a/man/DataType_is_ord.Rd b/man/DataType_is_ord.Rd new file mode 100644 index 000000000..bb7be2d65 --- /dev/null +++ b/man/DataType_is_ord.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/datatype.R +\name{DataType_is_ord} +\alias{DataType_is_ord} +\title{Check whether the data type is an ordinal type} +\usage{ +DataType_is_ord() +} +\value{ +A logical value +} +\description{ +Check whether the data type is an ordinal type +} +\examples{ +pl$String$is_ord() +pl$Categorical()$is_ord() +} diff --git a/man/DataType_is_primitive.Rd b/man/DataType_is_primitive.Rd new file mode 100644 index 000000000..ede825030 --- /dev/null +++ b/man/DataType_is_primitive.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/datatype.R +\name{DataType_is_primitive} +\alias{DataType_is_primitive} +\title{Check whether the data type is a primitive type} +\usage{ +DataType_is_primitive() +} +\value{ +A logical value +} +\description{ +Check whether the data type is a primitive type +} +\examples{ +pl$Float32$is_primitive() +pl$List()$is_primitive() +} diff --git a/man/DataType_is_signed_integer.Rd b/man/DataType_is_signed_integer.Rd new file mode 100644 index 000000000..8ec19ab26 --- /dev/null +++ b/man/DataType_is_signed_integer.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/datatype.R +\name{DataType_is_signed_integer} +\alias{DataType_is_signed_integer} +\title{Check whether the data type is a signed integer type} +\usage{ +DataType_is_signed_integer() +} +\value{ +A logical value +} +\description{ +Check whether the data type is a signed integer type +} +\examples{ +pl$Int32$is_signed_integer() +pl$UInt32$is_signed_integer() +} diff --git a/man/DataType_is_struct.Rd b/man/DataType_is_struct.Rd new file mode 100644 index 000000000..99006e03c --- /dev/null +++ b/man/DataType_is_struct.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/datatype.R +\name{DataType_is_struct} +\alias{DataType_is_struct} +\title{Check whether the data type is a temporal type} +\usage{ +DataType_is_struct() +} +\value{ +A logical value +} +\description{ +Check whether the data type is a temporal type +} +\examples{ +pl$Struct()$is_struct() +pl$Float32$is_struct() +} diff --git a/man/DataType_is_temporal.Rd b/man/DataType_is_temporal.Rd new file mode 100644 index 000000000..adc1330a7 --- /dev/null +++ b/man/DataType_is_temporal.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/datatype.R +\name{DataType_is_temporal} +\alias{DataType_is_temporal} +\title{Check whether the data type is a temporal type} +\usage{ +DataType_is_temporal() +} +\value{ +A logical value +} +\description{ +Check whether the data type is a temporal type +} +\examples{ +pl$Date$is_temporal() +pl$Float32$is_temporal() +} diff --git a/man/DataType_is_unsigned_integer.Rd b/man/DataType_is_unsigned_integer.Rd new file mode 100644 index 000000000..ce9704d68 --- /dev/null +++ b/man/DataType_is_unsigned_integer.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/datatype.R +\name{DataType_is_unsigned_integer} +\alias{DataType_is_unsigned_integer} +\title{Check whether the data type is an unsigned integer type} +\usage{ +DataType_is_unsigned_integer() +} +\value{ +A logical value +} +\description{ +Check whether the data type is an unsigned integer type +} +\examples{ +pl$UInt32$is_unsigned_integer() +pl$Int32$is_unsigned_integer() +} diff --git a/src/rust/src/rdatatype.rs b/src/rust/src/rdatatype.rs index cdb817d8b..375c63fa5 100644 --- a/src/rust/src/rdatatype.rs +++ b/src/rust/src/rdatatype.rs @@ -202,6 +202,66 @@ impl RPolarsDataType { pub fn is_temporal(&self) -> bool { self.0.is_temporal() } + + pub fn is_logical(&self) -> bool { + self.0.is_logical() + } + + pub fn is_float(&self) -> bool { + self.0.is_float() + } + + pub fn is_numeric(&self) -> bool { + self.0.is_numeric() + } + + pub fn is_integer(&self) -> bool { + self.0.is_integer() + } + + pub fn is_signed_integer(&self) -> bool { + self.0.is_signed_integer() + } + + pub fn is_unsigned_integer(&self) -> bool { + self.0.is_unsigned_integer() + } + + pub fn is_null(&self) -> bool { + self.0.is_null() + } + + pub fn is_binary(&self) -> bool { + self.0.is_binary() + } + + pub fn is_primitive(&self) -> bool { + self.0.is_primitive() + } + + pub fn is_bool(&self) -> bool { + self.0.is_bool() + } + + pub fn is_array(&self) -> bool { + self.0.is_array() + } + + pub fn is_list(&self) -> bool { + self.0.is_list() + } + + pub fn is_nested(&self) -> bool { + self.0.is_nested() + } + + pub fn is_struct(&self) -> bool { + self.0.is_struct() + } + + pub fn is_ord(&self) -> bool { + self.0.is_ord() + } } impl From for pl::DataType { diff --git a/src/rust/src/rlib.rs b/src/rust/src/rlib.rs index a3b9e71c6..b31edb78b 100644 --- a/src/rust/src/rlib.rs +++ b/src/rust/src/rlib.rs @@ -423,7 +423,13 @@ pub fn int_ranges(start: Robj, end: Robj, step: Robj, dtype: Robj) -> RResult as_polars_series(), - "non-integer `dtype`" + "non-integer `dtype` passed" ) expect_grepl_error( pl$int_range(0, 3, dtype = pl$Float32) |> as_polars_series(), - "non-integer `dtype`" + "non-integer `dtype` passed" ) # "step" works @@ -610,13 +610,10 @@ test_that("pl$int_ranges() works", { # ) # ) - # This one works with `pl$String` - # TODO: fix either this one or pl$int_range() - # https://github.com/pola-rs/polars/issues/15307 - # expect_grepl_error( - # df$select(int_range = pl$int_ranges("start", "end", dtype = pl$String)), - # "non-integer `dtype`" - # ) + expect_grepl_error( + df$select(int_range = pl$int_ranges("start", "end", dtype = pl$String)), + "non-integer `dtype` passed" + ) # "step" works expect_identical(