diff --git a/DESCRIPTION b/DESCRIPTION index 0f27d294a..feea8e169 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -118,5 +118,5 @@ Collate: 'zzz.R' Config/rextendr/version: 0.3.1 VignetteBuilder: knitr -Config/polars/LibVersion: 0.39.3 +Config/polars/LibVersion: 0.39.4 Config/polars/RustToolchainVersion: nightly-2024-04-15 diff --git a/R/expr__datetime.R b/R/expr__datetime.R index abcf84aeb..938e84448 100644 --- a/R/expr__datetime.R +++ b/R/expr__datetime.R @@ -535,21 +535,20 @@ ExprDT_nanosecond = function() { #' as_polars_series(as.Date("2022-1-1"))$dt$epoch("d") ExprDT_epoch = function(tu = c("us", "ns", "ms", "s", "d")) { tu = tu[1] + uw = \(res) unwrap(res, "in $dt$epoch:") # experimental rust-like error handling on R side for the fun of it, sorry # jokes aside here the use case is to tie various rust functions together # and add context to the error messages - expr_result = pcase( - !is_string(tu), Err("tu must be a string"), - tu %in% c("ms", "us", "ns"), .pr$Expr$timestamp(self, tu), - tu == "s", Ok(.pr$Expr$dt_epoch_seconds(self)), - tu == "d", Ok(self$cast(pl$Date)$cast(pl$Int32)), + pcase( + !is_string(tu), Err("tu must be a string") |> uw(), + tu %in% c("ms", "us", "ns"), .pr$Expr$dt_timestamp(self, tu) |> uw(), + tu == "s", .pr$Expr$dt_epoch_seconds(self), + tu == "d", self$cast(pl$Date)$cast(pl$Int32), or_else = Err( paste("tu must be one of 'ns', 'us', 'ms', 's', 'd', got", str_string(tu)) - ) - ) |> map_err(\(err) paste("in $dt$epoch:", err)) - - unwrap(expr_result) + ) |> uw() + ) } @@ -574,7 +573,7 @@ ExprDT_epoch = function(tu = c("us", "ns", "ms", "s", "d")) { #' pl$col("date")$dt$timestamp(tu = "ms")$alias("timestamp_ms") #' ) ExprDT_timestamp = function(tu = c("ns", "us", "ms")) { - .pr$Expr$timestamp(self, tu[1]) |> + .pr$Expr$dt_timestamp(self, tu[1]) |> map_err(\(err) paste("in $dt$timestamp:", err)) |> unwrap() } diff --git a/R/expr__meta.R b/R/expr__meta.R index c1f5f4fdc..7c62e289a 100644 --- a/R/expr__meta.R +++ b/R/expr__meta.R @@ -81,7 +81,7 @@ ExprMeta_pop = function() { #' e = (pl$col("alice") + pl$col("eve"))$alias("bob") #' e$meta$root_names() ExprMeta_root_names = function() { - .pr$Expr$meta_roots(self) + .pr$Expr$meta_root_names(self) } diff --git a/R/extendr-wrappers.R b/R/extendr-wrappers.R index ff5d5d890..2e13803f8 100644 --- a/R/extendr-wrappers.R +++ b/R/extendr-wrappers.R @@ -604,7 +604,7 @@ RPolarsExpr$rolling_median <- function(window_size, weights, min_periods, center RPolarsExpr$rolling_quantile <- function(quantile, interpolation, window_size, weights, min_periods, center, by, closed, warn_if_unsorted) .Call(wrap__RPolarsExpr__rolling_quantile, self, quantile, interpolation, window_size, weights, min_periods, center, by, closed, warn_if_unsorted) -RPolarsExpr$rolling_skew <- function(window_size_f, bias) .Call(wrap__RPolarsExpr__rolling_skew, self, window_size_f, bias) +RPolarsExpr$rolling_skew <- function(window_size, bias) .Call(wrap__RPolarsExpr__rolling_skew, self, window_size, bias) RPolarsExpr$abs <- function() .Call(wrap__RPolarsExpr__abs, self) @@ -820,7 +820,7 @@ RPolarsExpr$dt_microsecond <- function() .Call(wrap__RPolarsExpr__dt_microsecond RPolarsExpr$dt_nanosecond <- function() .Call(wrap__RPolarsExpr__dt_nanosecond, self) -RPolarsExpr$timestamp <- function(tu) .Call(wrap__RPolarsExpr__timestamp, self, tu) +RPolarsExpr$dt_timestamp <- function(tu) .Call(wrap__RPolarsExpr__dt_timestamp, self, tu) RPolarsExpr$dt_epoch_seconds <- function() .Call(wrap__RPolarsExpr__dt_epoch_seconds, self) @@ -1096,7 +1096,7 @@ RPolarsExpr$meta_pop <- function() .Call(wrap__RPolarsExpr__meta_pop, self) RPolarsExpr$meta_eq <- function(other) .Call(wrap__RPolarsExpr__meta_eq, self, other) -RPolarsExpr$meta_roots <- function() .Call(wrap__RPolarsExpr__meta_roots, self) +RPolarsExpr$meta_root_names <- function() .Call(wrap__RPolarsExpr__meta_root_names, self) RPolarsExpr$meta_output_name <- function() .Call(wrap__RPolarsExpr__meta_output_name, self) diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index bc167eb64..1c04b3bd9 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -2054,7 +2054,7 @@ dependencies = [ [[package]] name = "r-polars" -version = "0.39.3" +version = "0.39.4" dependencies = [ "either", "extendr-api", diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 981fd2c94..d0b3b5437 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "r-polars" -version = "0.39.3" +version = "0.39.4" edition = "2021" rust-version = "1.76.0" publish = false diff --git a/src/rust/src/lazy/dsl.rs b/src/rust/src/lazy/dsl.rs index 610c8ce8b..8341139f0 100644 --- a/src/rust/src/lazy/dsl.rs +++ b/src/rust/src/lazy/dsl.rs @@ -1,7 +1,6 @@ use crate::concurrent::RFnSignature; use crate::rdatatype::{ - new_rolling_cov_options, parse_fill_null_strategy, robj_to_timeunit, RPolarsDataType, - RPolarsDataTypeVector, + new_rolling_cov_options, parse_fill_null_strategy, RPolarsDataType, RPolarsDataTypeVector, }; use crate::robj_to; use crate::rpolarserr::{polars_to_rpolars_err, rerr, rpolars_to_polars_err, RResult, WithRctx}; @@ -9,18 +8,16 @@ use crate::series::RPolarsSeries; use crate::utils::extendr_concurrent::{ParRObj, ThreadCom}; use crate::utils::extendr_helpers::robj_inherits; use crate::utils::robj_to_rchoice; +use crate::utils::try_f64_into_usize; use crate::utils::wrappers::null_to_opt; -use crate::utils::{r_error_list, r_ok_list, r_result_list, robj_to_binary_vec}; -use crate::utils::{try_f64_into_u32, try_f64_into_usize}; +use crate::utils::{r_error_list, r_ok_list, robj_to_binary_vec}; use crate::CONFIG; use extendr_api::{extendr, prelude::*, rprintln, Deref, DerefMut}; use pl::PolarsError as pl_error; -use pl::{ - Duration, IntoSeries, RollingGroupOptions, SetOperation, StringNameSpaceImpl, TemporalMethods, -}; +use pl::{Duration, IntoSeries, RollingGroupOptions, SetOperation, TemporalMethods}; use polars::lazy::dsl; use polars::prelude as pl; -use polars::prelude::SortOptions; +use polars::prelude::{ExprEvalExtension, SortOptions}; use std::ops::{Add, Div, Mul, Rem, Sub}; use std::result::Result; pub type NameGenerator = pl::Arc String + Send + Sync>; @@ -227,14 +224,7 @@ impl RPolarsExpr { //any not translated expr from expr/expr.py pub fn to_physical(&self) -> Self { - self.0 - .clone() - .map( - |s| Ok(Some(s.to_physical_repr().into_owned())), - pl::GetOutput::map_dtype(|dt| dt.to_physical()), - ) - .with_fmt("to_physical") - .into() + self.0.clone().to_physical().into() } pub fn cast(&self, data_type: &RPolarsDataType, strict: bool) -> Self { @@ -358,16 +348,7 @@ impl RPolarsExpr { robj_to_rchoice(strategy)?.as_str(), robj_to!(Option, u32, limit)?, )?; - let expr: pl::Expr = self - .0 - .clone() - .apply( - move |s| s.fill_null(strat).map(Some), - pl::GetOutput::same_type(), - ) - .with_fmt("fill_null_with_strategy"); - - Ok(RPolarsExpr(expr)) + Ok(self.0.clone().fill_null_with_strategy(strat).into()) } pub fn fill_nan(&self, expr: &RPolarsExpr) -> Self { @@ -454,20 +435,9 @@ impl RPolarsExpr { } pub fn gather_every(&self, n: Robj, offset: Robj) -> RResult { - let n = robj_to!(usize, n).and_then(|n| match n { - 0 => rerr().bad_arg("n").bad_val("n can't be zero"), - _ => Ok(n), - })?; + let n = robj_to!(nonzero_usize, n)?.into(); let offset = robj_to!(usize, offset)?; - Ok(self - .0 - .clone() - .map( - move |s: pl::Series| Ok(Some(s.gather_every(n, offset))), - pl::GetOutput::same_type(), - ) - .with_fmt("gather_every") - .into()) + Ok(self.0.clone().gather_every(n, offset).into()) } pub fn hash(&self, seed: Robj, seed_1: Robj, seed_2: Robj, seed_3: Robj) -> RResult { @@ -716,16 +686,12 @@ impl RPolarsExpr { .into()) } - pub fn rolling_skew(&self, window_size_f: f64, bias: bool) -> List { - use pl::*; - let expr = try_f64_into_usize(window_size_f).map(|ws| { - RPolarsExpr( - self.0 - .clone() - .rolling_map_float(ws, move |ca| ca.clone().into_series().skew(bias).unwrap()), - ) - }); - r_result_list(expr) + pub fn rolling_skew(&self, window_size: f64, bias: bool) -> RResult { + Ok(self + .0 + .clone() + .rolling_skew(try_f64_into_usize(window_size)?, bias) + .into()) } pub fn abs(&self) -> Self { @@ -960,15 +926,17 @@ impl RPolarsExpr { self.0.clone().entropy(base, normalize).into() } - fn cumulative_eval(&self, expr: &RPolarsExpr, min_periods: f64, parallel: bool) -> List { - use pl::*; - r_result_list(try_f64_into_usize(min_periods).map(|min_p| { - RPolarsExpr( - self.0 - .clone() - .cumulative_eval(expr.0.clone(), min_p, parallel), - ) - })) + fn cumulative_eval( + &self, + expr: &RPolarsExpr, + min_periods: f64, + parallel: bool, + ) -> RResult { + Ok(self + .0 + .clone() + .cumulative_eval(expr.0.clone(), try_f64_into_usize(min_periods)?, parallel) + .into()) } pub fn implode(&self) -> Self { @@ -1412,11 +1380,13 @@ impl RPolarsExpr { self.clone().0.dt().nanosecond().into() } - pub fn timestamp(&self, tu: Robj) -> List { - let res = robj_to_timeunit(tu) - .map(|tu| RPolarsExpr(self.0.clone().dt().timestamp(tu))) - .map_err(|err| format!("valid tu needed for timestamp: {}", err)); - r_result_list(res) + pub fn dt_timestamp(&self, tu: Robj) -> RResult { + Ok(self + .clone() + .0 + .dt() + .timestamp(robj_to!(timeunit, tu)?) + .into()) } pub fn dt_epoch_seconds(&self) -> Self { @@ -1433,25 +1403,30 @@ impl RPolarsExpr { } pub fn dt_with_time_unit(&self, tu: Robj) -> RResult { - Ok(RPolarsExpr( - self.0.clone().dt().with_time_unit(robj_to!(timeunit, tu)?), - )) + Ok(self + .0 + .clone() + .dt() + .with_time_unit(robj_to!(timeunit, tu)?) + .into()) } pub fn dt_cast_time_unit(&self, tu: Robj) -> RResult { - Ok(RPolarsExpr( - self.0.clone().dt().cast_time_unit(robj_to!(timeunit, tu)?), - )) + Ok(self + .0 + .clone() + .dt() + .cast_time_unit(robj_to!(timeunit, tu)?) + .into()) } pub fn dt_convert_time_zone(&self, time_zone: Robj) -> RResult { - Ok(RPolarsExpr( - self.0 - .clone() - .dt() - .convert_time_zone(robj_to!(String, time_zone)?) - .into(), - )) + Ok(self + .0 + .clone() + .dt() + .convert_time_zone(robj_to!(String, time_zone)?) + .into()) } pub fn dt_replace_time_zone( @@ -1460,11 +1435,16 @@ impl RPolarsExpr { ambiguous: Robj, non_existent: Robj, ) -> RResult { - Ok(RPolarsExpr(self.0.clone().dt().replace_time_zone( - time_zone.into_option(), - robj_to!(PLExpr, ambiguous)?, - robj_to!(NonExistent, non_existent)?, - ))) + Ok(self + .0 + .clone() + .dt() + .replace_time_zone( + time_zone.into_option(), + robj_to!(PLExpr, ambiguous)?, + robj_to!(NonExistent, non_existent)?, + ) + .into()) } pub fn dt_total_days(&self) -> RResult { @@ -1565,11 +1545,8 @@ impl RPolarsExpr { self.0.clone().ceil().into() } - pub fn round(&self, decimals: f64) -> List { - let res = try_f64_into_u32(decimals) - .map_err(|err| format!("in round: {}", err)) - .map(|n| RPolarsExpr(self.0.clone().round(n))); - r_result_list(res) + pub fn round(&self, decimals: f64) -> RResult { + Ok(self.clone().0.round(decimals as u32).into()) } pub fn dot(&self, other: &RPolarsExpr) -> Self { @@ -1986,28 +1963,11 @@ impl RPolarsExpr { //string methods pub fn str_len_bytes(&self) -> Self { - use pl::*; - let function = |s: pl::Series| { - let ca = s.str()?; - Ok(Some(ca.str_len_bytes().into_series())) - }; - self.clone() - .0 - .map(function, pl::GetOutput::from_type(pl::DataType::UInt32)) - .with_fmt("str.len_bytes") - .into() + self.clone().0.str().len_bytes().into() } pub fn str_len_chars(&self) -> Self { - let function = |s: pl::Series| { - let ca = s.str()?; - Ok(Some(ca.str_len_chars().into_series())) - }; - self.clone() - .0 - .map(function, pl::GetOutput::from_type(pl::DataType::UInt32)) - .with_fmt("str.len_chars") - .into() + self.clone().0.str().len_chars().into() } pub fn str_concat(&self, delimiter: Robj, ignore_nulls: Robj) -> RResult { @@ -2103,25 +2063,13 @@ impl RPolarsExpr { self.0.clone().str().starts_with(sub.0.clone()).into() } - pub fn str_json_path_match(&self, pat: Robj) -> List { - let res = || -> Result { - use pl::*; - let pat: String = robj_to!(String, pat, "in str$json_path_match: {}")?; - let function = move |s: Series| { - let ca = s.str()?; - match ca.json_path_match(&pat) { - Ok(ca) => Ok(Some(ca.into_series())), - Err(e) => Err(pl::PolarsError::ComputeError(format!("{e:?}").into())), - } - }; - Ok(RPolarsExpr( - self.0 - .clone() - .map(function, pl::GetOutput::from_type(pl::DataType::String)) - .with_fmt("str.json_path_match"), - )) - }(); - r_result_list(res) + pub fn str_json_path_match(&self, pat: Robj) -> RResult { + Ok(self + .clone() + .0 + .str() + .json_path_match(robj_to!(String, pat)?) + .into()) } pub fn str_json_decode(&self, dtype: Robj, infer_schema_len: Robj) -> RResult { @@ -2465,7 +2413,7 @@ impl RPolarsExpr { Ok(self.0 == other.0) } - fn meta_roots(&self) -> Vec { + fn meta_root_names(&self) -> Vec { self.0 .clone() .meta() diff --git a/src/rust/src/rdatatype.rs b/src/rust/src/rdatatype.rs index d352bfe21..111cfc405 100644 --- a/src/rust/src/rdatatype.rs +++ b/src/rust/src/rdatatype.rs @@ -339,8 +339,8 @@ pub fn robj_to_asof_strategy(robj: Robj) -> RResult { match robj_to_rchoice(robj)?.as_str() { "forward" => Ok(AsofStrategy::Forward), "backward" => Ok(AsofStrategy::Backward), - s => rerr().bad_val(format!( - "asof strategy choice ('{s}') must be one of 'forward' or 'backward'" + s => rerr().notachoice(format!( + "asof strategy ('{s}') must be one of 'forward' or 'backward'" )), } } @@ -355,8 +355,8 @@ pub fn robj_to_unique_keep_strategy(robj: Robj) -> RResult { "first" => Ok(pl::UniqueKeepStrategy::First), "last" => Ok(pl::UniqueKeepStrategy::Last), "none" => Ok(pl::UniqueKeepStrategy::None), - s => rerr().bad_val(format!( - "keep strategy choice ('{s}') must be one of 'any', 'first', 'last', 'none'" + s => rerr().notachoice(format!( + "keep strategy ('{s}') must be one of 'any', 'first', 'last', 'none'" )), } } @@ -370,7 +370,7 @@ pub fn robj_to_quantile_interpolation_option(robj: Robj) -> RResult Ok(Midpoint), "linear" => Ok(Linear), s => rerr() - .bad_val(format!("interpolation choice ('{s}') must be one of 'nearest', 'higher', 'lower', 'midpoint', 'linear'")) + .notachoice(format!("interpolation ('{s}') must be one of 'nearest', 'higher', 'lower', 'midpoint', 'linear'")) , } } @@ -380,8 +380,8 @@ pub fn robj_to_interpolation_method(robj: Robj) -> RResult Ok(IM::Linear), "nearest" => Ok(IM::Nearest), - s => rerr().bad_val(format!( - "InterpolationMethod choice ('{s}') must be one of 'linear' or 'nearest'", + s => rerr().notachoice(format!( + "InterpolationMethod ('{s}') must be one of 'linear' or 'nearest'", )), } } @@ -410,8 +410,8 @@ pub fn robj_to_rank_method(robj: Robj) -> RResult { "ordinal" => Ok(RM::Ordinal), "random" => Ok(RM::Random), s => rerr() - .bad_val(format!( - "RankMethod choice ('{s}') must be one of 'average', 'dense', 'min', 'max', 'ordinal', 'random'" + .notachoice(format!( + "RankMethod ('{s}') must be one of 'average', 'dense', 'min', 'max', 'ordinal', 'random'" )), } } @@ -421,8 +421,8 @@ pub fn robj_to_non_existent(robj: Robj) -> RResult { match robj_to_rchoice(robj)?.to_lowercase().as_str() { "null" => Ok(NE::Null), "raise" => Ok(NE::Raise), - s => rerr().bad_val(format!( - "NonExistent choice ('{s}') must be one of 'null' or 'raise'" + s => rerr().notachoice(format!( + "NonExistent ('{s}') must be one of 'null' or 'raise'" )), } } @@ -433,8 +433,8 @@ pub fn robj_to_window_mapping(robj: Robj) -> RResult { "group_to_rows" => Ok(WM::GroupsToRows), "join" => Ok(WM::Join), "explode" => Ok(WM::Explode), - s => rerr().bad_val(format!( - "WindowMapping choice ('{s}') must be one of 'group_to_rows', 'join', 'explode'" + s => rerr().notachoice(format!( + "WindowMapping ('{s}') must be one of 'group_to_rows', 'join', 'explode'" )), } } @@ -471,7 +471,7 @@ pub fn literal_to_any_value(litval: pl::LiteralValue) -> RResult rerr().bad_val(format!("cannot convert LiteralValue {:?} to AnyValue", x)), + x => rerr().notachoice(format!("cannot convert LiteralValue {:?} to AnyValue", x)), } } @@ -497,7 +497,7 @@ pub fn robj_to_width_strategy(robj: Robj) -> RResult Ok(WS::FirstNonNull), "max_width" => Ok(WS::MaxWidth), - s => rerr().bad_val(format!( + s => rerr().notachoice(format!( "n_field_strategy ('{s}') must be one of 'first_non_null' or 'max_width'" )), } @@ -511,7 +511,7 @@ pub fn robj_to_timeunit(robj: Robj) -> RResult { "us" | "μs" => Ok(pl::TimeUnit::Microseconds), "ms" => Ok(pl::TimeUnit::Milliseconds), - _ => rerr().bad_val(format!( + _ => rerr().notachoice(format!( "str to polars TimeUnit ('{s}') must be one of 'ns', 'us/μs', 'ms'" )), } @@ -532,7 +532,7 @@ pub fn robj_to_categorical_ordering(robj: Robj) -> RResult Ok(CO::Physical), "lexical" => Ok(CO::Lexical), - _ => rerr().bad_val(format!( + _ => rerr().notachoice(format!( "CategoricalOrdering ('{s}') must be one of 'physical' or 'lexical'" )), } @@ -572,8 +572,8 @@ pub fn new_ipc_compression(robj: Robj) -> RResult> { "uncompressed" => Ok(None), "lz4" => Ok(Some(pl::IpcCompression::LZ4)), "zstd" => Ok(Some(pl::IpcCompression::ZSTD)), - s => rerr().bad_val(format!( - "IpcCompression choice ('{s}') must be one of 'uncompressed', 'lz4', 'zstd'" + s => rerr().notachoice(format!( + "IpcCompression ('{s}') must be one of 'uncompressed', 'lz4', 'zstd'" )), } } @@ -600,8 +600,8 @@ pub fn robj_to_join_type(robj: Robj) -> RResult { "outer_coalesce" => Ok(pl::JoinType::Outer { coalesce: true }), "semi" => Ok(pl::JoinType::Semi), "anti" => Ok(pl::JoinType::Anti), - s => rerr().bad_val(format!( - "JoinType choice ('{s}') must be one of 'cross', 'inner', 'left', 'outer', 'semi', 'anti'" + s => rerr().notachoice(format!( + "JoinType ('{s}') must be one of 'cross', 'inner', 'left', 'outer', 'semi', 'anti'" )), } } @@ -613,8 +613,8 @@ pub fn robj_to_closed_window(robj: Robj) -> RResult { "left" => Ok(CW::Left), "none" => Ok(CW::None), "right" => Ok(CW::Right), - s => rerr().bad_val(format!( - "ClosedWindow choice ('{s}') must be one of 'both', 'left', 'none', 'right'" + s => rerr().notachoice(format!( + "ClosedWindow ('{s}') must be one of 'both', 'left', 'none', 'right'" )), } } @@ -626,8 +626,8 @@ pub fn robj_to_closed_interval(robj: Robj) -> RResult { "left" => Ok(CI::Left), "none" => Ok(CI::None), "right" => Ok(CI::Right), - s => rerr().bad_val(format!( - "ClosedInterval choice ('{s}') must be one of 'both', 'left', 'none', 'right'" + s => rerr().notachoice(format!( + "ClosedInterval ('{s}') must be one of 'both', 'left', 'none', 'right'" )), } } @@ -639,8 +639,8 @@ pub fn robj_to_set_operation(robj: Robj) -> RResult { "intersection" => Ok(SO::Intersection), "difference" => Ok(SO::Difference), "symmetric_difference" => Ok(SO::SymmetricDifference), - s => rerr().bad_val(format!( - "SetOperation choice ('{s}') must be one of 'union', 'intersection', 'difference', 'symmetric_difference'" + s => rerr().notachoice(format!( + "SetOperation ('{s}') must be one of 'union', 'intersection', 'difference', 'symmetric_difference'" )), } } @@ -652,8 +652,8 @@ pub fn robj_to_join_validation(robj: Robj) -> RResult { "1:m" => Ok(JV::OneToMany), "1:1" => Ok(JV::OneToOne), "m:1" => Ok(JV::ManyToOne), - s => rerr().bad_val(format!( - "JoinValidation choice ('{s}') must be one of 'm:m', '1:m', '1:1', 'm:1'" + s => rerr().notachoice(format!( + "JoinValidation ('{s}') must be one of 'm:m', '1:m', '1:1', 'm:1'" )), } } @@ -664,8 +664,8 @@ pub fn robj_to_label(robj: Robj) -> RResult { "left" => Ok(Label::Left), "right" => Ok(Label::Right), "datapoint" => Ok(Label::DataPoint), - s => rerr().bad_val(format!( - "Label choice ('{s}') must be one of 'left', 'right', 'datapoint'" + s => rerr().notachoice(format!( + "Label ('{s}') must be one of 'left', 'right', 'datapoint'" )), } } @@ -682,8 +682,8 @@ pub fn robj_to_start_by(robj: Robj) -> RResult { "friday" => Ok(SB::Friday), "saturday" => Ok(SB::Saturday), "sunday" => Ok(SB::Sunday), - s => rerr().bad_val(format!( - "StartBy choice ('{s}') must be one of 'window', 'datapoint', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'" + s => rerr().notachoice(format!( + "StartBy ('{s}') must be one of 'window', 'datapoint', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'" )), } } @@ -694,8 +694,8 @@ pub fn robj_to_parallel_strategy(robj: extendr_api::Robj) -> RResult Ok(pl::ParallelStrategy::Columns), "row_groups" => Ok(pl::ParallelStrategy::RowGroups), "none" => Ok(pl::ParallelStrategy::None), - s => rerr().bad_val(format!( - "ParallelStrategy choice ('{s}') must be one of 'auto', 'columns', 'row_groups', 'none'" + s => rerr().notachoice(format!( + "ParallelStrategy ('{s}') must be one of 'auto', 'columns', 'row_groups', 'none'" )), } } @@ -705,8 +705,8 @@ pub fn robj_new_null_behavior(robj: Robj) -> RResult Ok(NB::Ignore), "drop" => Ok(NB::Drop), - s => rerr().bad_val(format!( - "NullBehavior choice ('{s}') must be one of 'drop' or 'ignore'" + s => rerr().notachoice(format!( + "NullBehavior ('{s}') must be one of 'drop' or 'ignore'" )), } } @@ -724,7 +724,7 @@ pub fn parse_fill_null_strategy( "mean" => Ok(Mean), "zero" => Ok(Zero), "one" => Ok(One), - s => rerr().bad_val(format!( + s => rerr().notachoice(format!( "FillNullStrategy ('{s}') must be one of 'forward', 'backward', 'min', 'max', 'mean', 'zero', 'one'" )), } diff --git a/src/rust/src/rpolarserr.rs b/src/rust/src/rpolarserr.rs index ca7fcb30b..88aa210dd 100644 --- a/src/rust/src/rpolarserr.rs +++ b/src/rust/src/rpolarserr.rs @@ -25,7 +25,7 @@ pub enum Rctx { Mistyped(String), #[error("Expected a value that {0}")] Misvalued(String), - #[error("Not a valid R choice because {0}")] + #[error("Invalid choice: {0}")] NotAChoice(String), #[error("{0}")] Plain(String), diff --git a/tests/testthat/_snaps/after-wrappers.md b/tests/testthat/_snaps/after-wrappers.md index 0bd6a241a..689bcc41f 100644 --- a/tests/testthat/_snaps/after-wrappers.md +++ b/tests/testthat/_snaps/after-wrappers.md @@ -325,117 +325,117 @@ [89] "dt_ordinal_day" "dt_quarter" [91] "dt_replace_time_zone" "dt_round" [93] "dt_second" "dt_strftime" - [95] "dt_time" "dt_total_days" - [97] "dt_total_hours" "dt_total_microseconds" - [99] "dt_total_milliseconds" "dt_total_minutes" - [101] "dt_total_nanoseconds" "dt_total_seconds" - [103] "dt_truncate" "dt_week" - [105] "dt_weekday" "dt_with_time_unit" - [107] "dt_year" "dtype_cols" - [109] "entropy" "eq" - [111] "eq_missing" "ewm_mean" - [113] "ewm_std" "ewm_var" - [115] "exclude" "exclude_dtype" - [117] "exp" "explode" - [119] "extend_constant" "fill_nan" - [121] "fill_null" "fill_null_with_strategy" - [123] "filter" "first" - [125] "flatten" "floor" - [127] "floor_div" "forward_fill" - [129] "gather" "gather_every" - [131] "gt" "gt_eq" - [133] "hash" "head" - [135] "implode" "interpolate" - [137] "is_between" "is_duplicated" - [139] "is_finite" "is_first_distinct" - [141] "is_in" "is_infinite" - [143] "is_last_distinct" "is_nan" - [145] "is_not_nan" "is_not_null" - [147] "is_null" "is_unique" - [149] "kurtosis" "last" - [151] "len" "list_all" - [153] "list_any" "list_arg_max" - [155] "list_arg_min" "list_contains" - [157] "list_diff" "list_eval" - [159] "list_gather" "list_gather_every" - [161] "list_get" "list_join" - [163] "list_len" "list_max" - [165] "list_mean" "list_min" - [167] "list_n_unique" "list_reverse" - [169] "list_set_operation" "list_shift" - [171] "list_slice" "list_sort" - [173] "list_sum" "list_to_struct" - [175] "list_unique" "lit" - [177] "log" "log10" - [179] "lower_bound" "lt" - [181] "lt_eq" "map_batches" - [183] "map_batches_in_background" "map_elements_in_background" - [185] "max" "mean" - [187] "median" "meta_eq" - [189] "meta_has_multiple_outputs" "meta_is_regex_projection" - [191] "meta_output_name" "meta_pop" - [193] "meta_roots" "meta_tree_format" - [195] "meta_undo_aliases" "min" - [197] "mode" "mul" - [199] "n_unique" "name_keep" - [201] "name_map" "name_prefix" - [203] "name_prefix_fields" "name_suffix" - [205] "name_suffix_fields" "name_to_lowercase" - [207] "name_to_uppercase" "nan_max" - [209] "nan_min" "neq" - [211] "neq_missing" "new_first" - [213] "new_last" "new_len" - [215] "not" "null_count" - [217] "or" "over" - [219] "pct_change" "peak_max" - [221] "peak_min" "pow" - [223] "print" "product" - [225] "qcut" "qcut_uniform" - [227] "quantile" "rank" - [229] "rechunk" "reinterpret" - [231] "rem" "rep" - [233] "repeat_by" "replace" - [235] "reshape" "reverse" - [237] "rle" "rle_id" - [239] "rolling" "rolling_corr" - [241] "rolling_cov" "rolling_max" - [243] "rolling_mean" "rolling_median" - [245] "rolling_min" "rolling_quantile" - [247] "rolling_skew" "rolling_std" - [249] "rolling_sum" "rolling_var" - [251] "round" "sample_frac" - [253] "sample_n" "search_sorted" - [255] "shift" "shift_and_fill" - [257] "shrink_dtype" "shuffle" - [259] "sign" "sin" - [261] "sinh" "skew" - [263] "slice" "sort_by" - [265] "sort_with" "std" - [267] "str_base64_decode" "str_base64_encode" - [269] "str_concat" "str_contains" - [271] "str_contains_any" "str_count_matches" - [273] "str_ends_with" "str_explode" - [275] "str_extract" "str_extract_all" - [277] "str_extract_groups" "str_find" - [279] "str_head" "str_hex_decode" - [281] "str_hex_encode" "str_json_decode" - [283] "str_json_path_match" "str_len_bytes" - [285] "str_len_chars" "str_pad_end" - [287] "str_pad_start" "str_replace" - [289] "str_replace_all" "str_replace_many" - [291] "str_reverse" "str_slice" - [293] "str_split" "str_split_exact" - [295] "str_splitn" "str_starts_with" - [297] "str_strip_chars" "str_strip_chars_end" - [299] "str_strip_chars_start" "str_tail" - [301] "str_to_date" "str_to_datetime" - [303] "str_to_integer" "str_to_lowercase" - [305] "str_to_time" "str_to_titlecase" - [307] "str_to_uppercase" "str_zfill" - [309] "struct_field_by_name" "struct_rename_fields" - [311] "sub" "sum" - [313] "tail" "tan" - [315] "tanh" "timestamp" + [95] "dt_time" "dt_timestamp" + [97] "dt_total_days" "dt_total_hours" + [99] "dt_total_microseconds" "dt_total_milliseconds" + [101] "dt_total_minutes" "dt_total_nanoseconds" + [103] "dt_total_seconds" "dt_truncate" + [105] "dt_week" "dt_weekday" + [107] "dt_with_time_unit" "dt_year" + [109] "dtype_cols" "entropy" + [111] "eq" "eq_missing" + [113] "ewm_mean" "ewm_std" + [115] "ewm_var" "exclude" + [117] "exclude_dtype" "exp" + [119] "explode" "extend_constant" + [121] "fill_nan" "fill_null" + [123] "fill_null_with_strategy" "filter" + [125] "first" "flatten" + [127] "floor" "floor_div" + [129] "forward_fill" "gather" + [131] "gather_every" "gt" + [133] "gt_eq" "hash" + [135] "head" "implode" + [137] "interpolate" "is_between" + [139] "is_duplicated" "is_finite" + [141] "is_first_distinct" "is_in" + [143] "is_infinite" "is_last_distinct" + [145] "is_nan" "is_not_nan" + [147] "is_not_null" "is_null" + [149] "is_unique" "kurtosis" + [151] "last" "len" + [153] "list_all" "list_any" + [155] "list_arg_max" "list_arg_min" + [157] "list_contains" "list_diff" + [159] "list_eval" "list_gather" + [161] "list_gather_every" "list_get" + [163] "list_join" "list_len" + [165] "list_max" "list_mean" + [167] "list_min" "list_n_unique" + [169] "list_reverse" "list_set_operation" + [171] "list_shift" "list_slice" + [173] "list_sort" "list_sum" + [175] "list_to_struct" "list_unique" + [177] "lit" "log" + [179] "log10" "lower_bound" + [181] "lt" "lt_eq" + [183] "map_batches" "map_batches_in_background" + [185] "map_elements_in_background" "max" + [187] "mean" "median" + [189] "meta_eq" "meta_has_multiple_outputs" + [191] "meta_is_regex_projection" "meta_output_name" + [193] "meta_pop" "meta_root_names" + [195] "meta_tree_format" "meta_undo_aliases" + [197] "min" "mode" + [199] "mul" "n_unique" + [201] "name_keep" "name_map" + [203] "name_prefix" "name_prefix_fields" + [205] "name_suffix" "name_suffix_fields" + [207] "name_to_lowercase" "name_to_uppercase" + [209] "nan_max" "nan_min" + [211] "neq" "neq_missing" + [213] "new_first" "new_last" + [215] "new_len" "not" + [217] "null_count" "or" + [219] "over" "pct_change" + [221] "peak_max" "peak_min" + [223] "pow" "print" + [225] "product" "qcut" + [227] "qcut_uniform" "quantile" + [229] "rank" "rechunk" + [231] "reinterpret" "rem" + [233] "rep" "repeat_by" + [235] "replace" "reshape" + [237] "reverse" "rle" + [239] "rle_id" "rolling" + [241] "rolling_corr" "rolling_cov" + [243] "rolling_max" "rolling_mean" + [245] "rolling_median" "rolling_min" + [247] "rolling_quantile" "rolling_skew" + [249] "rolling_std" "rolling_sum" + [251] "rolling_var" "round" + [253] "sample_frac" "sample_n" + [255] "search_sorted" "shift" + [257] "shift_and_fill" "shrink_dtype" + [259] "shuffle" "sign" + [261] "sin" "sinh" + [263] "skew" "slice" + [265] "sort_by" "sort_with" + [267] "std" "str_base64_decode" + [269] "str_base64_encode" "str_concat" + [271] "str_contains" "str_contains_any" + [273] "str_count_matches" "str_ends_with" + [275] "str_explode" "str_extract" + [277] "str_extract_all" "str_extract_groups" + [279] "str_find" "str_head" + [281] "str_hex_decode" "str_hex_encode" + [283] "str_json_decode" "str_json_path_match" + [285] "str_len_bytes" "str_len_chars" + [287] "str_pad_end" "str_pad_start" + [289] "str_replace" "str_replace_all" + [291] "str_replace_many" "str_reverse" + [293] "str_slice" "str_split" + [295] "str_split_exact" "str_splitn" + [297] "str_starts_with" "str_strip_chars" + [299] "str_strip_chars_end" "str_strip_chars_start" + [301] "str_tail" "str_to_date" + [303] "str_to_datetime" "str_to_integer" + [305] "str_to_lowercase" "str_to_time" + [307] "str_to_titlecase" "str_to_uppercase" + [309] "str_zfill" "struct_field_by_name" + [311] "struct_rename_fields" "sub" + [313] "sum" "tail" + [315] "tan" "tanh" [317] "to_physical" "top_k" [319] "unique" "unique_counts" [321] "unique_stable" "upper_bound" diff --git a/tests/testthat/test-dataframe.R b/tests/testthat/test-dataframe.R index b2e8d4ae7..f90c0d9de 100644 --- a/tests/testthat/test-dataframe.R +++ b/tests/testthat/test-dataframe.R @@ -882,7 +882,7 @@ test_that("join_asof_simple", { ) expect_grepl_error( pop$join_asof(gdp, left_on = "date", right_on = "date", strategy = "fruitcake"), - c("join_asof", "strategy choice", "fruitcake") + "must be one of 'forward' or 'backward'" ) # shared left_right on diff --git a/tests/testthat/test-joins.R b/tests/testthat/test-joins.R index 716083af5..cdaab9f58 100644 --- a/tests/testthat/test-joins.R +++ b/tests/testthat/test-joins.R @@ -39,7 +39,7 @@ test_that("lazyframe join examples", { # error on invalid choice expect_grepl_error( df$join(other_df, on = "ham", how = 42), - "Not a valid R choice" + "input is not a character vector" ) }) diff --git a/tests/testthat/test-lazy.R b/tests/testthat/test-lazy.R index ab35330c4..b67c17e78 100644 --- a/tests/testthat/test-lazy.R +++ b/tests/testthat/test-lazy.R @@ -495,7 +495,7 @@ test_that("join_asof_simple", { ) expect_grepl_error( pop$join_asof(gdp, left_on = "date", right_on = "date", strategy = "fruitcake"), - c("join_asof", "strategy choice", "fruitcake") + "must be one of 'forward' or 'backward'" ) # shared left_right on diff --git a/tests/testthat/test-parquet.R b/tests/testthat/test-parquet.R index be8b8bbb3..4aa8ce658 100644 --- a/tests/testthat/test-parquet.R +++ b/tests/testthat/test-parquet.R @@ -54,11 +54,14 @@ test_that("scan read parquet - parallel strategies", { } # bad parallel args - ctx = pl$read_parquet(tmpf, parallel = "34") |> get_err_ctx() - expect_true(startsWith(ctx$BadValue, "ParallelStrategy choice")) - expect_identical(ctx$BadArgument, "parallel") - ctx = pl$read_parquet(tmpf, parallel = 42) |> get_err_ctx() - expect_identical(ctx$NotAChoice, "input is not a character vector") + expect_grepl_error( + pl$read_parquet(tmpf, parallel = "34"), + "must be one of 'auto', 'columns', 'row_groups', 'none'" + ) + expect_grepl_error( + pl$read_parquet(tmpf, parallel = 42), + "input is not a character vector" + ) }) diff --git a/tools/lib-sums.tsv b/tools/lib-sums.tsv deleted file mode 100644 index 94a293d2d..000000000 --- a/tools/lib-sums.tsv +++ /dev/null @@ -1,6 +0,0 @@ -url sha256sum -https://github.com/pola-rs/r-polars/releases/download/lib-v0.39.3/libr_polars-0.39.3-aarch64-apple-darwin.tar.gz 4c6ac99286a01e399fd680092e3060537fc230bb9699df9ea940bf875628799d -https://github.com/pola-rs/r-polars/releases/download/lib-v0.39.3/libr_polars-0.39.3-aarch64-unknown-linux-gnu.tar.gz 1ca88fa4a5c82eada0ce6a34938da62f2ef9c893b76f54f7e6001fd8337e6a92 -https://github.com/pola-rs/r-polars/releases/download/lib-v0.39.3/libr_polars-0.39.3-x86_64-apple-darwin.tar.gz bead6abb0a02bf0a559b3bf9392ebb982ac02697e3ec3a0362e07307b7c5f7de -https://github.com/pola-rs/r-polars/releases/download/lib-v0.39.3/libr_polars-0.39.3-x86_64-pc-windows-gnu.tar.gz 4c5a3cdc40b57ce6e3fb389d43fae66b95ddafb73290591fd0780a01978aca02 -https://github.com/pola-rs/r-polars/releases/download/lib-v0.39.3/libr_polars-0.39.3-x86_64-unknown-linux-gnu.tar.gz a1176be2db12b4e8a7546850f89df749f470640f0ba36c9c6bfa83de4326574c