From ae51f6d722fa098e17d32c056c8669c3cce65720 Mon Sep 17 00:00:00 2001 From: pyz4 <42039243+pyz4@users.noreply.github.com> Date: Tue, 27 May 2025 14:37:07 -0400 Subject: [PATCH] fix(polars): add Value::Record to `NuExpression::can_downcast` logic (#15826) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description Merged PR #15553 added the ability to provide expressions in the form of records. This PR conforms the `NuExpression::can_downcast` logic to account for the newly allowed records argument type. As such, commands that rely on `can_downcast` in their implementation (e.g., `polars with-column`) will no longer err when provided with a record. See example below: ```nushell # Current error > [[a b]; [1 2] [3 4]] | polars into-df <-- only works if cast as lazyframe | polars with-column { c: ((polars col a) * 2) d: ((polars col a) * 3) } Error: nu::shell::cant_convert × Can't convert to NuDataFrame, NuLazyFrame, NuExpression, NuLazyGroupBy, NuWhen, │ NuDataType, NuSchema. ╭─[entry #24:3:26] 2 │ | polars into-df 3 │ ╭─▶ | polars with-column { 4 │ │ c: ((polars col a) * 2) 5 │ │ d: ((polars col a) * 3) 6 │ ├─▶ } · ╰──── can't convert record to NuDataFrame, NuLazyFrame, NuExpression, NuLazyGroupBy, NuWhen, NuDataType, NuSchema ╰──── # Fixed > [[a b]; [1 2] [3 4]] | polars into-df | polars with-column { c: ((polars col a) * 2) d: ((polars col a) * 3) } | polars collect ╭───┬───┬───┬───┬───╮ │ # │ a │ b │ c │ d │ ├───┼───┼───┼───┼───┤ │ 0 │ 1 │ 2 │ 2 │ 3 │ │ 1 │ 3 │ 4 │ 6 │ 9 │ ╰───┴───┴───┴───┴───╯ ``` # User-Facing Changes No breaking changes # Tests + Formatting An example test was added to `polars with-column`. # After Submitting --- .../src/dataframe/command/data/with_column.rs | 41 +++++++++++++++++-- .../src/dataframe/values/nu_expression/mod.rs | 1 + 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/crates/nu_plugin_polars/src/dataframe/command/data/with_column.rs b/crates/nu_plugin_polars/src/dataframe/command/data/with_column.rs index 38bafc9f72..61f90be19f 100644 --- a/crates/nu_plugin_polars/src/dataframe/command/data/with_column.rs +++ b/crates/nu_plugin_polars/src/dataframe/command/data/with_column.rs @@ -104,9 +104,44 @@ impl PluginCommand for WithColumn { ), }, Example { - description: "Add series to the dataframe using a record", + description: "Add series to a lazyframe using a record", example: r#"[[a b]; [1 2] [3 4]] | polars into-lazy + | polars with-column { + c: ((polars col a) * 2) + d: ((polars col a) * 3) + } + | polars collect"#, + result: Some( + NuDataFrame::try_from_columns( + vec![ + Column::new( + "a".to_string(), + vec![Value::test_int(1), Value::test_int(3)], + ), + Column::new( + "b".to_string(), + vec![Value::test_int(2), Value::test_int(4)], + ), + Column::new( + "c".to_string(), + vec![Value::test_int(2), Value::test_int(6)], + ), + Column::new( + "d".to_string(), + vec![Value::test_int(3), Value::test_int(9)], + ), + ], + None, + ) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + }, + Example { + description: "Add series to a dataframe using a record", + example: r#"[[a b]; [1 2] [3 4]] + | polars into-df | polars with-column { c: ((polars col a) * 2) d: ((polars col a) * 3) @@ -177,7 +212,7 @@ fn command_eager( if NuExpression::can_downcast(&new_column) { if let Some(name) = call.get_flag::>("name")? { return Err(ShellError::GenericError { - error: "Flag 'name' is unsuppored when used with expressions. Please use the `polars as` expression to name a column".into(), + error: "Flag 'name' is unsupported when used with expressions. Please use the `polars as` expression to name a column".into(), msg: "".into(), span: Some(name.span), help: Some("Use a `polars as` expression to name a column".into()), @@ -225,7 +260,7 @@ fn command_lazy( ) -> Result { if let Some(name) = call.get_flag::>("name")? { return Err(ShellError::GenericError { - error: "Flag 'name' is unsuppored for lazy dataframes. Please use the `polars as` expression to name a column".into(), + error: "Flag 'name' is unsupported for lazy dataframes. Please use the `polars as` expression to name a column".into(), msg: "".into(), span: Some(name.span), help: Some("Use a `polars as` expression to name a column".into()), diff --git a/crates/nu_plugin_polars/src/dataframe/values/nu_expression/mod.rs b/crates/nu_plugin_polars/src/dataframe/values/nu_expression/mod.rs index 60474139a6..b84f175bef 100644 --- a/crates/nu_plugin_polars/src/dataframe/values/nu_expression/mod.rs +++ b/crates/nu_plugin_polars/src/dataframe/values/nu_expression/mod.rs @@ -572,6 +572,7 @@ impl CustomValueSupport for NuExpression { match value { Value::Custom { val, .. } => val.as_any().downcast_ref::().is_some(), Value::List { vals, .. } => vals.iter().all(Self::can_downcast), + Value::Record { val, .. } => val.iter().all(|(_, value)| Self::can_downcast(value)), Value::String { .. } | Value::Int { .. } | Value::Bool { .. } | Value::Float { .. } => { true }