From aee8c65e8397d3e55c9e351e4caff28e68ca6c7f Mon Sep 17 00:00:00 2001 From: Richard Taylor <110459554+richardt-engineb@users.noreply.github.com> Date: Fri, 6 Sep 2024 15:02:30 +0100 Subject: [PATCH] #1660: Fix ExcelControl copying of stringified attribute (#1661) # Description As described in #1660, the `stringified` attribute is not copied during the `to_copy()` as it is not included in the `metadata_profile_patch`. This commit fixes it by adding it to the `metadata_profile_patch` and updates the documentation to clarify the interaction of `stringified` and schemas. This also inclues a unit test to verify the bug fix. - fixes #1660 - fixes #1659 # Tests Ensure the new unit test detects the issue before the fix: ``` > pytest frictionless/formats/excel/__spec__/test_control.py::test_excel_control_to_copy [...] > assert control_copy == control_with_changed_attributes E AssertionError: assert {'type': 'exc...tError': True} == {'type': 'exc...tError': True} E E Omitting 8 identical items, use -vv to show E Differing attributes: E ['stringified'] E E Drill down into differing attribute stringified: E stringified: False != True frictionless/formats/excel/__spec__/test_control.py:25: AssertionError ``` Ensure the unit test runs and passes after the fix: ``` > pytest frictionless/formats/excel/__spec__/test_control.py::test_excel_control_to_copy -v [...] frictionless/formats/excel/__spec__/test_control.py::test_excel_control_to_copy PASSED [100%] ``` --- .../formats/excel/__spec__/test_control.py | 17 +++++++++++++++++ frictionless/formats/excel/control.py | 7 +++++++ 2 files changed, 24 insertions(+) diff --git a/frictionless/formats/excel/__spec__/test_control.py b/frictionless/formats/excel/__spec__/test_control.py index 27aac29135..a6b2573445 100644 --- a/frictionless/formats/excel/__spec__/test_control.py +++ b/frictionless/formats/excel/__spec__/test_control.py @@ -6,3 +6,20 @@ def test_excel_dialect(): with Resource("data/table.xlsx") as resource: assert isinstance(resource.dialect.get_control("excel"), formats.ExcelControl) + +def test_excel_control_to_copy(): + """ + Test that the ExcelControl and all its attributes are correctly copied + """ + # Make a control with all values changed from the defaults + control_with_changed_attributes = formats.ExcelControl( + sheet="non-default", + fill_merged_cells=True, + preserve_formatting=True, + adjust_floating_point_error=True, + stringified=True + ) + + control_copy = control_with_changed_attributes.to_copy() + + assert control_copy == control_with_changed_attributes diff --git a/frictionless/formats/excel/control.py b/frictionless/formats/excel/control.py index 015fc2c9ea..298a2faa3e 100644 --- a/frictionless/formats/excel/control.py +++ b/frictionless/formats/excel/control.py @@ -51,6 +51,12 @@ class ExcelControl(Control): """ Stringifies all the cell values. Default value is False. + + Note that a table resource schema will still be applied and types coerced to match the schema + (either provided or inferred) _after_ the rows are read as strings. + + To return all cells as strings then both set `stringified=True` and specify a + schema that defines all fields to be of type string (see #1659). """ # Metadata @@ -61,5 +67,6 @@ class ExcelControl(Control): "fillMergedCells": {"type": "boolean"}, "preserveFormatting": {"type": "boolean"}, "adjustFloatingPointError": {"type": "boolean"}, + "stringified": {"type": "boolean"}, }, }