|
1 | 1 | import io
|
2 | 2 | import os
|
3 | 3 | import sys
|
| 4 | +import warnings |
4 | 5 | from zipfile import ZipFile
|
5 | 6 |
|
6 | 7 | from _csv import Error
|
@@ -741,3 +742,143 @@ def test_to_csv_iterative_compression_buffer(compression):
|
741 | 742 | pd.read_csv(buffer, compression=compression, index_col=0), df
|
742 | 743 | )
|
743 | 744 | assert not buffer.closed
|
| 745 | + |
| 746 | + |
| 747 | +def test_new_style_float_format_basic(): |
| 748 | + df = DataFrame({"A": [1234.56789, 9876.54321]}) |
| 749 | + result = df.to_csv(float_format="{:.2f}") |
| 750 | + expected = ",A\n0,1234.57\n1,9876.54\n" |
| 751 | + assert result == expected |
| 752 | + |
| 753 | + |
| 754 | +def test_new_style_float_format_thousands(): |
| 755 | + df = DataFrame({"A": [1234.56789, 9876.54321]}) |
| 756 | + result = df.to_csv(float_format="{:,.2f}") |
| 757 | + expected = ',A\n0,"1,234.57"\n1,"9,876.54"\n' |
| 758 | + assert result == expected |
| 759 | + |
| 760 | + |
| 761 | +def test_new_style_scientific_format(): |
| 762 | + df = DataFrame({"A": [0.000123, 0.000456]}) |
| 763 | + result = df.to_csv(float_format="{:.2e}") |
| 764 | + expected = ",A\n0,1.23e-04\n1,4.56e-04\n" |
| 765 | + assert result == expected |
| 766 | + |
| 767 | + |
| 768 | +def test_new_style_with_nan(): |
| 769 | + df = DataFrame({"A": [1.23, np.nan, 4.56]}) |
| 770 | + result = df.to_csv(float_format="{:.2f}", na_rep="NA") |
| 771 | + expected = ",A\n0,1.23\n1,NA\n2,4.56\n" |
| 772 | + assert result == expected |
| 773 | + |
| 774 | + |
| 775 | +def test_new_style_with_mixed_types(): |
| 776 | + df = DataFrame({"A": [1.23, 4.56], "B": ["x", "y"]}) |
| 777 | + result = df.to_csv(float_format="{:.2f}") |
| 778 | + expected = ",A,B\n0,1.23,x\n1,4.56,y\n" |
| 779 | + assert result == expected |
| 780 | + |
| 781 | + |
| 782 | +def test_new_style_with_mixed_types_in_column(): |
| 783 | + df = DataFrame({"A": [1.23, "text", 4.56]}) |
| 784 | + with warnings.catch_warnings(record=True): |
| 785 | + warnings.simplefilter("always") |
| 786 | + result = df.to_csv(float_format="{:.2f}") |
| 787 | + |
| 788 | + expected = ",A\n0,1.23\n1,text\n2,4.56\n" |
| 789 | + assert result == expected |
| 790 | + |
| 791 | + |
| 792 | +def test_invalid_new_style_format_missing_brace(): |
| 793 | + df = DataFrame({"A": [1.23]}) |
| 794 | + with pytest.raises(ValueError, match="Invalid new-style format string '{:.2f"): |
| 795 | + df.to_csv(float_format="{:.2f") |
| 796 | + |
| 797 | + |
| 798 | +def test_invalid_new_style_format_specifier(): |
| 799 | + df = DataFrame({"A": [1.23]}) |
| 800 | + with pytest.raises(ValueError, match="Invalid new-style format string '{:.2z}'"): |
| 801 | + df.to_csv(float_format="{:.2z}") |
| 802 | + |
| 803 | + |
| 804 | +def test_old_style_format_compatibility(): |
| 805 | + df = DataFrame({"A": [1234.56789, 9876.54321]}) |
| 806 | + result = df.to_csv(float_format="%.2f") |
| 807 | + expected = ",A\n0,1234.57\n1,9876.54\n" |
| 808 | + assert result == expected |
| 809 | + |
| 810 | + |
| 811 | +def test_callable_float_format_compatibility(): |
| 812 | + df = DataFrame({"A": [1234.56789, 9876.54321]}) |
| 813 | + result = df.to_csv(float_format=lambda x: f"{x:,.2f}") |
| 814 | + expected = ',A\n0,"1,234.57"\n1,"9,876.54"\n' |
| 815 | + assert result == expected |
| 816 | + |
| 817 | + |
| 818 | +def test_no_float_format(): |
| 819 | + df = DataFrame({"A": [1.23, 4.56]}) |
| 820 | + result = df.to_csv(float_format=None) |
| 821 | + expected = ",A\n0,1.23\n1,4.56\n" |
| 822 | + assert result == expected |
| 823 | + |
| 824 | + |
| 825 | +def test_large_numbers(): |
| 826 | + df = DataFrame({"A": [1e308, 2e308]}) |
| 827 | + result = df.to_csv(float_format="{:.2e}") |
| 828 | + expected = ",A\n0,1.00e+308\n1,inf\n" |
| 829 | + assert result == expected |
| 830 | + |
| 831 | + |
| 832 | +def test_zero_and_negative(): |
| 833 | + df = DataFrame({"A": [0.0, -1.23456]}) |
| 834 | + result = df.to_csv(float_format="{:+.2f}") |
| 835 | + expected = ",A\n0,+0.00\n1,-1.23\n" |
| 836 | + assert result == expected |
| 837 | + |
| 838 | + |
| 839 | +def test_unicode_format(): |
| 840 | + df = DataFrame({"A": [1.23, 4.56]}) |
| 841 | + result = df.to_csv(float_format="{:.2f}€", encoding="utf-8") |
| 842 | + expected = ",A\n0,1.23€\n1,4.56€\n" |
| 843 | + assert result == expected |
| 844 | + |
| 845 | + |
| 846 | +def test_empty_dataframe(): |
| 847 | + df = DataFrame({"A": []}) |
| 848 | + result = df.to_csv(float_format="{:.2f}") |
| 849 | + expected = ",A\n" |
| 850 | + assert result == expected |
| 851 | + |
| 852 | + |
| 853 | +def test_multi_column_float(): |
| 854 | + df = DataFrame({"A": [1.23, 4.56], "B": [7.89, 0.12]}) |
| 855 | + result = df.to_csv(float_format="{:.2f}") |
| 856 | + expected = ",A,B\n0,1.23,7.89\n1,4.56,0.12\n" |
| 857 | + assert result == expected |
| 858 | + |
| 859 | + |
| 860 | +def test_invalid_float_format_type(): |
| 861 | + df = DataFrame({"A": [1.23]}) |
| 862 | + with pytest.raises(ValueError, match="float_format must be a string or callable"): |
| 863 | + df.to_csv(float_format=123) |
| 864 | + |
| 865 | + |
| 866 | +def test_new_style_with_inf(): |
| 867 | + df = DataFrame({"A": [1.23, np.inf, -np.inf]}) |
| 868 | + result = df.to_csv(float_format="{:.2f}", na_rep="NA") |
| 869 | + expected = ",A\n0,1.23\n1,inf\n2,-inf\n" |
| 870 | + assert result == expected |
| 871 | + |
| 872 | + |
| 873 | +def test_new_style_with_precision_edge(): |
| 874 | + df = DataFrame({"A": [1.23456789]}) |
| 875 | + result = df.to_csv(float_format="{:.10f}") |
| 876 | + expected = ",A\n0,1.2345678900\n" |
| 877 | + assert result == expected |
| 878 | + |
| 879 | + |
| 880 | +def test_new_style_with_template(): |
| 881 | + df = DataFrame({"A": [1234.56789]}) |
| 882 | + result = df.to_csv(float_format="Value: {:,.2f}") |
| 883 | + expected = ',A\n0,"Value: 1,234.57"\n' |
| 884 | + assert result == expected |
0 commit comments