From a04d36851330cccb471283e4d04efcdb7838c5d0 Mon Sep 17 00:00:00 2001 From: Eric Tulowetzke Date: Thu, 8 Aug 2024 18:34:35 -0500 Subject: [PATCH 1/4] make it so float don't get rounded to ints --- crates/polars-core/src/datatypes/any_value.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/crates/polars-core/src/datatypes/any_value.rs b/crates/polars-core/src/datatypes/any_value.rs index e3db5b5cdba7..d361389ac3dd 100644 --- a/crates/polars-core/src/datatypes/any_value.rs +++ b/crates/polars-core/src/datatypes/any_value.rs @@ -537,7 +537,13 @@ impl<'a> AnyValue<'a> { // to string (av, DataType::String) => { - AnyValue::StringOwned(format_smartstring!("{}", av.extract::()?)) + if av.is_integer() { + AnyValue::StringOwned(format_smartstring!("{}", av.extract::()?)) + } else if av.is_float() { + AnyValue::StringOwned(format_smartstring!("{}", av.extract::()?)) + } else { + AnyValue::StringOwned(format_smartstring!("{}", av)) + } }, // to binary From 633a7605684bf38dab4cdb18dcecb02e545fad9d Mon Sep 17 00:00:00 2001 From: Eric Tulowetzke Date: Fri, 9 Aug 2024 14:39:15 -0500 Subject: [PATCH 2/4] Add more cheks in AnyValue cast like Boolean check --- crates/polars-core/src/datatypes/any_value.rs | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/crates/polars-core/src/datatypes/any_value.rs b/crates/polars-core/src/datatypes/any_value.rs index d361389ac3dd..0c13fcc72a58 100644 --- a/crates/polars-core/src/datatypes/any_value.rs +++ b/crates/polars-core/src/datatypes/any_value.rs @@ -536,15 +536,17 @@ impl<'a> AnyValue<'a> { (AnyValue::Float64(v), DataType::Boolean) => AnyValue::Boolean(*v != f64::default()), // to string - (av, DataType::String) => { - if av.is_integer() { - AnyValue::StringOwned(format_smartstring!("{}", av.extract::()?)) - } else if av.is_float() { - AnyValue::StringOwned(format_smartstring!("{}", av.extract::()?)) - } else { - AnyValue::StringOwned(format_smartstring!("{}", av)) - } - }, + (AnyValue::UInt8(_v), DataType::String) => AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)), + (AnyValue::UInt16(_v), DataType::String) => AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)), + (AnyValue::UInt32(_v), DataType::String) => AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)), + (AnyValue::UInt64(_v), DataType::String) => AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)), + (AnyValue::Int8(_v), DataType::String) => AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)), + (AnyValue::Int16(_v), DataType::String) => AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)), + (AnyValue::Int32(_v), DataType::String) => AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)), + (AnyValue::Int64(_v), DataType::String) => AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)), + (AnyValue::Float32(_v), DataType::String) => AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)), + (AnyValue::Float64(_v), DataType::String) => AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)), + (av, DataType::String) => AnyValue::StringOwned(format_smartstring!("{}", av)), // to binary (AnyValue::String(v), DataType::Binary) => AnyValue::Binary(v.as_bytes()), From 061c689219bdaa525f7bdcf02e63ea9b590f7bc5 Mon Sep 17 00:00:00 2001 From: Eric Tulowetzke Date: Fri, 9 Aug 2024 16:06:42 -0500 Subject: [PATCH 3/4] add test and run lint --- crates/polars-core/src/datatypes/any_value.rs | 46 ++++++++++++++----- py-polars/tests/unit/functions/test_lit.py | 11 +++++ 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/crates/polars-core/src/datatypes/any_value.rs b/crates/polars-core/src/datatypes/any_value.rs index 0c13fcc72a58..7653f90a9964 100644 --- a/crates/polars-core/src/datatypes/any_value.rs +++ b/crates/polars-core/src/datatypes/any_value.rs @@ -536,17 +536,41 @@ impl<'a> AnyValue<'a> { (AnyValue::Float64(v), DataType::Boolean) => AnyValue::Boolean(*v != f64::default()), // to string - (AnyValue::UInt8(_v), DataType::String) => AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)), - (AnyValue::UInt16(_v), DataType::String) => AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)), - (AnyValue::UInt32(_v), DataType::String) => AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)), - (AnyValue::UInt64(_v), DataType::String) => AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)), - (AnyValue::Int8(_v), DataType::String) => AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)), - (AnyValue::Int16(_v), DataType::String) => AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)), - (AnyValue::Int32(_v), DataType::String) => AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)), - (AnyValue::Int64(_v), DataType::String) => AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)), - (AnyValue::Float32(_v), DataType::String) => AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)), - (AnyValue::Float64(_v), DataType::String) => AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)), - (av, DataType::String) => AnyValue::StringOwned(format_smartstring!("{}", av)), + (AnyValue::UInt8(_v), DataType::String) => { + AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)) + }, + (AnyValue::UInt16(_v), DataType::String) => { + AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)) + }, + (AnyValue::UInt32(_v), DataType::String) => { + AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)) + }, + (AnyValue::UInt64(_v), DataType::String) => { + AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)) + }, + (AnyValue::Int8(_v), DataType::String) => { + AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)) + }, + (AnyValue::Int16(_v), DataType::String) => { + AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)) + }, + (AnyValue::Int32(_v), DataType::String) => { + AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)) + }, + (AnyValue::Int64(_v), DataType::String) => { + AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)) + }, + (AnyValue::Float32(_v), DataType::String) => { + AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)) + }, + (AnyValue::Float64(_v), DataType::String) => { + AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)) + }, + // this is needed other types + // if this isn't present then tests: agg, max, min break for other types + (_, DataType::String) => { + AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)) + }, // to binary (AnyValue::String(v), DataType::Binary) => AnyValue::Binary(v.as_bytes()), diff --git a/py-polars/tests/unit/functions/test_lit.py b/py-polars/tests/unit/functions/test_lit.py index 4b8ca8abe796..430a626d9b62 100644 --- a/py-polars/tests/unit/functions/test_lit.py +++ b/py-polars/tests/unit/functions/test_lit.py @@ -173,6 +173,17 @@ def test_lit_decimal() -> None: assert result == value +def test_lit_string_float() -> None: + value = 3.2 + + expr = pl.lit(value, dtype=pl.Utf8) + df = pl.select(expr) + result = df.item() + + assert df.dtypes[0] == pl.String + assert result == str(value) + + @given(s=series(min_size=1, max_size=1, allow_null=False, allowed_dtypes=pl.Decimal)) def test_lit_decimal_parametric(s: pl.Series) -> None: scale = s.dtype.scale # type: ignore[attr-defined] From 644cb530f95967cc6c7ac523836ce66f14b2689f Mon Sep 17 00:00:00 2001 From: Eric Tulowetzke Date: Sat, 10 Aug 2024 12:12:13 -0500 Subject: [PATCH 4/4] narrow down cases from AnyValue to string --- crates/polars-core/src/datatypes/any_value.rs | 42 ++++--------------- 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/crates/polars-core/src/datatypes/any_value.rs b/crates/polars-core/src/datatypes/any_value.rs index 7653f90a9964..4c7eeb093066 100644 --- a/crates/polars-core/src/datatypes/any_value.rs +++ b/crates/polars-core/src/datatypes/any_value.rs @@ -536,40 +536,14 @@ impl<'a> AnyValue<'a> { (AnyValue::Float64(v), DataType::Boolean) => AnyValue::Boolean(*v != f64::default()), // to string - (AnyValue::UInt8(_v), DataType::String) => { - AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)) - }, - (AnyValue::UInt16(_v), DataType::String) => { - AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)) - }, - (AnyValue::UInt32(_v), DataType::String) => { - AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)) - }, - (AnyValue::UInt64(_v), DataType::String) => { - AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)) - }, - (AnyValue::Int8(_v), DataType::String) => { - AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)) - }, - (AnyValue::Int16(_v), DataType::String) => { - AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)) - }, - (AnyValue::Int32(_v), DataType::String) => { - AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)) - }, - (AnyValue::Int64(_v), DataType::String) => { - AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)) - }, - (AnyValue::Float32(_v), DataType::String) => { - AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)) - }, - (AnyValue::Float64(_v), DataType::String) => { - AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)) - }, - // this is needed other types - // if this isn't present then tests: agg, max, min break for other types - (_, DataType::String) => { - AnyValue::StringOwned(format_smartstring!("{}", self.extract::()?)) + (av, DataType::String) => { + if av.is_unsigned_integer() { + AnyValue::StringOwned(format_smartstring!("{}", av.extract::()?)) + } else if av.is_float() { + AnyValue::StringOwned(format_smartstring!("{}", av.extract::()?)) + } else { + AnyValue::StringOwned(format_smartstring!("{}", av.extract::()?)) + } }, // to binary