From 2110ecbc9583f390f4a1ded4fee92390a5600db8 Mon Sep 17 00:00:00 2001 From: invalidarg Date: Thu, 5 Sep 2024 17:03:22 +0200 Subject: [PATCH 01/11] second item in tuple is no longer truncated at first colon https://github.com/pandas-dev/pandas/issues/59623 --- pandas/io/formats/style_render.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/io/formats/style_render.py b/pandas/io/formats/style_render.py index 8a6383f7e8f82..ab9c469b03e87 100644 --- a/pandas/io/formats/style_render.py +++ b/pandas/io/formats/style_render.py @@ -2072,9 +2072,9 @@ def maybe_convert_css_to_tuples(style: CSSProperties) -> CSSList: s = style.split(";") try: return [ - (x.split(":")[0].strip(), x.split(":")[1].strip()) + (x.split(":")[0].strip(), ":".join(x.split(":")[1:]).strip()) for x in s - if x.strip() != "" + if ":".join(x.split(":")[1:]).strip() != "" ] except IndexError as err: raise ValueError( From 28ec59cefe75e3ef994b2607e27c4561bd61901e Mon Sep 17 00:00:00 2001 From: invalidarg Date: Mon, 9 Sep 2024 20:54:14 +0200 Subject: [PATCH 02/11] added testcase for maybe_convert_css_to_tuples #59623 --- pandas/tests/io/formats/style/test_style.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pandas/tests/io/formats/style/test_style.py b/pandas/tests/io/formats/style/test_style.py index 89addbbbc1ded..d22189a19184f 100644 --- a/pandas/tests/io/formats/style/test_style.py +++ b/pandas/tests/io/formats/style/test_style.py @@ -886,6 +886,11 @@ def test_maybe_convert_css_to_tuples(self): expected = [] assert maybe_convert_css_to_tuples("") == expected + #issue #59623 + expected = [("a", "b"), ("c", "url('data:123')")] + assert maybe_convert_css_to_tuples("a:b;c: url('data:123');") == expected + + def test_maybe_convert_css_to_tuples_err(self): msg = "Styles supplied as string must follow CSS rule formats" with pytest.raises(ValueError, match=msg): From a02544bcf482f90fdacebc852dae7582641d9572 Mon Sep 17 00:00:00 2001 From: invalidarg Date: Mon, 9 Sep 2024 22:51:27 +0200 Subject: [PATCH 03/11] maybe_convert_css_to_tuples() raises on strings without ":" --- pandas/io/formats/style_render.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pandas/io/formats/style_render.py b/pandas/io/formats/style_render.py index ab9c469b03e87..5d688404d679f 100644 --- a/pandas/io/formats/style_render.py +++ b/pandas/io/formats/style_render.py @@ -2069,18 +2069,18 @@ def maybe_convert_css_to_tuples(style: CSSProperties) -> CSSList: ('border','1px solid red')] """ if isinstance(style, str): - s = style.split(";") - try: - return [ - (x.split(":")[0].strip(), ":".join(x.split(":")[1:]).strip()) - for x in s - if ":".join(x.split(":")[1:]).strip() != "" - ] - except IndexError as err: + if ":" not in style: raise ValueError( "Styles supplied as string must follow CSS rule formats, " - f"for example 'attr: val;'. '{style}' was given." - ) from err + +f"for example 'attr: val;'. '{style}' was given." + ) + s = style.split(";") + return [ + (x.split(":")[0].strip(), ":".join(x.split(":")[1:]).strip()) + for x in s + if ":".join(x.split(":")[1:]).strip() != "" + ] + return style From 00d34581c71b64fa362234351f2af7936b942b8c Mon Sep 17 00:00:00 2001 From: invalidarg Date: Mon, 9 Sep 2024 23:14:11 +0200 Subject: [PATCH 04/11] fixed implicit str concatination --- pandas/io/formats/style_render.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/io/formats/style_render.py b/pandas/io/formats/style_render.py index 5d688404d679f..ebe75c03315d7 100644 --- a/pandas/io/formats/style_render.py +++ b/pandas/io/formats/style_render.py @@ -2072,7 +2072,7 @@ def maybe_convert_css_to_tuples(style: CSSProperties) -> CSSList: if ":" not in style: raise ValueError( "Styles supplied as string must follow CSS rule formats, " - +f"for example 'attr: val;'. '{style}' was given." + f"for example 'attr: val;'. '{style}' was given." ) s = style.split(";") return [ From ccd74deb5bfe3b0f9779a6bd64beec8469cc5bb7 Mon Sep 17 00:00:00 2001 From: invalidarg Date: Fri, 13 Sep 2024 17:21:56 +0200 Subject: [PATCH 05/11] Fixed raise on empty string --- pandas/io/formats/style_render.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/io/formats/style_render.py b/pandas/io/formats/style_render.py index ebe75c03315d7..54afc2f4a4604 100644 --- a/pandas/io/formats/style_render.py +++ b/pandas/io/formats/style_render.py @@ -2069,7 +2069,7 @@ def maybe_convert_css_to_tuples(style: CSSProperties) -> CSSList: ('border','1px solid red')] """ if isinstance(style, str): - if ":" not in style: + if style and ":" not in style: raise ValueError( "Styles supplied as string must follow CSS rule formats, " f"for example 'attr: val;'. '{style}' was given." @@ -2080,7 +2080,7 @@ def maybe_convert_css_to_tuples(style: CSSProperties) -> CSSList: for x in s if ":".join(x.split(":")[1:]).strip() != "" ] - + return style From fd244988ae052ffe49bed37ef43ba6e91b91f18a Mon Sep 17 00:00:00 2001 From: invalidarg Date: Fri, 13 Sep 2024 17:24:48 +0200 Subject: [PATCH 06/11] Update test_style.py --- pandas/tests/io/formats/style/test_style.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pandas/tests/io/formats/style/test_style.py b/pandas/tests/io/formats/style/test_style.py index d22189a19184f..15e945996186e 100644 --- a/pandas/tests/io/formats/style/test_style.py +++ b/pandas/tests/io/formats/style/test_style.py @@ -892,7 +892,10 @@ def test_maybe_convert_css_to_tuples(self): def test_maybe_convert_css_to_tuples_err(self): - msg = "Styles supplied as string must follow CSS rule formats" + msg = ( + "Styles supplied as string must follow CSS rule formats, " + "for example 'attr: val;'. 'err' was given." + ) with pytest.raises(ValueError, match=msg): maybe_convert_css_to_tuples("err") From 84ef0ef9a28256d50a0008753acd0f887e53e4a9 Mon Sep 17 00:00:00 2001 From: invalidarg Date: Fri, 13 Sep 2024 20:25:40 +0200 Subject: [PATCH 07/11] attr:; -> ("attr","") Same behavior as before patch --- pandas/io/formats/style_render.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/io/formats/style_render.py b/pandas/io/formats/style_render.py index 54afc2f4a4604..85d5ccaffd317 100644 --- a/pandas/io/formats/style_render.py +++ b/pandas/io/formats/style_render.py @@ -2078,7 +2078,7 @@ def maybe_convert_css_to_tuples(style: CSSProperties) -> CSSList: return [ (x.split(":")[0].strip(), ":".join(x.split(":")[1:]).strip()) for x in s - if ":".join(x.split(":")[1:]).strip() != "" + if x.strip() != "" ] return style From 9c29d71c18ea071e2515667de20c6dd20f8a77e9 Mon Sep 17 00:00:00 2001 From: invalidarg Date: Fri, 13 Sep 2024 20:28:36 +0200 Subject: [PATCH 08/11] add test for "attr:;", ie empty value --- pandas/tests/io/formats/style/test_style.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pandas/tests/io/formats/style/test_style.py b/pandas/tests/io/formats/style/test_style.py index 15e945996186e..0b421e76e23bc 100644 --- a/pandas/tests/io/formats/style/test_style.py +++ b/pandas/tests/io/formats/style/test_style.py @@ -889,6 +889,10 @@ def test_maybe_convert_css_to_tuples(self): #issue #59623 expected = [("a", "b"), ("c", "url('data:123')")] assert maybe_convert_css_to_tuples("a:b;c: url('data:123');") == expected + + #if no value, return attr and empty string + expected = [("a", ""), ("c", "")] + assert maybe_convert_css_to_tuples("a:;c: ") == expected def test_maybe_convert_css_to_tuples_err(self): From bff71fadc51ba866a91ec52aa25e07bfe6ff2602 Mon Sep 17 00:00:00 2001 From: invalidarg Date: Fri, 13 Sep 2024 20:42:56 +0200 Subject: [PATCH 09/11] str concatenation in the test broke mypy --- pandas/tests/io/formats/style/test_style.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/pandas/tests/io/formats/style/test_style.py b/pandas/tests/io/formats/style/test_style.py index 0b421e76e23bc..7f8f63092a4a4 100644 --- a/pandas/tests/io/formats/style/test_style.py +++ b/pandas/tests/io/formats/style/test_style.py @@ -893,13 +893,10 @@ def test_maybe_convert_css_to_tuples(self): #if no value, return attr and empty string expected = [("a", ""), ("c", "")] assert maybe_convert_css_to_tuples("a:;c: ") == expected - def test_maybe_convert_css_to_tuples_err(self): - msg = ( - "Styles supplied as string must follow CSS rule formats, " - "for example 'attr: val;'. 'err' was given." - ) + msg = "Styles supplied as string must follow CSS rule formats, " \ + "for example 'attr: val;'. 'err' was given." with pytest.raises(ValueError, match=msg): maybe_convert_css_to_tuples("err") From afb46a619eb57754d20ad752f44336e5e99cb088 Mon Sep 17 00:00:00 2001 From: invalidarg Date: Fri, 13 Sep 2024 21:26:32 +0200 Subject: [PATCH 10/11] revert explicit str concat --- pandas/tests/io/formats/style/test_style.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pandas/tests/io/formats/style/test_style.py b/pandas/tests/io/formats/style/test_style.py index 7f8f63092a4a4..fa208bd09705f 100644 --- a/pandas/tests/io/formats/style/test_style.py +++ b/pandas/tests/io/formats/style/test_style.py @@ -895,8 +895,10 @@ def test_maybe_convert_css_to_tuples(self): assert maybe_convert_css_to_tuples("a:;c: ") == expected def test_maybe_convert_css_to_tuples_err(self): - msg = "Styles supplied as string must follow CSS rule formats, " \ - "for example 'attr: val;'. 'err' was given." + msg = ( + "Styles supplied as string must follow CSS rule formats, " + "for example 'attr: val;'. 'err' was given." + ) with pytest.raises(ValueError, match=msg): maybe_convert_css_to_tuples("err") From f2e912b4cd6a33a55df0d943c65d16aab7ac1cd7 Mon Sep 17 00:00:00 2001 From: invalidarg Date: Fri, 20 Sep 2024 20:52:08 +0200 Subject: [PATCH 11/11] Invalidarg patch black (#1) * black test_style * Update style_render.py --- pandas/io/formats/style_render.py | 6 +++--- pandas/tests/io/formats/style/test_style.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pandas/io/formats/style_render.py b/pandas/io/formats/style_render.py index 85d5ccaffd317..08d9fd938c873 100644 --- a/pandas/io/formats/style_render.py +++ b/pandas/io/formats/style_render.py @@ -906,9 +906,9 @@ def concatenated_visible_rows(obj): row_body_headers = [ { **col, - "display_value": col["display_value"] - if col["is_visible"] - else "", + "display_value": ( + col["display_value"] if col["is_visible"] else "" + ), "cellstyle": self.ctx_index[r, c], } for c, col in enumerate(row[:index_levels]) diff --git a/pandas/tests/io/formats/style/test_style.py b/pandas/tests/io/formats/style/test_style.py index fa208bd09705f..e9fc2b2d27afd 100644 --- a/pandas/tests/io/formats/style/test_style.py +++ b/pandas/tests/io/formats/style/test_style.py @@ -886,11 +886,11 @@ def test_maybe_convert_css_to_tuples(self): expected = [] assert maybe_convert_css_to_tuples("") == expected - #issue #59623 + # issue #59623 expected = [("a", "b"), ("c", "url('data:123')")] assert maybe_convert_css_to_tuples("a:b;c: url('data:123');") == expected - #if no value, return attr and empty string + # if no value, return attr and empty string expected = [("a", ""), ("c", "")] assert maybe_convert_css_to_tuples("a:;c: ") == expected