Skip to content

Commit

Permalink
change FLOAT_PRECISION type from AtomicU8 to RwLock<Option<usize>>
Browse files Browse the repository at this point in the history
  • Loading branch information
alicja-januszkiewicz committed Sep 17, 2023
1 parent 1cacae5 commit 16aaebb
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 30 deletions.
27 changes: 16 additions & 11 deletions crates/polars-core/src/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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<Option<usize>> = RwLock::new(None);

pub fn get_float_fmt() -> FloatFmt {
match FLOAT_FMT.load(Ordering::Relaxed) {
Expand All @@ -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<usize> {
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<usize>) {
*FLOAT_PRECISION.write().unwrap() = precision;
}

macro_rules! format_array {
Expand Down Expand Up @@ -724,12 +725,16 @@ const SCIENTIFIC_BOUND: f64 = 999999.0;
fn fmt_float<T: Num + NumCast>(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) {
Expand Down
8 changes: 1 addition & 7 deletions py-polars/polars/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down
9 changes: 2 additions & 7 deletions py-polars/src/functions/meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,14 @@ pub fn get_float_fmt() -> PyResult<String> {
}

#[pyfunction]
pub fn set_float_precision(precision: u8) -> PyResult<()> {
pub fn set_float_precision(precision: Option<usize>) -> 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<u8> {
pub fn get_float_precision() -> PyResult<Option<usize>> {
use polars_core::fmt::get_float_precision;
Ok(get_float_precision())
}
6 changes: 1 addition & 5 deletions py-polars/tests/unit/test_cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]})
Expand Down Expand Up @@ -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:
Expand Down

0 comments on commit 16aaebb

Please sign in to comment.