diff --git a/pandas-stubs/_typing.pyi b/pandas-stubs/_typing.pyi index 965a146da..d140b79d5 100644 --- a/pandas-stubs/_typing.pyi +++ b/pandas-stubs/_typing.pyi @@ -626,7 +626,7 @@ CompressionOptions: TypeAlias = ( FormattersType: TypeAlias = ( list[Callable] | tuple[Callable, ...] | Mapping[str | int, Callable] ) -FloatFormatType: TypeAlias = str | Callable | EngFormatter +FloatFormatType: TypeAlias = str | Callable[[float], str] | EngFormatter # converters ConvertersArg: TypeAlias = dict[Hashable, Callable[[Dtype], Dtype]] diff --git a/pandas-stubs/core/frame.pyi b/pandas-stubs/core/frame.pyi index abebc547c..9ecec7c19 100644 --- a/pandas-stubs/core/frame.pyi +++ b/pandas-stubs/core/frame.pyi @@ -18,7 +18,10 @@ from typing import ( overload, ) -from _typing import TimeZones +from _typing import ( + FloatFormatType, + TimeZones, +) from matplotlib.axes import Axes as PlotAxes import numpy as np from pandas import ( @@ -2311,7 +2314,7 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): index: _bool = ..., na_rep: _str = ..., formatters: FormattersType | None = ..., - float_format: Callable[[float], str] | None = ..., + float_format: FloatFormatType | None = ..., sparsify: _bool | None = ..., index_names: _bool = ..., justify: _str | None = ..., @@ -2334,7 +2337,7 @@ class DataFrame(NDFrame, OpsMixin, _GetItemHack): index: _bool = ..., na_rep: _str = ..., formatters: FormattersType | None = ..., - float_format: Callable[[float], str] | None = ..., + float_format: FloatFormatType | None = ..., sparsify: _bool | None = ..., index_names: _bool = ..., justify: _str | None = ..., diff --git a/pandas-stubs/core/series.pyi b/pandas-stubs/core/series.pyi index 64b7ec6c3..ed19e23ee 100644 --- a/pandas-stubs/core/series.pyi +++ b/pandas-stubs/core/series.pyi @@ -25,6 +25,7 @@ from typing import ( ) from _typing import ( + FloatFormatType, Label, ReplaceValue, TimeZones, @@ -530,7 +531,7 @@ class Series(IndexOpsMixin[S1], NDFrame): self, buf: FilePath | WriteBuffer[str], na_rep: _str = ..., - float_format: Callable[[float], str] = ..., + float_format: FloatFormatType = ..., header: _bool = ..., index: _bool = ..., length: _bool = ..., @@ -544,7 +545,7 @@ class Series(IndexOpsMixin[S1], NDFrame): self, buf: None = ..., na_rep: _str = ..., - float_format: Callable[[float], str] = ..., + float_format: FloatFormatType = ..., header: _bool = ..., index: _bool = ..., length: _bool = ..., diff --git a/tests/test_frame.py b/tests/test_frame.py index acb96183d..d292058d3 100644 --- a/tests/test_frame.py +++ b/tests/test_frame.py @@ -55,6 +55,7 @@ pytest_warns_bounded, ) +from pandas.io.formats.format import EngFormatter from pandas.io.formats.style import Styler from pandas.io.parsers import TextFileReader @@ -1698,6 +1699,27 @@ def test_types_to_string() -> None: df.to_string(col_space={"col1": 1, "col2": 3}) +def test_dataframe_to_string_float_fmt() -> None: + """Test the different argument types for float_format.""" + df = pd.DataFrame( + {"values": [2.304, 1.1, 3487392, 13.4732894237, 14.3, 18.0, 17.434, 19.3]} + ) + check(assert_type(df.to_string(), str), str) + + def _formatter(x) -> str: + return f"{x:.2f}" + + check(assert_type(df.to_string(float_format=_formatter), str), str) + check( + assert_type( + df.to_string(float_format=EngFormatter(accuracy=2, use_eng_prefix=False)), + str, + ), + str, + ) + check(assert_type(df.to_string(float_format="%.2f"), str), str) + + def test_types_to_html() -> None: df = pd.DataFrame( data={ diff --git a/tests/test_series.py b/tests/test_series.py index 3b3604c02..4cc33628c 100644 --- a/tests/test_series.py +++ b/tests/test_series.py @@ -60,6 +60,8 @@ ) from tests.extension.decimal.array import DecimalDtype +from pandas.io.formats.format import EngFormatter + if TYPE_CHECKING: from pandas.core.series import ( OffsetSeries, @@ -2932,6 +2934,27 @@ def test_to_string() -> None: ) +def test_series_to_string_float_fmt() -> None: + """Test the different argument types for float_format.""" + sr = pd.Series( + [2.304, 1.1, 3487392, 13.4732894237, 14.3, 18.0, 17.434, 19.3], name="values" + ) + check(assert_type(sr.to_string(), str), str) + + def _formatter(x) -> str: + return f"{x:.2f}" + + check(assert_type(sr.to_string(float_format=_formatter), str), str) + check( + assert_type( + sr.to_string(float_format=EngFormatter(accuracy=2, use_eng_prefix=False)), + str, + ), + str, + ) + check(assert_type(sr.to_string(float_format="%.2f"), str), str) + + def test_types_mask() -> None: s = pd.Series([1, 2, 3, 4, 5])