diff --git a/crates/polars-core/src/fmt.rs b/crates/polars-core/src/fmt.rs index 2ba0cee9f4f47..d47f4722b88f7 100644 --- a/crates/polars-core/src/fmt.rs +++ b/crates/polars-core/src/fmt.rs @@ -2,6 +2,7 @@ use std::borrow::Cow; use std::fmt::{Debug, Display, Formatter}; use std::sync::atomic::{AtomicU8, Ordering}; +use std::sync::RwLock; use std::{fmt, str}; #[cfg(any( @@ -33,7 +34,7 @@ pub enum FloatFmt { Full, } static FLOAT_FMT: AtomicU8 = AtomicU8::new(FloatFmt::Mixed as u8); -static FLOAT_PRECISION: AtomicU8 = AtomicU8::new(u8::MAX); +static FLOAT_PRECISION: RwLock> = RwLock::new(None); pub fn get_float_fmt() -> FloatFmt { match FLOAT_FMT.load(Ordering::Relaxed) { @@ -43,16 +44,16 @@ pub fn get_float_fmt() -> FloatFmt { } } -pub fn get_float_precision() -> u8 { - FLOAT_PRECISION.load(Ordering::Relaxed) +pub fn get_float_precision() -> Option { + FLOAT_PRECISION.read().unwrap().clone() } pub fn set_float_fmt(fmt: FloatFmt) { FLOAT_FMT.store(fmt as u8, Ordering::Relaxed) } -pub fn set_float_precision(precision: u8) { - FLOAT_PRECISION.store(precision, Ordering::Relaxed) +pub fn set_float_precision(precision: Option) { + *FLOAT_PRECISION.write().unwrap() = precision; } macro_rules! format_array { @@ -724,12 +725,16 @@ const SCIENTIFIC_BOUND: f64 = 999999.0; fn fmt_float(f: &mut Formatter<'_>, width: usize, v: T) -> fmt::Result { let v: f64 = NumCast::from(v).unwrap(); - let precision = get_float_precision(); - if precision != u8::MAX { - if format!("{v:.precision$}", precision = precision as usize).len() > 19 { - return write!(f, "{v:>width$.precision$e}", precision = precision as usize); - } - return write!(f, "{v:>width$.precision$}", precision = precision as usize); + let float_precision = get_float_precision(); + + match float_precision { + Some(precision) => { + if format!("{v:.precision$}", precision = precision).len() > 19 { + return write!(f, "{v:>width$.precision$e}", precision = precision); + } + return write!(f, "{v:>width$.precision$}", precision = precision); + }, + _ => {}, } if matches!(get_float_fmt(), FloatFmt::Full) { diff --git a/py-polars/polars/config.py b/py-polars/polars/config.py index 2004b0834d79b..fa5f1a756729c 100644 --- a/py-polars/polars/config.py +++ b/py-polars/polars/config.py @@ -17,7 +17,7 @@ def _get_float_fmt() -> str: # pragma: no cover def _get_float_precision() -> int: - return 0 + return -1 # note: module not available when building docs @@ -379,12 +379,6 @@ def set_float_precision(cls, precision: int | None = None) -> type[Config]: Number of decimal places to display """ - if precision is None: - precision = 255 - elif precision > 16 and precision != 255: - raise ValueError( - f"precision must be None, or a number between 0-16; got {precision}" - ) _set_float_precision(precision) return cls diff --git a/py-polars/src/functions/meta.rs b/py-polars/src/functions/meta.rs index 36aecc06633d1..70e408d37f9d3 100644 --- a/py-polars/src/functions/meta.rs +++ b/py-polars/src/functions/meta.rs @@ -58,19 +58,14 @@ pub fn get_float_fmt() -> PyResult { } #[pyfunction] -pub fn set_float_precision(precision: u8) -> PyResult<()> { +pub fn set_float_precision(precision: Option) -> PyResult<()> { use polars_core::fmt::set_float_precision; - if precision > 16 && precision != u8::MAX { - return Err(PyValueError::new_err(format!( - "maximum supported float precision is 16, got {precision}", - ))); - } set_float_precision(precision); Ok(()) } #[pyfunction] -pub fn get_float_precision() -> PyResult { +pub fn get_float_precision() -> PyResult> { use polars_core::fmt::get_float_precision; Ok(get_float_precision()) } diff --git a/py-polars/tests/unit/test_cfg.py b/py-polars/tests/unit/test_cfg.py index f722c129feb80..d926a943adb15 100644 --- a/py-polars/tests/unit/test_cfg.py +++ b/py-polars/tests/unit/test_cfg.py @@ -611,10 +611,6 @@ def test_numeric_right_alignment() -> None: "└─────────┴─────────┴───────────┘" ) - # test nonsensical float precision raises an error - with pytest.raises(ValueError): - pl.Config.set_float_precision(50) - def test_string_cache() -> None: df1 = pl.DataFrame({"a": ["foo", "bar", "ham"], "b": [1, 2, 3]}) @@ -684,7 +680,7 @@ def test_config_load_save(tmp_path: Path) -> None: assert os.environ.get("POLARS_FMT_MAX_COLS") is None assert os.environ.get("POLARS_VERBOSE") is None assert _get_float_fmt() == "mixed" - assert _get_float_precision() == 255 + assert _get_float_precision() is None def test_config_scope() -> None: