From 4ac6f4e631ccf595d8ab864c7df9305f8224faf9 Mon Sep 17 00:00:00 2001 From: lsgordon Date: Sun, 22 Jun 2025 21:22:48 -0500 Subject: [PATCH 1/6] Added coverage 314-349 and change in excel.py --- pandas/io/formats/excel.py | 12 +++++----- pandas/tests/io/formats/test_to_excel.py | 29 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/pandas/io/formats/excel.py b/pandas/io/formats/excel.py index 5fde6577e9f95..1602bd62e78e8 100644 --- a/pandas/io/formats/excel.py +++ b/pandas/io/formats/excel.py @@ -303,13 +303,13 @@ def _border_style( # 'slantDashDot' # 'thick' # 'thin' - if width is None and style is None and color is None: - # Return None will remove "border" from style dictionary - return None - if width is None and style is None: - # Return "none" will keep "border" in style dictionary - return "none" + if color is None: + # Return None will remove "border" from style dictionary + return None + else: + # Return "none" will keep "border" in style dictionary + return "none" if style in ("none", "hidden"): return "none" diff --git a/pandas/tests/io/formats/test_to_excel.py b/pandas/tests/io/formats/test_to_excel.py index b40201b9ba1e6..9398ad9634503 100644 --- a/pandas/tests/io/formats/test_to_excel.py +++ b/pandas/tests/io/formats/test_to_excel.py @@ -155,6 +155,14 @@ ( "border-top-style: solid; border-top-width: 4pt", {"border": {"top": {"style": "thick"}}}, + ), + ( + "border-top-style: solid; border-top-width: none", + {"border": {"top": {"style": "none"}}}, + ), + ( + "border-top-style: solid; border-top-width: 0.000001pt", + {"border": {"top": {"style": "none"}}}, ), ( "border-top-style: dotted", @@ -194,6 +202,12 @@ "border-top-color: blue", {"border": {"top": {"color": "0000FF", "style": "none"}}}, ), + ( + "border-top-style: slantDashDot; border-top-color: blue", + {"border": {"top": {"style": "slantDashDot", "color": "0000FF"}}}, + ), + + # ALIGNMENT # - horizontal ("text-align: center", {"alignment": {"horizontal": "center"}}), @@ -249,6 +263,21 @@ def test_css_to_excel_multiple(): } == actual +@pytest.mark.parametrize( + "css", + [ + "border-top-style: unhandled-border-style", + "border-style: another-unhandled-style", + ], +) + +def test_css_to_excel_unhandled_border_style_warns(css): + """Test that unhandled border styles raise a CSSWarning.""" + convert = CSSToExcelConverter() + with tm.assert_produces_warning(CSSWarning, match="Unhandled border style format"): + convert(css) + + @pytest.mark.parametrize( "css,inherited,expected", [ From d02d94ec180138c563ece0b8a952f7dbcd86bf8f Mon Sep 17 00:00:00 2001 From: lsgordon Date: Mon, 23 Jun 2025 18:15:54 -0500 Subject: [PATCH 2/6] Adding further coverage for excel.py --- pandas/io/formats/excel.py | 5 ----- pandas/tests/io/formats/test_to_excel.py | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/pandas/io/formats/excel.py b/pandas/io/formats/excel.py index 1602bd62e78e8..f2cf1a4838c36 100644 --- a/pandas/io/formats/excel.py +++ b/pandas/io/formats/excel.py @@ -411,11 +411,6 @@ def _get_decoration(self, props: Mapping[str, str]) -> Sequence[str]: else: return () - def _get_underline(self, decoration: Sequence[str]) -> str | None: - if "underline" in decoration: - return "single" - return None - def _get_shadow(self, props: Mapping[str, str]) -> bool | None: if "text-shadow" in props: return bool(re.search("^[^#(]*[1-9]", props["text-shadow"])) diff --git a/pandas/tests/io/formats/test_to_excel.py b/pandas/tests/io/formats/test_to_excel.py index 9398ad9634503..fffaf58857d61 100644 --- a/pandas/tests/io/formats/test_to_excel.py +++ b/pandas/tests/io/formats/test_to_excel.py @@ -358,6 +358,21 @@ def test_css_to_excel_bad_colors(input_color): convert = CSSToExcelConverter() assert expected == convert(css) +@pytest.mark.parametrize("input_color", ["#", "#1234567"]) +def test_css_to_excel_invalid_color_raises(input_color): + """Test that invalid colors raise a ValueError.""" + css = ( + f"border-top-color: {input_color}; " + f"border-right-color: {input_color}; " + f"border-bottom-color: {input_color}; " + f"border-left-color: {input_color}; " + f"background-color: {input_color}; " + f"color: {input_color}" + ) + + convert = CSSToExcelConverter() + with pytest.raises(ValueError, match=f"Unexpected color {input_color}"): + convert(css) def tests_css_named_colors_valid(): upper_hexs = set(map(str.upper, string.hexdigits)) From 9bc5fad6721f6edde9f38e38775a512a4d14d437 Mon Sep 17 00:00:00 2001 From: lsgordon Date: Mon, 23 Jun 2025 18:28:51 -0500 Subject: [PATCH 3/6] Whitespace changes (whoops) --- pandas/tests/io/formats/test_to_excel.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pandas/tests/io/formats/test_to_excel.py b/pandas/tests/io/formats/test_to_excel.py index fffaf58857d61..babbfcb46a6fc 100644 --- a/pandas/tests/io/formats/test_to_excel.py +++ b/pandas/tests/io/formats/test_to_excel.py @@ -156,7 +156,7 @@ "border-top-style: solid; border-top-width: 4pt", {"border": {"top": {"style": "thick"}}}, ), - ( + ( "border-top-style: solid; border-top-width: none", {"border": {"top": {"style": "none"}}}, ), @@ -206,8 +206,6 @@ "border-top-style: slantDashDot; border-top-color: blue", {"border": {"top": {"style": "slantDashDot", "color": "0000FF"}}}, ), - - # ALIGNMENT # - horizontal ("text-align: center", {"alignment": {"horizontal": "center"}}), @@ -270,7 +268,6 @@ def test_css_to_excel_multiple(): "border-style: another-unhandled-style", ], ) - def test_css_to_excel_unhandled_border_style_warns(css): """Test that unhandled border styles raise a CSSWarning.""" convert = CSSToExcelConverter() @@ -358,6 +355,7 @@ def test_css_to_excel_bad_colors(input_color): convert = CSSToExcelConverter() assert expected == convert(css) + @pytest.mark.parametrize("input_color", ["#", "#1234567"]) def test_css_to_excel_invalid_color_raises(input_color): """Test that invalid colors raise a ValueError.""" @@ -374,6 +372,7 @@ def test_css_to_excel_invalid_color_raises(input_color): with pytest.raises(ValueError, match=f"Unexpected color {input_color}"): convert(css) + def tests_css_named_colors_valid(): upper_hexs = set(map(str.upper, string.hexdigits)) for color in CSSToExcelConverter.NAMED_COLORS.values(): From c03c59a811238b9145a9b4e2a624bea7a9a0492d Mon Sep 17 00:00:00 2001 From: lsgordon Date: Mon, 23 Jun 2025 18:30:02 -0500 Subject: [PATCH 4/6] Whitespace changes (whoops) --- .gitignore | 1 + pandas/tests/io/test_common.py | 1 + 2 files changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index d951f3fb9cbad..07f268222e3cc 100644 --- a/.gitignore +++ b/.gitignore @@ -141,3 +141,4 @@ doc/source/savefig/ # Pyodide/WASM related files # ############################## /.pyodide-xbuildenv-* +.venv/ diff --git a/pandas/tests/io/test_common.py b/pandas/tests/io/test_common.py index 4a5e41397b59d..31940c0ac6391 100644 --- a/pandas/tests/io/test_common.py +++ b/pandas/tests/io/test_common.py @@ -33,6 +33,7 @@ pytestmark = pytest.mark.filterwarnings( "ignore:Passing a BlockManager to DataFrame:DeprecationWarning" + "ignore:pyarrow requires pandas:UserWarning:pyarrow.lib", ) From a4e7d370fdfd382bbcdcfd1fd44d55ccfabac4d0 Mon Sep 17 00:00:00 2001 From: Leo Gordon <112820316+lsgordon@users.noreply.github.com> Date: Mon, 23 Jun 2025 18:47:31 -0500 Subject: [PATCH 5/6] Update .gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 07f268222e3cc..d951f3fb9cbad 100644 --- a/.gitignore +++ b/.gitignore @@ -141,4 +141,3 @@ doc/source/savefig/ # Pyodide/WASM related files # ############################## /.pyodide-xbuildenv-* -.venv/ From 9b8f45cc660d374c7ee1667744539fc6a2b1f902 Mon Sep 17 00:00:00 2001 From: Leo Gordon <112820316+lsgordon@users.noreply.github.com> Date: Mon, 23 Jun 2025 18:49:46 -0500 Subject: [PATCH 6/6] Update test_common.py --- pandas/tests/io/test_common.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/tests/io/test_common.py b/pandas/tests/io/test_common.py index 31940c0ac6391..4a5e41397b59d 100644 --- a/pandas/tests/io/test_common.py +++ b/pandas/tests/io/test_common.py @@ -33,7 +33,6 @@ pytestmark = pytest.mark.filterwarnings( "ignore:Passing a BlockManager to DataFrame:DeprecationWarning" - "ignore:pyarrow requires pandas:UserWarning:pyarrow.lib", )