From 1fcbde686490da0e90b902ae1315a42b3754f06f Mon Sep 17 00:00:00 2001 From: Richard Howe Date: Wed, 12 Jun 2024 22:12:21 -0400 Subject: [PATCH 01/14] Adding implementation, tests. Updating documentation --- doc/source/whatsnew/v3.0.0.rst | 1 + pandas/io/parsers/base_parser.py | 8 +++++++- pandas/tests/io/excel/test_readers.py | 8 ++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index fe1dcefe05ff2..82eddd502fda3 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -547,6 +547,7 @@ I/O - Bug in :meth:`DataFrame.to_stata` when writing :class:`DataFrame` and ``byteorder=`big```. (:issue:`58969`) - Bug in :meth:`DataFrame.to_string` that raised ``StopIteration`` with nested DataFrames. (:issue:`16098`) - Bug in :meth:`read_csv` raising ``TypeError`` when ``index_col`` is specified and ``na_values`` is a dict containing the key ``None``. (:issue:`57547`) +- Bug in :meth:`read_excel` raising ``ValueError`` when passing array of boolean values when ``dtype=pd.BooleanDtype.name``. (:issue:`58159`) - Bug in :meth:`read_stata` raising ``KeyError`` when input file is stored in big-endian format and contains strL data. (:issue:`58638`) Period diff --git a/pandas/io/parsers/base_parser.py b/pandas/io/parsers/base_parser.py index c6cc85b9f722b..0754ffd36c9b0 100644 --- a/pandas/io/parsers/base_parser.py +++ b/pandas/io/parsers/base_parser.py @@ -742,7 +742,9 @@ def _cast_types(self, values: ArrayLike, cast_type: DtypeObj, column) -> ArrayLi elif isinstance(cast_type, ExtensionDtype): array_type = cast_type.construct_array_type() try: - if isinstance(cast_type, BooleanDtype): + if isinstance(cast_type, BooleanDtype) and all( + isinstance(value, str) for value in values + ): # error: Unexpected keyword argument "true_values" for # "_from_sequence_of_strings" of "ExtensionArray" return array_type._from_sequence_of_strings( # type: ignore[call-arg] @@ -751,6 +753,10 @@ def _cast_types(self, values: ArrayLike, cast_type: DtypeObj, column) -> ArrayLi true_values=self.true_values, false_values=self.false_values, ) + elif isinstance(cast_type, BooleanDtype) and all( + isinstance(value, bool) for value in values + ): + return values else: return array_type._from_sequence_of_strings(values, dtype=cast_type) except NotImplementedError as err: diff --git a/pandas/tests/io/excel/test_readers.py b/pandas/tests/io/excel/test_readers.py index 6d6c3ad6b77a7..148686671b241 100644 --- a/pandas/tests/io/excel/test_readers.py +++ b/pandas/tests/io/excel/test_readers.py @@ -163,6 +163,14 @@ def xfail_datetimes_with_pyxlsb(engine, request): ) +def test_read_excel_type_check(): + # GH 58159 + df = DataFrame({"bool_column": [True]}, dtype=pd.BooleanDtype.name) + df.to_excel("test-file.xlsx", index=False) + df2 = pd.read_excel("test-file.xlsx", dtype={"bool_column": pd.BooleanDtype.name}) + assert all(isinstance(val, bool) for val in df2["bool_column"]) + + class TestReaders: @pytest.fixture(autouse=True) def cd_and_set_engine(self, engine, datapath, monkeypatch): From f77c41d9893c4c8356abbbfe5afd007043a82d1b Mon Sep 17 00:00:00 2001 From: Richard Howe Date: Wed, 12 Jun 2024 22:56:31 -0400 Subject: [PATCH 02/14] Fixing dependency error by moving test inside of TestReaders --- pandas/tests/io/excel/test_readers.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/pandas/tests/io/excel/test_readers.py b/pandas/tests/io/excel/test_readers.py index 148686671b241..9ee40bd284845 100644 --- a/pandas/tests/io/excel/test_readers.py +++ b/pandas/tests/io/excel/test_readers.py @@ -163,15 +163,18 @@ def xfail_datetimes_with_pyxlsb(engine, request): ) -def test_read_excel_type_check(): - # GH 58159 - df = DataFrame({"bool_column": [True]}, dtype=pd.BooleanDtype.name) - df.to_excel("test-file.xlsx", index=False) - df2 = pd.read_excel("test-file.xlsx", dtype={"bool_column": pd.BooleanDtype.name}) - assert all(isinstance(val, bool) for val in df2["bool_column"]) - - class TestReaders: + def test_read_excel_type_check(self): + # GH 58159 + df = DataFrame({"bool_column": [True]}, dtype=pd.BooleanDtype.name) + df.to_excel("test-type.xlsx", index=False) + df2 = pd.read_excel( + "test-type.xlsx", + dtype={"bool_column": pd.BooleanDtype.name}, + engine="openpyxl", + ) + assert all(isinstance(val, bool) for val in df2["bool_column"]) + @pytest.fixture(autouse=True) def cd_and_set_engine(self, engine, datapath, monkeypatch): """ From ffb65d430fc43c1224cef12f434edd92139a0934 Mon Sep 17 00:00:00 2001 From: Richard Howe Date: Sat, 15 Jun 2024 14:56:49 -0400 Subject: [PATCH 03/14] Updating implementation based on reviewer feedback --- pandas/core/arrays/boolean.py | 4 ++-- pandas/io/parsers/base_parser.py | 8 +++++++- pandas/tests/io/excel/test_readers.py | 7 ++++--- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/pandas/core/arrays/boolean.py b/pandas/core/arrays/boolean.py index a326925545045..553c7db6a54c4 100644 --- a/pandas/core/arrays/boolean.py +++ b/pandas/core/arrays/boolean.py @@ -296,8 +296,8 @@ class BooleanArray(BaseMaskedArray): Length: 3, dtype: boolean """ - _TRUE_VALUES = {"True", "TRUE", "true", "1", "1.0"} - _FALSE_VALUES = {"False", "FALSE", "false", "0", "0.0"} + _TRUE_VALUES = {True, "True", "TRUE", "true", "1", "1.0"} + _FALSE_VALUES = {None, False, "False", "FALSE", "false", "0", "0.0"} @classmethod def _simple_new(cls, values: np.ndarray, mask: npt.NDArray[np.bool_]) -> Self: diff --git a/pandas/io/parsers/base_parser.py b/pandas/io/parsers/base_parser.py index 0754ffd36c9b0..da1769a624240 100644 --- a/pandas/io/parsers/base_parser.py +++ b/pandas/io/parsers/base_parser.py @@ -756,7 +756,13 @@ def _cast_types(self, values: ArrayLike, cast_type: DtypeObj, column) -> ArrayLi elif isinstance(cast_type, BooleanDtype) and all( isinstance(value, bool) for value in values ): - return values + values = [str(val) for val in values] + return array_type._from_sequence_of_strings( # type: ignore[call-arg] + values, + dtype=cast_type, + true_values=self.true_values, + false_values=self.false_values, + ) else: return array_type._from_sequence_of_strings(values, dtype=cast_type) except NotImplementedError as err: diff --git a/pandas/tests/io/excel/test_readers.py b/pandas/tests/io/excel/test_readers.py index 9ee40bd284845..af37f388c5360 100644 --- a/pandas/tests/io/excel/test_readers.py +++ b/pandas/tests/io/excel/test_readers.py @@ -164,16 +164,17 @@ def xfail_datetimes_with_pyxlsb(engine, request): class TestReaders: - def test_read_excel_type_check(self): + @pytest.mark.parametrize("col", [[True, None, False], [True], [True, False]]) + def test_read_excel_type_check(self, col): # GH 58159 - df = DataFrame({"bool_column": [True]}, dtype=pd.BooleanDtype.name) + df = DataFrame({"bool_column": col}, dtype=pd.BooleanDtype.name) df.to_excel("test-type.xlsx", index=False) df2 = pd.read_excel( "test-type.xlsx", dtype={"bool_column": pd.BooleanDtype.name}, engine="openpyxl", ) - assert all(isinstance(val, bool) for val in df2["bool_column"]) + tm.assert_frame_equal(df, df2) @pytest.fixture(autouse=True) def cd_and_set_engine(self, engine, datapath, monkeypatch): From 14e565efd4cc95965fda9dee80fbb9e3d5020935 Mon Sep 17 00:00:00 2001 From: Richard Howe Date: Sat, 15 Jun 2024 15:44:33 -0400 Subject: [PATCH 04/14] Creating a more clean implementation --- pandas/core/arrays/boolean.py | 9 +++++++-- pandas/io/parsers/base_parser.py | 15 ++++----------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/pandas/core/arrays/boolean.py b/pandas/core/arrays/boolean.py index 553c7db6a54c4..474e6e6010a37 100644 --- a/pandas/core/arrays/boolean.py +++ b/pandas/core/arrays/boolean.py @@ -296,8 +296,9 @@ class BooleanArray(BaseMaskedArray): Length: 3, dtype: boolean """ - _TRUE_VALUES = {True, "True", "TRUE", "true", "1", "1.0"} - _FALSE_VALUES = {None, False, "False", "FALSE", "false", "0", "0.0"} + _TRUE_VALUES = {"True", "TRUE", "true", "1", "1.0"} + _FALSE_VALUES = {"False", "FALSE", "false", "0", "0.0"} + _NONE_VALUES = {"nan"} @classmethod def _simple_new(cls, values: np.ndarray, mask: npt.NDArray[np.bool_]) -> Self: @@ -329,15 +330,19 @@ def _from_sequence_of_strings( copy: bool = False, true_values: list[str] | None = None, false_values: list[str] | None = None, + none_values: list[str] | None = None, ) -> BooleanArray: true_values_union = cls._TRUE_VALUES.union(true_values or []) false_values_union = cls._FALSE_VALUES.union(false_values or []) + none_values_union = cls._NONE_VALUES.union(none_values or []) def map_string(s) -> bool: if s in true_values_union: return True elif s in false_values_union: return False + elif s in none_values_union: + return None else: raise ValueError(f"{s} cannot be cast to bool") diff --git a/pandas/io/parsers/base_parser.py b/pandas/io/parsers/base_parser.py index da1769a624240..11bc63c0c00f3 100644 --- a/pandas/io/parsers/base_parser.py +++ b/pandas/io/parsers/base_parser.py @@ -753,18 +753,11 @@ def _cast_types(self, values: ArrayLike, cast_type: DtypeObj, column) -> ArrayLi true_values=self.true_values, false_values=self.false_values, ) - elif isinstance(cast_type, BooleanDtype) and all( - isinstance(value, bool) for value in values - ): - values = [str(val) for val in values] - return array_type._from_sequence_of_strings( # type: ignore[call-arg] - values, - dtype=cast_type, - true_values=self.true_values, - false_values=self.false_values, - ) else: - return array_type._from_sequence_of_strings(values, dtype=cast_type) + values_str = [str(val) for val in values] + return array_type._from_sequence_of_strings( + values_str, dtype=cast_type + ) except NotImplementedError as err: raise NotImplementedError( f"Extension Array: {array_type} must implement " From 873bc9bb56c285ee6b428a1f1979ed5f705db5e4 Mon Sep 17 00:00:00 2001 From: Richard Howe Date: Sat, 15 Jun 2024 18:15:46 -0400 Subject: [PATCH 05/14] Fixing broken unit tests --- pandas/core/arrays/boolean.py | 8 +++++++- pandas/io/parsers/base_parser.py | 12 ++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/pandas/core/arrays/boolean.py b/pandas/core/arrays/boolean.py index 474e6e6010a37..5b91d0a985c94 100644 --- a/pandas/core/arrays/boolean.py +++ b/pandas/core/arrays/boolean.py @@ -297,7 +297,13 @@ class BooleanArray(BaseMaskedArray): """ _TRUE_VALUES = {"True", "TRUE", "true", "1", "1.0"} - _FALSE_VALUES = {"False", "FALSE", "false", "0", "0.0"} + _FALSE_VALUES = { + "False", + "FALSE", + "false", + "0", + "0.0", + } _NONE_VALUES = {"nan"} @classmethod diff --git a/pandas/io/parsers/base_parser.py b/pandas/io/parsers/base_parser.py index 11bc63c0c00f3..af2e95d588434 100644 --- a/pandas/io/parsers/base_parser.py +++ b/pandas/io/parsers/base_parser.py @@ -742,22 +742,18 @@ def _cast_types(self, values: ArrayLike, cast_type: DtypeObj, column) -> ArrayLi elif isinstance(cast_type, ExtensionDtype): array_type = cast_type.construct_array_type() try: - if isinstance(cast_type, BooleanDtype) and all( - isinstance(value, str) for value in values - ): + if isinstance(cast_type, BooleanDtype): # error: Unexpected keyword argument "true_values" for # "_from_sequence_of_strings" of "ExtensionArray" + values_str = [str(val) for val in values] return array_type._from_sequence_of_strings( # type: ignore[call-arg] - values, + values_str, dtype=cast_type, true_values=self.true_values, false_values=self.false_values, ) else: - values_str = [str(val) for val in values] - return array_type._from_sequence_of_strings( - values_str, dtype=cast_type - ) + return array_type._from_sequence_of_strings(values, dtype=cast_type) except NotImplementedError as err: raise NotImplementedError( f"Extension Array: {array_type} must implement " From e91806621d0daaffa75b0dae7dd697eeee6eafba Mon Sep 17 00:00:00 2001 From: Richard Howe Date: Sat, 15 Jun 2024 18:55:38 -0400 Subject: [PATCH 06/14] Fixing docstring error --- pandas/core/arrays/boolean.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/arrays/boolean.py b/pandas/core/arrays/boolean.py index 5b91d0a985c94..9156790ff1972 100644 --- a/pandas/core/arrays/boolean.py +++ b/pandas/core/arrays/boolean.py @@ -342,7 +342,7 @@ def _from_sequence_of_strings( false_values_union = cls._FALSE_VALUES.union(false_values or []) none_values_union = cls._NONE_VALUES.union(none_values or []) - def map_string(s) -> bool: + def map_string(s) -> bool | None: if s in true_values_union: return True elif s in false_values_union: From 7de150e797f79f9d3d0bfb3fc13f2d31a56de0eb Mon Sep 17 00:00:00 2001 From: Richard Howe Date: Sun, 16 Jun 2024 21:06:31 -0400 Subject: [PATCH 07/14] Updating implementation based on reviewer feedback. Adding additional unit tests --- pandas/core/arrays/boolean.py | 7 ++++--- pandas/io/parsers/base_parser.py | 1 + pandas/tests/io/data/excel/test7.xlsx | Bin 0 -> 5267 bytes pandas/tests/io/excel/test_readers.py | 17 +++++++++++++++++ 4 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 pandas/tests/io/data/excel/test7.xlsx diff --git a/pandas/core/arrays/boolean.py b/pandas/core/arrays/boolean.py index 9156790ff1972..3d932ed6bf4e2 100644 --- a/pandas/core/arrays/boolean.py +++ b/pandas/core/arrays/boolean.py @@ -304,7 +304,6 @@ class BooleanArray(BaseMaskedArray): "0", "0.0", } - _NONE_VALUES = {"nan"} @classmethod def _simple_new(cls, values: np.ndarray, mask: npt.NDArray[np.bool_]) -> Self: @@ -340,14 +339,16 @@ def _from_sequence_of_strings( ) -> BooleanArray: true_values_union = cls._TRUE_VALUES.union(true_values or []) false_values_union = cls._FALSE_VALUES.union(false_values or []) - none_values_union = cls._NONE_VALUES.union(none_values or []) + + if none_values is None: + none_values = [] def map_string(s) -> bool | None: if s in true_values_union: return True elif s in false_values_union: return False - elif s in none_values_union: + elif s in none_values: return None else: raise ValueError(f"{s} cannot be cast to bool") diff --git a/pandas/io/parsers/base_parser.py b/pandas/io/parsers/base_parser.py index af2e95d588434..787ac73613cec 100644 --- a/pandas/io/parsers/base_parser.py +++ b/pandas/io/parsers/base_parser.py @@ -751,6 +751,7 @@ def _cast_types(self, values: ArrayLike, cast_type: DtypeObj, column) -> ArrayLi dtype=cast_type, true_values=self.true_values, false_values=self.false_values, + none_values=self.na_values, ) else: return array_type._from_sequence_of_strings(values, dtype=cast_type) diff --git a/pandas/tests/io/data/excel/test7.xlsx b/pandas/tests/io/data/excel/test7.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..37b9191411fc5a36cbcb4ac192aa155839d3de9d GIT binary patch literal 5267 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 U!9%+V3yTPSM4%hW#ZR681wl&2l>h($ literal 0 HcmV?d00001 diff --git a/pandas/tests/io/excel/test_readers.py b/pandas/tests/io/excel/test_readers.py index af37f388c5360..e109c6f0bdc91 100644 --- a/pandas/tests/io/excel/test_readers.py +++ b/pandas/tests/io/excel/test_readers.py @@ -176,6 +176,23 @@ def test_read_excel_type_check(self, col): ) tm.assert_frame_equal(df, df2) + def test_pass_none_type(self): + # GH 58159 + with pd.ExcelFile("test7.xlsx") as excel: + parsed = pd.read_excel( + excel, + sheet_name="Sheet1", + keep_default_na=True, + na_values=["nan", "None", "abcd"], + dtype=pd.BooleanDtype.name, + engine="openpyxl", + ) + expected = DataFrame( + {"Test": [True, None, False, None, False, None, True]}, + dtype=pd.BooleanDtype.name, + ) + tm.assert_frame_equal(parsed, expected) + @pytest.fixture(autouse=True) def cd_and_set_engine(self, engine, datapath, monkeypatch): """ From 2a2e8a3346b7c29a1a7e399b715bf5c6fe13da42 Mon Sep 17 00:00:00 2001 From: Richard Howe Date: Fri, 21 Jun 2024 23:07:48 -0400 Subject: [PATCH 08/14] Updating implementation based on reviewer feedback --- doc/source/whatsnew/v3.0.0.rst | 2 +- pandas/core/arrays/boolean.py | 8 +------- pandas/tests/io/data/excel/test7.xlsx | Bin 5267 -> 0 bytes pandas/tests/io/excel/test_readers.py | 14 +++++++------- 4 files changed, 9 insertions(+), 15 deletions(-) delete mode 100644 pandas/tests/io/data/excel/test7.xlsx diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 82eddd502fda3..442385bd22492 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -547,7 +547,7 @@ I/O - Bug in :meth:`DataFrame.to_stata` when writing :class:`DataFrame` and ``byteorder=`big```. (:issue:`58969`) - Bug in :meth:`DataFrame.to_string` that raised ``StopIteration`` with nested DataFrames. (:issue:`16098`) - Bug in :meth:`read_csv` raising ``TypeError`` when ``index_col`` is specified and ``na_values`` is a dict containing the key ``None``. (:issue:`57547`) -- Bug in :meth:`read_excel` raising ``ValueError`` when passing array of boolean values when ``dtype=pd.BooleanDtype.name``. (:issue:`58159`) +- Bug in :meth:`read_excel` raising ``ValueError`` when passing array of boolean values when ``dtype="boolean"``. (:issue:`58159`) - Bug in :meth:`read_stata` raising ``KeyError`` when input file is stored in big-endian format and contains strL data. (:issue:`58638`) Period diff --git a/pandas/core/arrays/boolean.py b/pandas/core/arrays/boolean.py index 3d932ed6bf4e2..74c0cd7719c13 100644 --- a/pandas/core/arrays/boolean.py +++ b/pandas/core/arrays/boolean.py @@ -297,13 +297,7 @@ class BooleanArray(BaseMaskedArray): """ _TRUE_VALUES = {"True", "TRUE", "true", "1", "1.0"} - _FALSE_VALUES = { - "False", - "FALSE", - "false", - "0", - "0.0", - } + _FALSE_VALUES = {"False", "FALSE", "false", "0", "0.0"} @classmethod def _simple_new(cls, values: np.ndarray, mask: npt.NDArray[np.bool_]) -> Self: diff --git a/pandas/tests/io/data/excel/test7.xlsx b/pandas/tests/io/data/excel/test7.xlsx deleted file mode 100644 index 37b9191411fc5a36cbcb4ac192aa155839d3de9d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5267 zcmaJ_by!pj7H4Sb20>szI!C%gI))PI4w0GxX6Q}{>2wHbA0i-+E|m~zq)QNRzyKLa zkaTB!`>m|I@16VI_~V{)@9Ez;20A#nG+2a$gjlDYZ_Ti-5Hb4M*2mccCM<-x)?{?+ z^@2#^P{E0O$KuOMge8?7x|$tqVl1yXAWTgOWqr~6N2=6RB*}mFrg(>iUpiE*=t2Zm zKwLUD33tsCu)DY%L!a~wUwQ`$ON^F=^;1e|7(rF|d{Xtb4@cINhsuNDY1%}e4!}AS zfRB#bPFV6v4}7fe`iopT#c#%#Z$G5+b}=cP56A6{0eiZOL$p|L1SyEFo3dxJ`3-36 zmW4c#>ZBrdjw1?OaSm-8evir`yG{bq1XJd+ZSD-vO|_)3U1SY^&dZ~2Z`<_oayY~v z?WBqUxxj;9#1K1ZBaC5VVHy0bnaI&^1b7Jh zLw(#GpipWVl0{$Mho;ccpt&Tu_?;YqUFV}fO-qev80WeY1Y zd+;3eBf4bR2>E>Cq#i$(IUX>WKEI?bmQ#~ck+wT8j@+v}8F4Qy^m-&3{!RO=dQYT? zH3h7_aErgKQ7PHv^pNw6Oxj4pN_&&`23rBa2ZarC!sIM1=Ya(o7QBLORDioopQUGC zlF7h^kfg;>UWv3#HKifV$xHSQKLc{PhOUEi4&xI2TV=G?EARAoPC1C4-H)7_@OXCy zQQqc%xFArVF``nm+!CF*z)|c{0iv^}e9%*s=~5h2qeglHmGP0?(${Z`Y|pjV$sX&7 z;*%`|#umlWKH})V$Hrr~lQ_V31e%8E9ncfT?Nf&utFn1WU*}Q$90i<>@k@Rw^wABf z#Lk`33nc8JqaXV|Q7T(!l!4d@AJj@5QQ`(Z;oM|Sj$cSUp1O}1shj{>JSbCUfN)2X zm+d*FL8h{}ay>EvPcz{g2K0wIGM99up&Z8sJ3@_1u#x7EH;{|o`@A)0{?q3+)YZ0_ zxDi97TAcx~u)J{oDQ-yriW?X_(8C#qiJGrw6OeomP3U`5v#|LkqH+#T)8a4fx4?+X zr&<+SQ!FatY(`IC9Vg?)#GYMW-E-83#?d}Tz8hz*Z>HF z?&wnq`Ebk_l$)3nK3q4-^l<}w1mD|;2QdVAWIt#VQ0_C;J@uMYekJzUVZ(FtwjEL^ z;Muc~J`!Tpl5h8S;SA@eZxV;6UeA0Zn34^}CLC8BXHq4$Om29kBelc;F9BfJbrQ71 zKaEKtOO@Kdj)#Bl1vPHjdXjI<$5;ckbE58pl%-3uBe}(;RZ5M&i3R!kWjgXtWm_6N%(~CyJaqN_g$@(45o3Q8Se_H~E}IHGvzk8wxzfBaUNC(@4}tm+lbDv}(;P5;4ZBWuDT4 zEsU2dmGRA_ZtazdCvcz@c&u%qZ@1_nc;TGJF_{)y1tD41@Q?=1irQTSruUiO&{wet}|BO&{ zuH!usL}1UzSg^a8DB}9)!+YwY9eLj5$Dbch`W_7>cbG!B&XAi(*8KX@H~z3ZRN;qZ z>(sq1WXZvc$1WD(t}dq^v%ZdlzYkY0!mT{QTReWuI5Z&YtWjiTXZxde0RXrvPiaTG-$3g`+eZ0Io+ouAI2{3}?Jk@NXQO7AV(# z0H8kITH&NiM?|Oih!p27Re^8K*ujz*&v7vc@qJa^bQWDi6KVe`AsBuYQrLZGXE;pw z=j|3IH@Zx~&?PB~E>s-_d{KTnGiHQ<_exDK)t!5P}{V^nx2yaMidWya1+30x2h zao`G3JQI|U2ou9|lu*KQt+cnVX-{C!q@h%DA|@UCu2H$+f=5zc1+@@7wp z?^>>XtXJ9lC_vzts2{;Xt<$6l5OK{R{RMBU2Lt#ecGk0{$H4}`E?<^crE%xj#4`E-(8rIR%VrofY3*GS9NZ!@w zN@23fx;P(`!`<|9twb6vx~h|HS3v}Ol(DaJXME3x4eI-gPnwnDbaIyHCNoA6*K*9& zJC03c`9TAxRqrD119*l9^~^K?y^)aZU?(}!ip)De4jy`ku^2DcIOWZ;%h>N9>>1>6 zvbG))((opH7`udqUj$cY!nBI)J~~%*?KsY3$;o8)CR?Y6(COKzy?bz{femEH*9=>$UB_9ol_Ogn&xqcJYu12|jlNU^wz2OdC zR5`X~Q8>TUVBAQ7`V^s7OG5~_MJ^*|cf~EDSCFREOfUG5>wawtd?(REsY1Ge@KWa= za`k&^I&znRoOMFl--oDK;P4v-PsH1JYP25AZf-xJ^1YVl|4w?qDaQdn42? z@AnoZI6s(QWD>DC4iuz>6@=s|`1pLt-&m-+`LsV$Ull5iPxoTHzpJ|aVAkD3H!POX z^HnL&XzlLTrLXE*B3c=(iVVkRdlV=n)=?+Fn?_n;&)AbZn**24m$*}({|pnWvb<{q zUD~0+Cv&I>g%c43+Jf481nO@i95ce+<;M{<&crzCFB4|SuV|k(tu`0>Vc*!1$yAGD z_9LsvXG&%wLlPUJXx;?LxFsVrbnp{Je~3H!W%CgWD=7sQm90+-wMx7(s0md2{NQ45 zX4I&-5s|nX37>6!M!^s3*un4hl!cF95@7OwO6v^Rj&6pnXh`|@K#K9N{QnDbUWHSC z!OwKC`%n0JL92fJT8qH(p;XsH<+_XSfPTaEw|x>BvrRw3gqSReoVVX*zMVUGq518L zSn`+nJ{1!Dr=_^D-LL%!yCN@kzOG$287*B|z0aBYoRzA&lX^aaUQ5`b;Xuk<$e|}q z*1CL9Td!(vus!;#q44m&)>Hvtl=e=IB~BxR-=G85^W(YW94VP?S@2`f0O_?+AC`2{ z38PepReoU+f!K?M;*uPxOWgl(U59PGC|Qmd(3 zSq{O*SVn*MBxn+?H|IY>Oqzc~h5PnC&Q5pWKCTd#pNJtjt=kRf7KtkAf~YKb9n8at zyA;fGIDcm!kZ3x}IJ@6J8Fz&GK&K61dt<*c0&KgK)!)>%44A-dqVRNk~QnheqbzArl%L)0Ub=+_9 z4zOt5i@-DZb}Im*xI2tbu6 z9rLrlkIsDlhZ#jVowr-X)3<6}*MqTI5*!zBvR>9XYHC|fFO76cLT4wC4FaXiW>5I! zxm>x~DDN9;Rm?f=H|D*byoVwaJ*!^)~o8g)@_0>z~_}tKbdk(l#5BV zm&exuhtr>V{4I;s-Dcz`>yFB}B=Q&d2+qNXoCqr)WFy@}aJ8mhhEZe2J@+Ia5HA*6 z`|YRui&~#0>AQ1w9BwO(3|HN0#XtxI{w46rTo)W3u#G|yr#U>V-o*ms?{vbBv*qLq76<`ZiS{`FPrbM=#OAPC!Uj_pl8gZNumP82r>%ZRqF= zgF`)knsKb2s0Tz7ySDseC2A6q5O zm39=msRlJF@-`An8S8npy$;BfF`hA8h^0PZ50O6E`yzg!L+11z^?e1(7VKFT=CVYO z(Q9oMD0m9#R?T!b*m2 zbP2Fbx{Kwf{P}t|Lg#j!kMz?{Ny!)~lgM&1cN{)rB2Uh5_U<|kJeHGG0~-M$YI!Cs zS^A+!rKxQ)qV}huJ}oopB%#=%h2>IIHVY0n^9Yy%M(^#OfY1D}Hwu%VxIKyuSQ4^MrqxWi*pT7u$u(KK`m^gD$>A z{RhSMGUnsU8<(z!wWW058(P*v$rU0)cNACwiY<$+yP{@N%YFVk@p@n&_Lka@PyUIK zr`yvM?_~(Wo=R9s*KI893y$jV8LA^}gHEquoU|_6LhghPylFg)lK|K>SijakS2rG* z_0NCPm1WTHj8{iq%tGWBaic%=+j``8=BwiYW-9(gwrJ3RX8tuJ|IT_9SzzXeU*v`V zpYQ(9H1WHXt6dm_LVl4K(N8IVgGqjubG4~qdiF0$L|YT1$nPEecL`UkE2jDVqG*!; z(+YoQzgk!@CHNP~kzHZ`cR~K0`)c}PlJplvpndwQ5C5kW{Vw2YX#KYUGxXp5pPV<) U!9%+V3yTPSM4%hW#ZR681wl&2l>h($ diff --git a/pandas/tests/io/excel/test_readers.py b/pandas/tests/io/excel/test_readers.py index e109c6f0bdc91..721be1b9ba0e2 100644 --- a/pandas/tests/io/excel/test_readers.py +++ b/pandas/tests/io/excel/test_readers.py @@ -165,15 +165,15 @@ def xfail_datetimes_with_pyxlsb(engine, request): class TestReaders: @pytest.mark.parametrize("col", [[True, None, False], [True], [True, False]]) - def test_read_excel_type_check(self, col): + def test_read_excel_type_check(self, col, datapath): # GH 58159 - df = DataFrame({"bool_column": col}, dtype=pd.BooleanDtype.name) - df.to_excel("test-type.xlsx", index=False) - df2 = pd.read_excel( - "test-type.xlsx", - dtype={"bool_column": pd.BooleanDtype.name}, - engine="openpyxl", + df = DataFrame({"bool_column": col}, dtype="boolean") + df.to_excel("test_boolean_types.xlsx", index=False) + f_path = os.path.join( + datapath("io", "data", "excel"), "test_boolean_types.xlsx" ) + + df2 = pd.read_excel(f_path, dtype={"bool_column": "boolean"}, engine="openpyxl") tm.assert_frame_equal(df, df2) def test_pass_none_type(self): From 614c88079d91146145d8430c1f429964c24aab03 Mon Sep 17 00:00:00 2001 From: Richard Howe Date: Fri, 21 Jun 2024 23:09:56 -0400 Subject: [PATCH 09/14] Updating implementation based on reviewer feedback --- .../tests/io/data/excel/test_boolean_types.xlsx | Bin 0 -> 5280 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 pandas/tests/io/data/excel/test_boolean_types.xlsx diff --git a/pandas/tests/io/data/excel/test_boolean_types.xlsx b/pandas/tests/io/data/excel/test_boolean_types.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..e57edb38f12c691f1e4b11e9da5f7403ec3db347 GIT binary patch literal 5280 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 HI{Wp1>Nx6h literal 0 HcmV?d00001 From c62571eb591b07209f3d73463912b84017100787 Mon Sep 17 00:00:00 2001 From: Richard Howe Date: Fri, 21 Jun 2024 23:12:55 -0400 Subject: [PATCH 10/14] Using datapath fixture --- pandas/tests/io/excel/test_readers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/io/excel/test_readers.py b/pandas/tests/io/excel/test_readers.py index 721be1b9ba0e2..3c2e53c9040d1 100644 --- a/pandas/tests/io/excel/test_readers.py +++ b/pandas/tests/io/excel/test_readers.py @@ -168,11 +168,11 @@ class TestReaders: def test_read_excel_type_check(self, col, datapath): # GH 58159 df = DataFrame({"bool_column": col}, dtype="boolean") - df.to_excel("test_boolean_types.xlsx", index=False) f_path = os.path.join( datapath("io", "data", "excel"), "test_boolean_types.xlsx" ) + df.to_excel(f_path, index=False) df2 = pd.read_excel(f_path, dtype={"bool_column": "boolean"}, engine="openpyxl") tm.assert_frame_equal(df, df2) From d871d79924f7210c9c4400566166a1ba61fed45c Mon Sep 17 00:00:00 2001 From: Richard Howe Date: Sat, 22 Jun 2024 22:09:11 -0400 Subject: [PATCH 11/14] Fixing failing unit test --- pandas/tests/internals/test_none_type.xlsx | Bin 0 -> 4889 bytes .../io/data/excel/test_boolean_types.xlsx | Bin 5280 -> 5279 bytes .../tests/io/data/excel/test_none_type.xlsx | Bin 0 -> 5302 bytes pandas/tests/io/excel/test_readers.py | 11 +++++++---- 4 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 pandas/tests/internals/test_none_type.xlsx create mode 100644 pandas/tests/io/data/excel/test_none_type.xlsx diff --git a/pandas/tests/internals/test_none_type.xlsx b/pandas/tests/internals/test_none_type.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..fa6395f064fca00d49a7e08fa4329c6f7a710379 GIT binary patch literal 4889 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 literal 0 HcmV?d00001 diff --git a/pandas/tests/io/data/excel/test_boolean_types.xlsx b/pandas/tests/io/data/excel/test_boolean_types.xlsx index e57edb38f12c691f1e4b11e9da5f7403ec3db347..234703c32f0abe61516c3e44aa35275242d14f08 100644 GIT binary patch delta 325 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 Date: Sat, 22 Jun 2024 23:54:30 -0400 Subject: [PATCH 12/14] Removing unneeded file --- pandas/tests/internals/test_none_type.xlsx | Bin 4889 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 pandas/tests/internals/test_none_type.xlsx diff --git a/pandas/tests/internals/test_none_type.xlsx b/pandas/tests/internals/test_none_type.xlsx deleted file mode 100644 index fa6395f064fca00d49a7e08fa4329c6f7a710379..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4889 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 From 66d34f0fb88a3e38a1adc78a4d704b06394b9d72 Mon Sep 17 00:00:00 2001 From: Richard Howe Date: Mon, 24 Jun 2024 23:19:14 -0400 Subject: [PATCH 13/14] Fixing failing documentation test --- doc/source/whatsnew/v3.0.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 8c6e4ec046d52..5fef55347fda8 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -555,10 +555,10 @@ I/O - Bug in :meth:`DataFrame.to_string` that raised ``StopIteration`` with nested DataFrames. (:issue:`16098`) - Bug in :meth:`HDFStore.get` was failing to save data of dtype datetime64[s] correctly (:issue:`59004`) - Bug in :meth:`read_csv` raising ``TypeError`` when ``index_col`` is specified and ``na_values`` is a dict containing the key ``None``. (:issue:`57547`) -lean - Bug in :meth:`read_csv` raising ``TypeError`` when ``nrows`` and ``iterator`` are specified without specifying a ``chunksize``. (:issue:`59079`) - Bug in :meth:`read_excel` raising ``ValueError`` when passing array of boolean values when ``dtype="boolean"``. (:issue:`58159`) - Bug in :meth:`read_stata` raising ``KeyError`` when input file is stored in big-endian format and contains strL data. (:issue:`58638`) +- Period ^^^^^^ From 42285ffdd86d490db259bf3069f13bdd804d8618 Mon Sep 17 00:00:00 2001 From: Richard Howe Date: Tue, 25 Jun 2024 15:40:28 -0400 Subject: [PATCH 14/14] Updating unit test based on reviewer feedback --- pandas/tests/io/excel/test_readers.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pandas/tests/io/excel/test_readers.py b/pandas/tests/io/excel/test_readers.py index 017e5ff2f7aea..5ce78b1c90e76 100644 --- a/pandas/tests/io/excel/test_readers.py +++ b/pandas/tests/io/excel/test_readers.py @@ -168,9 +168,7 @@ class TestReaders: def test_read_excel_type_check(self, col, datapath): # GH 58159 df = DataFrame({"bool_column": col}, dtype="boolean") - f_path = os.path.join( - datapath("io", "data", "excel"), "test_boolean_types.xlsx" - ) + f_path = datapath("io", "data", "excel", "test_boolean_types.xlsx") df.to_excel(f_path, index=False) df2 = pd.read_excel(f_path, dtype={"bool_column": "boolean"}, engine="openpyxl") @@ -178,7 +176,7 @@ def test_read_excel_type_check(self, col, datapath): def test_pass_none_type(self, datapath): # GH 58159 - f_path = os.path.join(datapath("io", "data", "excel"), "test_none_type.xlsx") + f_path = datapath("io", "data", "excel", "test_none_type.xlsx") with pd.ExcelFile(f_path) as excel: parsed = pd.read_excel(