openpyxl issueshttps://foss.heptapod.net/openpyxl/openpyxl/-/issues2024-03-21T10:35:31Zhttps://foss.heptapod.net/openpyxl/openpyxl/-/issues/21623.1.2: pytest fails in openpyxl/drawing/tests/test_drawing.py2024-03-21T10:35:31ZTomasz Kłoczko3.1.2: pytest fails in openpyxl/drawing/tests/test_drawing.pyI'm packaging your module as an rpm package so I'm using the typical PEP517 based build, install and test cycle used on building packages from non-root account.
- `python3 -sBm build -w --no-isolation`
- because I'm calling `build` with ...I'm packaging your module as an rpm package so I'm using the typical PEP517 based build, install and test cycle used on building packages from non-root account.
- `python3 -sBm build -w --no-isolation`
- because I'm calling `build` with `--no-isolation` I'm using during all processes only locally installed modules
- install .whl file in </install/prefix> using `installer` module
- run pytest with $PYTHONPATH pointing to sitearch and sitelib inside </install/prefix>
- build is performed in env which is *`cut off from access to the public network`* (pytest is executed with `-m "not network"`)
<details>
<summary>Here is pytest output:</summary>
```console
+ PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-openpyxl-3.1.2-6.fc36.x86_64/usr/lib64/python3.9/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-openpyxl-3.1.2-6.fc36.x86_64/usr/lib/python3.9/site-packages
+ /usr/bin/pytest -ra -m 'not network'
==================================================================================== test session starts ====================================================================================
platform linux -- Python 3.9.18, pytest-8.1.1, pluggy-1.4.0
benchmark: 4.0.0 (defaults: timer=time.perf_counter disable_gc=False min_rounds=5 min_time=0.000005 max_time=1.0 calibration_precision=10 warmup=False warmup_iterations=100000)
rootdir: /home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2
configfile: pytest.ini
plugins: hypothesis-6.99.6, Faker-24.2.0, benchmark-4.0.0
collected 2513 items
openpyxl/cell/tests/test_cell.py .........................s........x........................ [ 2%]
openpyxl/cell/tests/test_read_only.py ......... [ 2%]
openpyxl/cell/tests/test_rich_text.py ................. [ 3%]
openpyxl/cell/tests/test_text.py ............ [ 3%]
openpyxl/cell/tests/test_writer.py ....................................................... [ 6%]
openpyxl/chart/tests/test_3d.py .... [ 6%]
openpyxl/chart/tests/test_area_chart.py ..... [ 6%]
openpyxl/chart/tests/test_axis.py ................. [ 7%]
openpyxl/chart/tests/test_bar_chart.py ...... [ 7%]
openpyxl/chart/tests/test_bubble_chart.py .. [ 7%]
openpyxl/chart/tests/test_chart.py .................. [ 8%]
openpyxl/chart/tests/test_chartspace.py ........ [ 8%]
openpyxl/chart/tests/test_data_source.py .................. [ 9%]
openpyxl/chart/tests/test_error_bar.py .. [ 9%]
openpyxl/chart/tests/test_label.py .... [ 9%]
openpyxl/chart/tests/test_layout.py ... [ 9%]
openpyxl/chart/tests/test_legend.py .... [ 9%]
openpyxl/chart/tests/test_line_chart.py ..... [ 9%]
openpyxl/chart/tests/test_marker.py .... [ 10%]
openpyxl/chart/tests/test_picture.py .. [ 10%]
openpyxl/chart/tests/test_pie_chart.py ......... [ 10%]
openpyxl/chart/tests/test_pivot.py .... [ 10%]
openpyxl/chart/tests/test_plotarea.py ............ [ 11%]
openpyxl/chart/tests/test_print.py .... [ 11%]
openpyxl/chart/tests/test_radar_chart.py .. [ 11%]
openpyxl/chart/tests/test_reader.py ... [ 11%]
openpyxl/chart/tests/test_reference.py .......... [ 11%]
openpyxl/chart/tests/test_scatter_chart.py .. [ 11%]
openpyxl/chart/tests/test_series.py ......... [ 12%]
openpyxl/chart/tests/test_series_factory.py ....... [ 12%]
openpyxl/chart/tests/test_shapes.py .. [ 12%]
openpyxl/chart/tests/test_stock_chart.py .. [ 12%]
openpyxl/chart/tests/test_surface_chart.py ........ [ 13%]
openpyxl/chart/tests/test_text.py ..... [ 13%]
openpyxl/chart/tests/test_title.py ... [ 13%]
openpyxl/chart/tests/test_trendline.py .... [ 13%]
openpyxl/chart/tests/test_updown_bars.py .. [ 13%]
openpyxl/chartsheet/tests/test_chartsheet.py .... [ 13%]
openpyxl/chartsheet/tests/test_custom.py .... [ 13%]
openpyxl/chartsheet/tests/test_properties.py .. [ 14%]
openpyxl/chartsheet/tests/test_protection.py ... [ 14%]
openpyxl/chartsheet/tests/test_publish.py .... [ 14%]
openpyxl/chartsheet/tests/test_relation.py .... [ 14%]
openpyxl/chartsheet/tests/test_views.py .... [ 14%]
openpyxl/comments/tests/test_author.py .. [ 14%]
openpyxl/comments/tests/test_comment.py .... [ 14%]
openpyxl/comments/tests/test_comment_reader.py ... [ 14%]
openpyxl/comments/tests/test_comment_sheet.py ...... [ 15%]
openpyxl/comments/tests/test_shape_writer.py .... [ 15%]
openpyxl/compat/tests/test_compat.py ........s..... [ 15%]
openpyxl/descriptors/tests/test_base.py ................................................ [ 17%]
openpyxl/descriptors/tests/test_excel.py ................................ [ 19%]
openpyxl/descriptors/tests/test_namespace.py ... [ 19%]
openpyxl/descriptors/tests/test_nested.py ......................... [ 20%]
openpyxl/descriptors/tests/test_sequence.py ................... [ 20%]
openpyxl/descriptors/tests/test_serialisable.py ............... [ 21%]
openpyxl/drawing/tests/test_color.py ............ [ 22%]
openpyxl/drawing/tests/test_connector.py x. [ 22%]
openpyxl/drawing/tests/test_descriptors.py . [ 22%]
openpyxl/drawing/tests/test_drawing.py FFFFFFFF [ 22%]
openpyxl/drawing/tests/test_effect.py ...... [ 22%]
openpyxl/drawing/tests/test_fill.py ................. [ 23%]
openpyxl/drawing/tests/test_geometry.py ................ [ 24%]
openpyxl/drawing/tests/test_graphic.py ...........xx.. [ 24%]
openpyxl/drawing/tests/test_image.py s..... [ 24%]
openpyxl/drawing/tests/test_line.py ....... [ 25%]
openpyxl/drawing/tests/test_picture.py ........ [ 25%]
openpyxl/drawing/tests/test_properties.py .......... [ 25%]
openpyxl/drawing/tests/test_relation.py .. [ 25%]
openpyxl/drawing/tests/test_spreadsheet_drawing.py .......................... [ 26%]
openpyxl/drawing/tests/test_text.py .............. [ 27%]
openpyxl/formatting/tests/test_formatting.py ....... [ 27%]
openpyxl/formatting/tests/test_rule.py ................................ [ 29%]
openpyxl/formula/tests/test_tokenizer.py ............................................................................................................................................ [ 34%]
...................................................... [ 36%]
openpyxl/formula/tests/test_translate.py ......................................................................................................................... [ 41%]
openpyxl/packaging/tests/test_core.py ........ [ 41%]
openpyxl/packaging/tests/test_custom.py ............................... [ 43%]
openpyxl/packaging/tests/test_extended.py .. [ 43%]
openpyxl/packaging/tests/test_interface.py . [ 43%]
openpyxl/packaging/tests/test_manifest.py .................... [ 44%]
openpyxl/packaging/tests/test_pivot.py .. [ 44%]
openpyxl/packaging/tests/test_relationship.py ...... [ 44%]
openpyxl/packaging/tests/test_workbook.py ... [ 44%]
openpyxl/pivot/tests/test_cache.py .......................... [ 45%]
openpyxl/pivot/tests/test_fields.py .............. [ 46%]
openpyxl/pivot/tests/test_record.py ..... [ 46%]
openpyxl/pivot/tests/test_table.py ................x.................x [ 47%]
openpyxl/reader/tests/test_drawings.py .... [ 47%]
openpyxl/reader/tests/test_excel.py ............................... [ 49%]
openpyxl/reader/tests/test_strings.py ... [ 49%]
openpyxl/reader/tests/test_workbook.py ........... [ 49%]
openpyxl/styles/tests/test_alignments.py ... [ 49%]
openpyxl/styles/tests/test_borders.py .. [ 49%]
openpyxl/styles/tests/test_cell_style.py .......... [ 50%]
openpyxl/styles/tests/test_colors.py .................. [ 50%]
openpyxl/styles/tests/test_differential.py .... [ 51%]
openpyxl/styles/tests/test_fills.py ............................. [ 52%]
openpyxl/styles/tests/test_fonts.py .... [ 52%]
openpyxl/styles/tests/test_named_style.py ......................... [ 53%]
openpyxl/styles/tests/test_number_style.py .............................................................................. [ 56%]
openpyxl/styles/tests/test_protection.py .. [ 56%]
openpyxl/styles/tests/test_proxy.py ..... [ 56%]
openpyxl/styles/tests/test_styleable.py .......... [ 57%]
openpyxl/styles/tests/test_stylesheet.py .................... [ 58%]
openpyxl/styles/tests/test_table.py ...... [ 58%]
openpyxl/tests/test_backend.py .. [ 58%]
openpyxl/tests/test_iter.py ................................................... [ 60%]
openpyxl/tests/test_read.py ...... [ 60%]
openpyxl/tests/test_read_write_custom_doc_props.py .x [ 60%]
openpyxl/tests/test_vba.py .... [ 60%]
openpyxl/utils/tests/test_bound_dictionary.py ... [ 60%]
openpyxl/utils/tests/test_cell.py ..................................................................... [ 63%]
openpyxl/utils/tests/test_dataframe.py sssssss [ 63%]
openpyxl/utils/tests/test_datetime.py ................................................................................................ [ 67%]
openpyxl/utils/tests/test_escape.py .. [ 67%]
openpyxl/utils/tests/test_formulas.py .... [ 68%]
openpyxl/utils/tests/test_indexed_list.py ...... [ 68%]
openpyxl/utils/tests/test_inference.py .................. [ 69%]
openpyxl/utils/tests/test_protection.py . [ 69%]
openpyxl/utils/tests/test_units.py ......................................................................... [ 71%]
openpyxl/workbook/external_link/tests/test_external.py ......... [ 72%]
openpyxl/workbook/tests/test_child.py ..................... [ 73%]
openpyxl/workbook/tests/test_defined_name.py .................................... [ 74%]
openpyxl/workbook/tests/test_external_reference.py .. [ 74%]
openpyxl/workbook/tests/test_function_group.py .... [ 74%]
openpyxl/workbook/tests/test_properties.py ...... [ 75%]
openpyxl/workbook/tests/test_protection.py ..... [ 75%]
openpyxl/workbook/tests/test_smart_tags.py ...... [ 75%]
openpyxl/workbook/tests/test_views.py .... [ 75%]
openpyxl/workbook/tests/test_web.py ...... [ 75%]
openpyxl/workbook/tests/test_workbook.py ...........x............................. [ 77%]
openpyxl/workbook/tests/test_writer.py ............. [ 78%]
openpyxl/worksheet/tests/test_cell_range.py ........................................................... [ 80%]
openpyxl/worksheet/tests/test_controls.py .. [ 80%]
openpyxl/worksheet/tests/test_datavalidation.py ................... [ 81%]
openpyxl/worksheet/tests/test_dimensions.py ........................ [ 82%]
openpyxl/worksheet/tests/test_filters.py .............................. [ 83%]
openpyxl/worksheet/tests/test_formula.py .. [ 83%]
openpyxl/worksheet/tests/test_header.py .................. [ 84%]
openpyxl/worksheet/tests/test_hyperlink.py ..... [ 84%]
openpyxl/worksheet/tests/test_merge.py ............... [ 84%]
openpyxl/worksheet/tests/test_ole.py .. [ 85%]
openpyxl/worksheet/tests/test_page.py ........ [ 85%]
openpyxl/worksheet/tests/test_pagebreak.py ..... [ 85%]
openpyxl/worksheet/tests/test_print_settings.py ........................ [ 86%]
openpyxl/worksheet/tests/test_properties.py ... [ 86%]
openpyxl/worksheet/tests/test_protection.py ...... [ 86%]
openpyxl/worksheet/tests/test_read_only.py .................... [ 87%]
openpyxl/worksheet/tests/test_reader.py .......................................................................... [ 90%]
openpyxl/worksheet/tests/test_related.py . [ 90%]
openpyxl/worksheet/tests/test_scenario.py ...... [ 90%]
openpyxl/worksheet/tests/test_table.py ....................... [ 91%]
openpyxl/worksheet/tests/test_views.py ...... [ 92%]
openpyxl/worksheet/tests/test_worksheet.py ..................................................................................................... [ 96%]
openpyxl/worksheet/tests/test_worksheet_copy.py ............... [ 96%]
openpyxl/worksheet/tests/test_write_only.py .......... [ 97%]
openpyxl/worksheet/tests/test_writer.py ................................. [ 98%]
openpyxl/writer/tests/test_excel.py ............ [ 98%]
openpyxl/writer/tests/test_template.py ................ [ 99%]
openpyxl/xml/tests/test_functions.py ..ssss....... [100%]
========================================================================================= FAILURES ==========================================================================================
___________________________________________________________________________________ TestDrawing.test_ctor ___________________________________________________________________________________
self = <openpyxl.drawing.tests.test_drawing.TestDrawing object at 0x7f4607aee670>
def test_ctor(self):
> d = self.drawing
E AttributeError: 'TestDrawing' object has no attribute 'drawing'
self = <openpyxl.drawing.tests.test_drawing.TestDrawing object at 0x7f4607aee670>
/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/drawing/tests/test_drawing.py:17: AttributeError
__________________________________________________________________________________ TestDrawing.test_width ___________________________________________________________________________________
self = <openpyxl.drawing.tests.test_drawing.TestDrawing object at 0x7f4607aee040>
def test_width(self):
> d = self.drawing
E AttributeError: 'TestDrawing' object has no attribute 'drawing'
self = <openpyxl.drawing.tests.test_drawing.TestDrawing object at 0x7f4607aee040>
/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/drawing/tests/test_drawing.py:30: AttributeError
____________________________________________________________________________ TestDrawing.test_proportional_width ____________________________________________________________________________
self = <openpyxl.drawing.tests.test_drawing.TestDrawing object at 0x7f4607aee970>
def test_proportional_width(self):
> d = self.drawing
E AttributeError: 'TestDrawing' object has no attribute 'drawing'
self = <openpyxl.drawing.tests.test_drawing.TestDrawing object at 0x7f4607aee970>
/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/drawing/tests/test_drawing.py:36: AttributeError
__________________________________________________________________________________ TestDrawing.test_height __________________________________________________________________________________
self = <openpyxl.drawing.tests.test_drawing.TestDrawing object at 0x7f4607aee610>
def test_height(self):
> d = self.drawing
E AttributeError: 'TestDrawing' object has no attribute 'drawing'
self = <openpyxl.drawing.tests.test_drawing.TestDrawing object at 0x7f4607aee610>
/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/drawing/tests/test_drawing.py:43: AttributeError
___________________________________________________________________________ TestDrawing.test_proportional_height ____________________________________________________________________________
self = <openpyxl.drawing.tests.test_drawing.TestDrawing object at 0x7f4607aeedc0>
def test_proportional_height(self):
> d = self.drawing
E AttributeError: 'TestDrawing' object has no attribute 'drawing'
self = <openpyxl.drawing.tests.test_drawing.TestDrawing object at 0x7f4607aeedc0>
/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/drawing/tests/test_drawing.py:49: AttributeError
______________________________________________________________________________ TestDrawing.test_set_dimension _______________________________________________________________________________
self = <openpyxl.drawing.tests.test_drawing.TestDrawing object at 0x7f4607aeeee0>
def test_set_dimension(self):
> d = self.drawing
E AttributeError: 'TestDrawing' object has no attribute 'drawing'
self = <openpyxl.drawing.tests.test_drawing.TestDrawing object at 0x7f4607aeeee0>
/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/drawing/tests/test_drawing.py:56: AttributeError
_____________________________________________________________________________ TestDrawing.test_absolute_anchor ______________________________________________________________________________
self = <openpyxl.drawing.tests.test_drawing.TestDrawing object at 0x7f4607aeeb20>
@pytest.mark.pil_required
def test_absolute_anchor(self):
> node = self.drawing.anchor
E AttributeError: 'TestDrawing' object has no attribute 'drawing'
self = <openpyxl.drawing.tests.test_drawing.TestDrawing object at 0x7f4607aeeb20>
/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/drawing/tests/test_drawing.py:69: AttributeError
______________________________________________________________________________ TestDrawing.test_onecell_anchor ______________________________________________________________________________
self = <openpyxl.drawing.tests.test_drawing.TestDrawing object at 0x7f4607aea310>
@pytest.mark.pil_required
def test_onecell_anchor(self):
> self.drawing.anchortype = "oneCell"
E AttributeError: 'TestDrawing' object has no attribute 'drawing'
self = <openpyxl.drawing.tests.test_drawing.TestDrawing object at 0x7f4607aea310>
/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/drawing/tests/test_drawing.py:84: AttributeError
========================================================================================= XFAILURES =========================================================================================
______________________________________________________________________________________ test_timedelta _______________________________________________________________________________________
dummy_cell = <Cell 'Dummy Worksheet'.A1>
@pytest.mark.xfail
def test_timedelta(dummy_cell):
cell = dummy_cell
cell.value = timedelta(days=1, hours=3)
> assert cell.value == 1.125
E AssertionError: assert datetime.timedelta(days=1, seconds=10800) == 1.125
E + where datetime.timedelta(days=1, seconds=10800) = <Cell 'Dummy Worksheet'.A1>.value
cell = <Cell 'Dummy Worksheet'.A1>
dummy_cell = <Cell 'Dummy Worksheet'.A1>
openpyxl/cell/tests/test_cell.py:218: AssertionError
_______________________________________________________________________________ TestConnectorShape.test_ctor ________________________________________________________________________________
self = <openpyxl.drawing.tests.test_connector.TestConnectorShape object at 0x7f4607a9f520>, ConnectorShape = <class 'openpyxl.drawing.connector.ConnectorShape'>
@pytest.mark.xfail
def test_ctor(self, ConnectorShape):
> fut = ConnectorShape()
ConnectorShape = <class 'openpyxl.drawing.connector.ConnectorShape'>
self = <openpyxl.drawing.tests.test_connector.TestConnectorShape object at 0x7f4607a9f520>
/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/drawing/tests/test_connector.py:20:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/drawing/connector.py:95: in __init__
self.nvCxnSpPr = nvCxnSpPr
fPublished = None
macro = None
nvCxnSpPr = None
self = <openpyxl.drawing.connector.ConnectorShape object>
Parameters:
macro=None, fPublished=None, nvCxnSpPr=None, spPr=None, style=None
spPr = None
style = None
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Values must be of type <class 'openpyxl.drawing.connector.ConnectorNonVisual'>
instance = <openpyxl.drawing.connector.ConnectorShape object>
Parameters:
macro=None, fPublished=None, nvCxnSpPr=None, spPr=None, style=None, value = None
def __set__(self, instance, value):
if not isinstance(value, self.expected_type):
if (not self.allow_none
or (self.allow_none and value is not None)):
msg = f"{instance.__class__}.{self.name} should be {self.expected_type} but value is {type(value)}"
if DEBUG:
msg = f"{instance.__class__}.{self.name} should be {self.expected_type} but {value} is {type(value)}"
> raise TypeError(msg)
E TypeError: <class 'openpyxl.drawing.connector.ConnectorShape'>.nvCxnSpPr should be <class 'openpyxl.drawing.connector.ConnectorNonVisual'> but value is <class 'NoneType'>
__class__ = <class 'openpyxl.descriptors.base.Typed'>
instance = <openpyxl.drawing.connector.ConnectorShape object>
Parameters:
macro=None, fPublished=None, nvCxnSpPr=None, spPr=None, style=None
msg = "<class 'openpyxl.drawing.connector.ConnectorShape'>.nvCxnSpPr should be <class 'openpyxl.drawing.connector.ConnectorNonVisual'> but value is <class 'NoneType'>"
self = Values must be of type <class 'openpyxl.drawing.connector.ConnectorNonVisual'>
value = None
/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/descriptors/base.py:46: TypeError
_________________________________________________________________________________ TestGroupShape.test_ctor __________________________________________________________________________________
self = <openpyxl.drawing.tests.test_graphic.TestGroupShape object at 0x7f4607a04cd0>, GroupShape = <class 'openpyxl.drawing.graphic.GroupShape'>
@pytest.mark.xfail
def test_ctor(self, GroupShape):
> grp = GroupShape()
GroupShape = <class 'openpyxl.drawing.graphic.GroupShape'>
self = <openpyxl.drawing.tests.test_graphic.TestGroupShape object at 0x7f4607a04cd0>
/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/drawing/tests/test_graphic.py:197:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/drawing/graphic.py:175: in __init__
self.nvGrpSpPr = nvGrpSpPr
grpSpPr = None
nvGrpSpPr = None
pic = None
self = <[TypeError('can only concatenate tuple (not "list") to tuple') raised in repr()] GroupShape object at 0x7f4606e7a190>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Values must be of type <class 'openpyxl.drawing.properties.NonVisualGroupShape'>
instance = <[TypeError('can only concatenate tuple (not "list") to tuple') raised in repr()] GroupShape object at 0x7f4606e7a190>, value = None
def __set__(self, instance, value):
if not isinstance(value, self.expected_type):
if (not self.allow_none
or (self.allow_none and value is not None)):
msg = f"{instance.__class__}.{self.name} should be {self.expected_type} but value is {type(value)}"
if DEBUG:
msg = f"{instance.__class__}.{self.name} should be {self.expected_type} but {value} is {type(value)}"
> raise TypeError(msg)
E TypeError: <class 'openpyxl.drawing.graphic.GroupShape'>.nvGrpSpPr should be <class 'openpyxl.drawing.properties.NonVisualGroupShape'> but value is <class 'NoneType'>
__class__ = <class 'openpyxl.descriptors.base.Typed'>
instance = <[TypeError('can only concatenate tuple (not "list") to tuple') raised in repr()] GroupShape object at 0x7f4606e7a190>
msg = "<class 'openpyxl.drawing.graphic.GroupShape'>.nvGrpSpPr should be <class 'openpyxl.drawing.properties.NonVisualGroupShape'> but value is <class 'NoneType'>"
self = Values must be of type <class 'openpyxl.drawing.properties.NonVisualGroupShape'>
value = None
/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/descriptors/base.py:46: TypeError
_______________________________________________________________________________ TestGroupShape.test_from_xml ________________________________________________________________________________
self = <openpyxl.drawing.tests.test_graphic.TestGroupShape object at 0x7f4607b22e20>, GroupShape = <class 'openpyxl.drawing.graphic.GroupShape'>
@pytest.mark.xfail
def test_from_xml(self, GroupShape):
src = """
<xdr:grpSp xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<xdr:nvGrpSpPr>
<xdr:cNvPr id="14" name="Group 13"/>
<xdr:cNvGrpSpPr/>
</xdr:nvGrpSpPr>
<xdr:grpSpPr>
<a:xfrm>
<a:off x="0" y="394447"/>
<a:ext cx="1944896" cy="707294"/>
<a:chOff x="0" y="351692"/>
<a:chExt cx="1918002" cy="670746"/>
</a:xfrm>
</xdr:grpSpPr>
<xdr:sp macro="" textlink="">
<xdr:nvSpPr>
<xdr:cNvPr id="15" name="Rectangle 14"/>
<xdr:cNvSpPr/>
</xdr:nvSpPr>
<xdr:spPr>
<a:xfrm>
<a:off x="562916" y="377825"/>
<a:ext cx="182880" cy="137982"/>
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst/>
</a:prstGeom>
<a:solidFill>
<a:schemeClr val="accent3">
<a:lumMod val="60000"/>
<a:lumOff val="40000"/>
</a:schemeClr>
</a:solidFill>
<a:ln w="9525">
<a:solidFill>
<a:sysClr val="windowText" lastClr="000000"/>
</a:solidFill>
</a:ln>
</xdr:spPr>
<xdr:style>
<a:lnRef idx="2">
<a:schemeClr val="accent1">
<a:shade val="50000"/>
</a:schemeClr>
</a:lnRef>
<a:fillRef idx="1">
<a:schemeClr val="accent1"/>
</a:fillRef>
<a:effectRef idx="0">
<a:schemeClr val="accent1"/>
</a:effectRef>
<a:fontRef idx="minor">
<a:schemeClr val="lt1"/>
</a:fontRef>
</xdr:style>
<xdr:txBody>
<a:bodyPr vertOverflow="clip" horzOverflow="clip" rtlCol="0" anchor="t"/>
<a:lstStyle/>
<a:p>
<a:pPr algn="l"/>
<a:endParaRPr lang="en-US" sz="1100"/>
</a:p>
</xdr:txBody>
</xdr:sp>
</xdr:grpSp>
"""
node = fromstring(src)
grp = GroupShape.from_tree(node)
> assert grp == GroupShape()
GroupShape = <class 'openpyxl.drawing.graphic.GroupShape'>
grp = <[TypeError('can only concatenate tuple (not "list") to tuple') raised in repr()] GroupShape object at 0x7f4606f2b730>
node = <Element {http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing}grpSp at 0x7f4607171900>
self = <openpyxl.drawing.tests.test_graphic.TestGroupShape object at 0x7f4607b22e20>
src = '\n <xdr:grpSp xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"\n xmlns:a.../>\n </a:p>\n </xdr:txBody>\n </xdr:sp>\n </xdr:grpSp>\n\n '
/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/drawing/tests/test_graphic.py:278:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/drawing/graphic.py:175: in __init__
self.nvGrpSpPr = nvGrpSpPr
grpSpPr = None
nvGrpSpPr = None
pic = None
self = <[TypeError('can only concatenate tuple (not "list") to tuple') raised in repr()] GroupShape object at 0x7f4606f2b6a0>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Values must be of type <class 'openpyxl.drawing.properties.NonVisualGroupShape'>
instance = <[TypeError('can only concatenate tuple (not "list") to tuple') raised in repr()] GroupShape object at 0x7f4606f2b6a0>, value = None
def __set__(self, instance, value):
if not isinstance(value, self.expected_type):
if (not self.allow_none
or (self.allow_none and value is not None)):
msg = f"{instance.__class__}.{self.name} should be {self.expected_type} but value is {type(value)}"
if DEBUG:
msg = f"{instance.__class__}.{self.name} should be {self.expected_type} but {value} is {type(value)}"
> raise TypeError(msg)
E TypeError: <class 'openpyxl.drawing.graphic.GroupShape'>.nvGrpSpPr should be <class 'openpyxl.drawing.properties.NonVisualGroupShape'> but value is <class 'NoneType'>
__class__ = <class 'openpyxl.descriptors.base.Typed'>
instance = <[TypeError('can only concatenate tuple (not "list") to tuple') raised in repr()] GroupShape object at 0x7f4606f2b6a0>
msg = "<class 'openpyxl.drawing.graphic.GroupShape'>.nvGrpSpPr should be <class 'openpyxl.drawing.properties.NonVisualGroupShape'> but value is <class 'NoneType'>"
self = Values must be of type <class 'openpyxl.drawing.properties.NonVisualGroupShape'>
value = None
/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/descriptors/base.py:46: TypeError
______________________________________________________________________ TestPivotTableDefinition.test_formatted_fields _______________________________________________________________________
self = <openpyxl.pivot.tests.test_table.TestPivotTableDefinition object at 0x7f46078ef9d0>, TableDefinition = <class 'openpyxl.pivot.table.TableDefinition'>
datadir = local('/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/pivot/tests/data')
@pytest.mark.xfail
def test_formatted_fields(self, TableDefinition, datadir):
datadir.chdir()
> with open("table_with_conditional.xml", "rb") as src:
E FileNotFoundError: [Errno 2] No such file or directory: 'table_with_conditional.xml'
TableDefinition = <class 'openpyxl.pivot.table.TableDefinition'>
datadir = local('/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/pivot/tests/data')
self = <openpyxl.pivot.tests.test_table.TestPivotTableDefinition object at 0x7f46078ef9d0>
/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/pivot/tests/test_table.py:248: FileNotFoundError
___________________________________________________________________________ TestConditionalFormatList.test_dedupe ___________________________________________________________________________
self = <openpyxl.pivot.tests.test_table.TestConditionalFormatList object at 0x7f46078e99d0>, ConditionalFormatList = <class 'openpyxl.pivot.table.ConditionalFormatList'>
@pytest.mark.xfail
def test_dedupe(self, ConditionalFormatList):
src = """
<conditionalFormats count="3">
<conditionalFormat scope="data" priority="3">
<pivotAreas count="1">
<pivotArea outline="0" fieldPosition="0">
<references count="1">
<reference field="4294967294" count="1" selected="0">
<x v="0"/>
</reference>
</references>
</pivotArea>
</pivotAreas>
</conditionalFormat>
<conditionalFormat scope="data" priority="2">
<pivotAreas count="1">
<pivotArea outline="0" fieldPosition="0">
<references count="1">
<reference field="4294967294" count="1" selected="0">
<x v="1"/>
</reference>
</references>
</pivotArea>
</pivotAreas>
</conditionalFormat>
<conditionalFormat scope="data" priority="1">
<pivotAreas count="1">
<pivotArea outline="0" fieldPosition="0">
<references count="1">
<reference field="4294967294" count="1" selected="0">
<x v="1"/>
</reference>
</references>
</pivotArea>
</pivotAreas>
</conditionalFormat>
</conditionalFormats>
"""
node = fromstring(src)
fmts = ConditionalFormatList.from_tree(node)
fmts._dedupe()
xml = tostring(fmts.to_tree())
expected = """
<conditionalFormats count="2">
<conditionalFormat scope="data" priority="3">
<pivotAreas>
<pivotArea dataOnly="1" outline="0" fieldPosition="0" type="normal">
<references count="1">
<reference field="4294967294" selected="0">
<x v="0"/>
</reference>
</references>
</pivotArea>
</pivotAreas>
</conditionalFormat>
<conditionalFormat scope="data" priority="2">
<pivotAreas>
<pivotArea dataOnly="1" outline="0" fieldPosition="0" type="normal">
<references count="1">
<reference field="4294967294" selected="0">
<x v="1"/>
</reference>
</references>
</pivotArea>
</pivotAreas>
</conditionalFormat>
</conditionalFormats>
"""
diff = compare_xml(xml, expected)
> assert diff is None, diff
E AssertionError: Expected:
E <conditionalFormats count="2">
E <conditionalFormat priority="3" scope="data">
E <pivotAreas>
E <pivotArea dataOnly="1" fieldPosition="0" outline="0" type="normal">
E <references count="1">
E <reference field="4294967294" selected="0">
E <x v="0"></x>
E </reference>
E </references>
E </pivotArea>
E </pivotAreas>
E </conditionalFormat>
E <conditionalFormat priority="2" scope="data">
E <pivotAreas>
E <pivotArea dataOnly="1" fieldPosition="0" outline="0" type="normal">
E <references count="1">
E <reference field="4294967294" selected="0">
E <x v="1"></x>
E </reference>
E </references>
E </pivotArea>
E </pivotAreas>
E </conditionalFormat>
E </conditionalFormats>
E
E Got:
E <conditionalFormats count="2">
E <conditionalFormat priority="1" scope="data">
E <pivotAreas>
E <pivotArea dataOnly="1" fieldPosition="0" outline="0" type="normal">
E <references count="1">
E <reference field="4294967294" selected="0">
E <x v="1"></x>
E </reference>
E </references>
E </pivotArea>
E </pivotAreas>
E </conditionalFormat>
E <conditionalFormat priority="3" scope="data">
E <pivotAreas>
E <pivotArea dataOnly="1" fieldPosition="0" outline="0" type="normal">
E <references count="1">
E <reference field="4294967294" selected="0">
E <x v="0"></x>
E </reference>
E </references>
E </pivotArea>
E </pivotAreas>
E </conditionalFormat>
E </conditionalFormats>
E
E Diff:
E <conditionalFormats count="2">
E <conditionalFormat priority="3 (got: 1)" scope="data">
E <pivotAreas>
E <pivotArea dataOnly="1" fieldPosition="0" outline="0" type="normal">
E <references count="1">
E <reference field="4294967294" selected="0">
E <x v="0 (got: 1)"></x>
E </reference>
E </references>
E </pivotArea>
E </pivotAreas>
E </conditionalFormat>
E <conditionalFormat priority="2 (got: 3)" scope="data">
E <pivotAreas>
E <pivotArea dataOnly="1" fieldPosition="0" outline="0" type="normal">
E <references count="1">
E <reference field="4294967294" selected="0">
E <x v="1 (got: 0)"></x>
E </reference>
E </references>
E </pivotArea>
E </pivotAreas>
E </conditionalFormat>
E </conditionalFormats>
E
E assert 'Expected:\n <conditionalFormats count="2">\n <conditionalFormat priority="3" scope="data">\n <pivotAreas>\n ... </references>\n </pivotArea>\n </pivotAreas>\n </conditionalFormat>\n </conditionalFormats>\n' is None
ConditionalFormatList = <class 'openpyxl.pivot.table.ConditionalFormatList'>
diff = 'Expected:\n <conditionalFormats count="2">\n <conditionalFormat priority="3" scope="data">\n <pivotAreas>\n ... </references>\n </pivotArea>\n </pivotAreas>\n </conditionalFormat>\n </conditionalFormats>\n'
expected = '\n <conditionalFormats count="2">\n <conditionalFormat scope="data" priority="3">\n <pivotAreas>...\n </pivotArea>\n </pivotAreas>\n </conditionalFormat>\n </conditionalFormats>\n '
fmts = <openpyxl.pivot.table.ConditionalFormatList object>
Parameters:
count=2, conditionalFormat=[<openpyxl.pivot.table.Cond... stdDevPSubtotal=None, varSubtotal=None, varPSubtotal=None, x=[<openpyxl.pivot.fields.Index object>
Parameters:
v=0]]]]
node = <Element conditionalFormats at 0x7f4606aa7400>
self = <openpyxl.pivot.tests.test_table.TestConditionalFormatList object at 0x7f46078e99d0>
src = '\n <conditionalFormats count="3">\n <conditionalFormat scope="data" priority="3">\n <pivotArea... </pivotArea>\n </pivotAreas>\n </conditionalFormat>\n </conditionalFormats>\n '
xml = b'<conditionalFormats count="2"><conditionalFormat scope="data" priority="1"><pivotAreas><pivotArea type="normal" data...94" selected="0"><x v="0"/></reference></references></pivotArea></pivotAreas></conditionalFormat></conditionalFormats>'
/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/pivot/tests/test_table.py:642: AssertionError
________________________________________________________________________________ test_write_custom_doc_props ________________________________________________________________________________
datadir = local('/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/tests/data')
@pytest.mark.xfail
def test_write_custom_doc_props(datadir):
datadir.join("reader").chdir()
wb = load_workbook('example_vba_and_no_custom_doc_props.xlsm')
assert len(wb.custom_doc_props) == 0
> wb.custom_doc_props.add("PropName1", "2020-08-24T20:19:22Z", "date")
E AttributeError: 'CustomPropertyList' object has no attribute 'add'
datadir = local('/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/tests/data')
wb = <openpyxl.workbook.workbook.Workbook object at 0x7f460673bfd0>
/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/tests/test_read_write_custom_doc_props.py:38: AttributeError
_______________________________________________________________________________ test_set_invalid_active_index _______________________________________________________________________________
Workbook = <class 'openpyxl.workbook.workbook.Workbook'>
@pytest.mark.xfail
def test_set_invalid_active_index(Workbook):
wb = Workbook()
with pytest.raises(ValueError):
> wb.active = 1
E Failed: DID NOT RAISE <class 'ValueError'>
Workbook = <class 'openpyxl.workbook.workbook.Workbook'>
wb = <openpyxl.workbook.workbook.Workbook object at 0x7f4606a1ae80>
/home/tkloczko/rpmbuild/BUILD/openpyxl-3.1.2/openpyxl/workbook/tests/test_workbook.py:110: Failed
================================================================================== short test summary info ==================================================================================
SKIPPED [8] conftest.py:44: Pandas must be installed
SKIPPED [1] openpyxl/compat/tests/test_compat.py:68: condition: sys.version_info[0]>=3
SKIPPED [1] conftest.py:19: PIL is installed
SKIPPED [4] conftest.py:24: defusedxml is required to guard against these vulnerabilities
XFAIL openpyxl/cell/tests/test_cell.py::test_timedelta
XFAIL openpyxl/drawing/tests/test_connector.py::TestConnectorShape::test_ctor
XFAIL openpyxl/drawing/tests/test_graphic.py::TestGroupShape::test_ctor
XFAIL openpyxl/drawing/tests/test_graphic.py::TestGroupShape::test_from_xml
XFAIL openpyxl/pivot/tests/test_table.py::TestPivotTableDefinition::test_formatted_fields
XFAIL openpyxl/pivot/tests/test_table.py::TestConditionalFormatList::test_dedupe
XFAIL openpyxl/tests/test_read_write_custom_doc_props.py::test_write_custom_doc_props
XFAIL openpyxl/workbook/tests/test_workbook.py::test_set_invalid_active_index
FAILED openpyxl/drawing/tests/test_drawing.py::TestDrawing::test_ctor - AttributeError: 'TestDrawing' object has no attribute 'drawing'
FAILED openpyxl/drawing/tests/test_drawing.py::TestDrawing::test_width - AttributeError: 'TestDrawing' object has no attribute 'drawing'
FAILED openpyxl/drawing/tests/test_drawing.py::TestDrawing::test_proportional_width - AttributeError: 'TestDrawing' object has no attribute 'drawing'
FAILED openpyxl/drawing/tests/test_drawing.py::TestDrawing::test_height - AttributeError: 'TestDrawing' object has no attribute 'drawing'
FAILED openpyxl/drawing/tests/test_drawing.py::TestDrawing::test_proportional_height - AttributeError: 'TestDrawing' object has no attribute 'drawing'
FAILED openpyxl/drawing/tests/test_drawing.py::TestDrawing::test_set_dimension - AttributeError: 'TestDrawing' object has no attribute 'drawing'
FAILED openpyxl/drawing/tests/test_drawing.py::TestDrawing::test_absolute_anchor - AttributeError: 'TestDrawing' object has no attribute 'drawing'
FAILED openpyxl/drawing/tests/test_drawing.py::TestDrawing::test_onecell_anchor - AttributeError: 'TestDrawing' object has no attribute 'drawing'
=================================================================== 8 failed, 2483 passed, 14 skipped, 8 xfailed in 9.68s ===================================================================
```
</details>
<details>
<summary>List of installed modules in build env:</summary>
```console
Package Version
----------------------------- -----------
alabaster 0.7.16
attrs 23.2.0
Babel 2.14.0
build 1.1.1
charset-normalizer 3.3.2
click 8.1.7
cloudpickle 3.0.0
distro 1.9.0
dnf 4.19.0
docutils 0.20.1
editables 0.5
et_xmlfile 1.1.0
exceptiongroup 1.1.3
gpg 1.23.2
hatch-fancy-pypi-readme 24.1.0
hatch-vcs 0.4.0
hatchling 1.21.1
hypothesis 6.99.6
idna 3.6
imagesize 1.4.1
importlib_metadata 7.0.1
importlib_resources 6.3.1
incremental 22.10.0
iniconfig 2.0.0
installer 0.7.0
Jinja2 3.1.3
libdnf 0.73.0
lxml 5.1.0
markdown-it-py 3.0.0
MarkupSafe 2.1.3
mdit-py-plugins 0.4.0
mdurl 0.1.2
myst-parser 2.0.0
olefile 0.47
packaging 24.0
pathspec 0.12.1
pillow 10.2.0
pluggy 1.4.0
Pygments 2.17.2
pyproject_hooks 1.0.0
pytest 8.1.1
python-dateutil 2.9.0.post0
PyYAML 6.0.1
requests 2.31.0
setuptools 69.1.1
setuptools-scm 8.0.4
snowballstemmer 2.2.0
sortedcontainers 2.4.0
Sphinx 7.2.6
sphinx_rtd_theme 2.0.0
sphinxcontrib-applehelp 1.0.8
sphinxcontrib-devhelp 1.0.5
sphinxcontrib-htmlhelp 2.0.5
sphinxcontrib-jquery 4.1
sphinxcontrib-jsmath 1.0.1
sphinxcontrib-qthelp 1.0.7
sphinxcontrib-serializinghtml 1.1.10
sphinxcontrib-towncrier 0.4.0a0
tokenize_rt 5.2.0
tomli 2.0.1
towncrier 23.11.0
trove-classifiers 2024.3.13
typing_extensions 4.10.0
urllib3 1.26.18
wheel 0.43.0
zipp 3.17.0
zope.event 5.0
zope.interface 6.2
```
</details>
Please let me know if you need more details or want me to perform some diagnostics.https://foss.heptapod.net/openpyxl/openpyxl/-/issues/2161Issues with Pivot Cache2024-03-23T03:16:22ZsnippetIssues with Pivot Cache`CT_pCDSDTCEntries` Elements are choice, so should `allow_none`
`CT_Tuple` only `item` is required, rest should allow none.
Spec:
```
<complexType name="CT_PCDSDTCEntries">
<choice maxOccurs="unbounded">
<element name="m" type="CT_Mis...`CT_pCDSDTCEntries` Elements are choice, so should `allow_none`
`CT_Tuple` only `item` is required, rest should allow none.
Spec:
```
<complexType name="CT_PCDSDTCEntries">
<choice maxOccurs="unbounded">
<element name="m" type="CT_Missing"/>
<element name="n" type="CT_Number"/>
<element name="e" type="CT_Error"/>
<element name="s" type="CT_String"/>
</choice>
<attribute name="count" type="xsd:unsignedInt"/>
</complexType>
```
```
<complexType name="CT_Tuple">
<attribute name="fld" type="xsd:unsignedInt"/>
<attribute name="hier" type="xsd:unsignedInt"/>
<attribute name="item" type="xsd:unsignedInt" use="required"/>
</complexType>
```
Sample file:[sample5.xlsx](/uploads/406f96401e8974ba8a18f5e7a6744679/sample5.xlsx)
Tracking here so I don't lose it. I'll submit the merge on 3.1?snippetsnippethttps://foss.heptapod.net/openpyxl/openpyxl/-/issues/2160Comments are lost when loading existing xlsx files then saving2024-03-24T06:12:35ZMelanie LimComments are lost when loading existing xlsx files then saving#### Description
Comments are being lost when I load an existing file and save it, without any modifications.
#### Versions tested
* 3.1.2
* 3.0.10
#### Test code
```python
import openpyxl
print(openpyxl.__version__)
def run():
in...#### Description
Comments are being lost when I load an existing file and save it, without any modifications.
#### Versions tested
* 3.1.2
* 3.0.10
#### Test code
```python
import openpyxl
print(openpyxl.__version__)
def run():
input_path = "./comment-test-input.xlsx"
output_path = "./comment-test-output.xlsx"
wb = openpyxl.load_workbook(filename=input_path)
wb.save(output_path)
run()
```
#### Test file
[comment-test-input.xlsx](/uploads/39e8438f4108bf1029de8987be64ee8b/comment-test-input.xlsx)
#### Output file
[comment-test-output.xlsx](/uploads/5fb86f5a3939cea1912e7febe1995350/comment-test-output.xlsx)
#### Additional info
I am not sure if this is of any relevance, but when I filter for the `xml` files containing either of the strings, "comment" or "Comment", I see that there have been files "lost" from the input file and files "added" to the output file.
Running the following code snippet:
```python
from zipfile import ZipFile
import openpyxl
print(openpyxl.__version__)
def run():
input_path = "./comment-test-input.xlsx"
output_path = "./comment-test-output.xlsx"
wb = openpyxl.load_workbook(filename=input_path)
wb.save(output_path)
list_comment_xml_filenames(input_path, "input_file")
list_comment_xml_filenames(output_path, "output_file")
def list_comment_xml_filenames(filepath, id):
with ZipFile(filepath) as xlsx_file:
filenames = xlsx_file.namelist()
comment_filenames = filter(
lambda filename: "comment" in filename or "Comment" in filename,
filenames
)
print(f"{id}: {list(comment_filenames)}")
run()
```
Produces:
```python
input_file: ['xl/comments1.xml', 'xl/threadedComments/threadedComment1.xml']
output_file: ['xl/comments/comment1.xml', 'xl/drawings/commentsDrawing1.vml']
```https://foss.heptapod.net/openpyxl/openpyxl/-/issues/2158Version 3.0.10 can open excel files that are "Read-only recomended"2024-03-12T11:03:19ZMichaelRygaardVersion 3.0.10 can open excel files that are "Read-only recomended"This is my first time reporting an issue, so im sorry if im doing it wrong.
in Version 3.0.10 I can open all my files and get data (100 of files)
but any upgrade after that will give me
```
"ValueError: Unable to read workbook: could n...This is my first time reporting an issue, so im sorry if im doing it wrong.
in Version 3.0.10 I can open all my files and get data (100 of files)
but any upgrade after that will give me
```
"ValueError: Unable to read workbook: could not read worksheets from C:/py_excel/test.xlsm.
This is most probably because the workbook source files contain some invalid XML.
Please see the exception for more details."
```
downgrading back to 3.0.10 will make my scripts work again.
I have traced the problem to the prompt "The author would like you to open this as read-only. unless you need to make changes. open as read-only?"
this promt comes if you during save file in excel do this
1) save as
2) More Optionions
3) Tools
4) Geeneral options
5) mark as "Read-only recommended"
we have this set on some templates that are use every week so people dont overwrite the template by mistake.
I dont know what make openpyxl change how it handle this in later verions, but it would be nice if you could make this work in your updates.
Thank you verry much for a great lib.https://foss.heptapod.net/openpyxl/openpyxl/-/issues/2156ValueError: All strings must be XML compatible: Unicode or ASCII, no NULL byt...2024-03-06T16:43:22ZMichal ČihařValueError: All strings must be XML compatible: Unicode or ASCII, no NULL bytes or control charactersWhen saving certain files, we ended up with the following error:
```
File "weblate/formats/external.py", line 66, in save_content
workbook.save(handle)
File "openpyxl/workbook/workbook.py", line 386, in save
save_workbook(se...When saving certain files, we ended up with the following error:
```
File "weblate/formats/external.py", line 66, in save_content
workbook.save(handle)
File "openpyxl/workbook/workbook.py", line 386, in save
save_workbook(self, filename)
File "openpyxl/writer/excel.py", line 294, in save_workbook
writer.save()
File "openpyxl/writer/excel.py", line 275, in save
self.write_data()
File "openpyxl/writer/excel.py", line 77, in write_data
self._write_worksheets()
File "openpyxl/writer/excel.py", line 215, in _write_worksheets
self.write_worksheet(ws)
File "openpyxl/writer/excel.py", line 200, in write_worksheet
writer.write()
File "openpyxl/worksheet/_writer.py", line 359, in write
self.write_rows()
File "openpyxl/worksheet/_writer.py", line 125, in write_rows
self.write_row(xf, row, row_idx)
File "openpyxl/worksheet/_writer.py", line 147, in write_row
write_cell(xf, self.ws, cell, cell.has_style)
File "openpyxl/cell/_writer.py", line 130, in lxml_write_cell
el.text = value
File "src/lxml/etree.pyx", line 1048, in lxml.etree._Element.text.__set__
File "src/lxml/apihelpers.pxi", line 749, in lxml.etree._setNodeText
File "src/lxml/apihelpers.pxi", line 737, in lxml.etree._createTextNode
File "src/lxml/apihelpers.pxi", line 1530, in lxml.etree._utf8
ValueError: All strings must be XML compatible: Unicode or ASCII, no NULL bytes or control characters
```
The error is triggered by lxml because of some forbidden characters:
https://github.com/lxml/lxml/blob/3ccc7d583e325ceb0ebdf8fc295bbb7fc8cd404d/src/lxml/apihelpers.pxi#L1486
I think the following regexp should be extended to catch invalid values when setting the text instead of crashing with `ValueError` later when saving the file:
https://foss.heptapod.net/openpyxl/openpyxl/-/blob/branch/3.1/openpyxl/cell/cell.py#L45https://foss.heptapod.net/openpyxl/openpyxl/-/issues/2153CustomFilterValueDescriptor: Don't raise in case values only contain spaces2024-03-20T10:41:37ZSebastian WagnerCustomFilterValueDescriptor: Don't raise in case values only contain spacesEncountered this value error this when trying to read a (maybe somewhat invalid?) file. This patch helped me getting around this. I really can't give you the file and I also still don't have any idea where exactly this bad value appears....Encountered this value error this when trying to read a (maybe somewhat invalid?) file. This patch helped me getting around this. I really can't give you the file and I also still don't have any idea where exactly this bad value appears.
As I can neither fork or push to this repo, here is the patch:
```
$ hg tip -p
changeset: 9502:619eda28646e
tag: tip
topic: CustomFilterValueDescriptor-non-empty-values
parent: 9447:b1807ec23379
user: Sebastian Wagner
date: Thu Feb 22 15:20:01 2024 +0100
summary: CustomFilterValueDescriptor: Don't raise in case values contain spaces
diff -r b1807ec23379 -r 619eda28646e openpyxl/worksheet/filters.py
--- a/openpyxl/worksheet/filters.py Sat Mar 11 18:01:30 2023 +0100
+++ b/openpyxl/worksheet/filters.py Thu Feb 22 15:20:01 2024 +0100
@@ -160,9 +160,12 @@
def __set__(self, instance, value):
if isinstance(value, str):
- m = self.pattern.match(value)
- if not m:
- raise ValueError("Value must be either numerical or a string containing a wildcard")
+ if not value.strip():
+ self.expected_type = str
+ else:
+ m = self.pattern.match(value)
+ if not m:
+ raise ValueError(f"Value must be either numerical or a string containing a wildcard.")
if "*" in value:
self.expected_type = str
super().__set__(instance, value)
```https://foss.heptapod.net/openpyxl/openpyxl/-/issues/2148Incorrect value returned for width of not-customized column2024-03-06T23:36:52ZJean AllardIncorrect value returned for width of not-customized columnI have an issue with openpyxl when I verify the width of a column not customized.
In openpyxl the attribute active.column_dimensions["A"].width returns 13 but in Excel the column width is set to 10.71 (default value).
So, if baseColWid...I have an issue with openpyxl when I verify the width of a column not customized.
In openpyxl the attribute active.column_dimensions["A"].width returns 13 but in Excel the column width is set to 10.71 (default value).
So, if baseColWidth is equal to 10 in the XML file why do openpyxl return 13 as result?
Question: If my column "A" is not customized and has a default value, why openpyxl returns 13 with the instruction:
print(wb.active.column_dimensions["A"].width)
For a row not customized the instruction:
print(wb.active.row_dimensions[1].height)
returns None.
Openpyxl should return the values in variables baseColWidth and defaultRowHeight under the attribute sheet_format.
Thanks!https://foss.heptapod.net/openpyxl/openpyxl/-/issues/2147openpyxl 3.1.2 will not open workbook with PrintTitles set to "#N/A"2024-02-12T07:39:18ZSachin Saharanopenpyxl 3.1.2 will not open workbook with PrintTitles set to "#N/A"Version in use "version": "==3.1.2"
`openpyxl 3.1.2` raises error when we try to load a workbook with `PrintTitles` set as `#N/A`. This workbook was created using `openpyxl 3.0.9`. This seems like a backwards compatibility issue.
## **...Version in use "version": "==3.1.2"
`openpyxl 3.1.2` raises error when we try to load a workbook with `PrintTitles` set as `#N/A`. This workbook was created using `openpyxl 3.0.9`. This seems like a backwards compatibility issue.
## **How to Reproduce**
First create a workbook using `openpyxl 3.0.9` with `PrintTitles` set as `#N/A` :
```python
from openpyxl.workbook.defined_name import DefinedName
from openpyxl import Workbook
wb = Workbook()
print_titles = DefinedName(name='_xlnm.Print_Titles', attr_text='#N/A')
print_titles.localSheetId = 0
wb.defined_names.append(print_titles)
wb.save('file_path.xlsx')
```
Loading the above workbook using `openpyxl 3.0.9` works fine:
```python
# Works fine
wb = openpyxl.load_workbook('file_path.xlsx')
```
Loading the above workbook using `openpyxl 3.1.2` raises following error:
```python
wb = openpyxl.load_workbook('file_path.xlsx')
File .../python3.11/site-packages/openpyxl/reader/excel.py:303, in ExcelReader.read(self)
302 action = "assign names"
--> 303 self.parser.assign_names()
304 if not self.read_only:
File .../python-3.11/std/lib64/python3.11/site-packages/openpyxl/reader/workbook.py:111, in WorkbookParser.assign_names(self)
110 elif reserved == "Print_Titles":
--> 111 titles = PrintTitles.from_string(defn.value)
112 sheet._print_rows = titles.rows
File .../python3.11/site-packages/openpyxl/worksheet/print_settings.py:121, in PrintTitles.from_string(cls, value)
120 if not kw:
--> 121 raise ValueError(f"{value} is not a valid print titles definition")
123 cols = rows = None
ValueError: #N/A is not a valid print titles definition
The above exception was the direct cause of the following exception:
ValueError Traceback (most recent call last)
Cell In[1], line 1
----> 1 wb = openpyxl.load_workbook('file_path.xlsx')
File .../python3.11/site-packages/openpyxl/reader/excel.py:346, in load_workbook(filename, read_only, keep_vba, data_only, keep_links, rich_text)
316 """Open the given filename and return the workbook
317
318 :param filename: the path to open or a file-like object
(...)
342
343 """
344 reader = ExcelReader(filename, read_only, keep_vba,
345 data_only, keep_links, rich_text)
--> 346 reader.read()
347 return reader.wb
File .../python3.11/site-packages/openpyxl/reader/excel.py:307, in ExcelReader.read(self)
305 self.archive.close()
306 except ValueError as e:
--> 307 raise ValueError(
308 f"Unable to read workbook: could not {action} from {self.archive.filename}.\n"
309 "This is most probably because the workbook source files contain some invalid XML.\n"
310 "Please see the exception for more details."
311 ) from e
ValueError: Unable to read workbook: could not assign names from file_path.xlsx.
This is most probably because the workbook source files contain some invalid XML.
Please see the exception for more details.
```https://foss.heptapod.net/openpyxl/openpyxl/-/issues/2143Find a replacement for readthedocs2024-02-08T09:25:06ZCharlieCFind a replacement for readthedocsReadthedocs have announced that they will be dropping support for Mercurial repositories and thus, we won't be able to use it in the future.
I really, really hate the "common cold" argument that tries to force everyone to switch to git....Readthedocs have announced that they will be dropping support for Mercurial repositories and thus, we won't be able to use it in the future.
I really, really hate the "common cold" argument that tries to force everyone to switch to git. There were good reasons for not using it at the start, migration isn't trivial but most importantly: choice is good. It's one of the reasons that many of us chose to use Python in the first place. But I also don't understand the notional work of keeping support for Mercurial: it's really just about keeping a few packages around that someone else maintains.
So, first of all thanks to everyone behind Heptapod that meant we could keep the repo going with a minimum of work. I assume it should be possible to create a documentation website using it and we can use CI to generate the files.https://foss.heptapod.net/openpyxl/openpyxl/-/issues/2142Switch worksheet serialisation to async2024-02-08T09:19:57ZCharlieCSwitch worksheet serialisation to asyncNow that async is established in Python and we have 3.6 as a baseline, it's probably time to rewrite worksheet serialisation to use async code as this might make it slightly easier to maintain: I've always hated `yield from` as a way to ...Now that async is established in Python and we have 3.6 as a baseline, it's probably time to rewrite worksheet serialisation to use async code as this might make it slightly easier to maintain: I've always hated `yield from` as a way to implement coroutines.https://foss.heptapod.net/openpyxl/openpyxl/-/issues/2141Reading an image causes workbook.save() to fail with ValueError exception2024-02-08T09:17:12ZRaymond CôtéReading an image causes workbook.save() to fail with ValueError exceptionReading a worksheet image causes `workbook.save()` to fail with ValueError: I/O operation on closed file.
## How to Reproduce
Use the attached sample.xlsx file and following code to demonstrate the problem.
```python
import io
import ...Reading a worksheet image causes `workbook.save()` to fail with ValueError: I/O operation on closed file.
## How to Reproduce
Use the attached sample.xlsx file and following code to demonstrate the problem.
```python
import io
import openpyxl as pyxl
workbook = pyxl.load_workbook("./sample.xlsx")
sheet = workbook.worksheets[0]
image = sheet._images[0]
data = image._data
# Program works when the following line is commented out.
data()
workbook.save("./freddy.xlsx")
workbook.close()
```
## Environment
- Python: 3.11
- OpenPyxl: 3.1.2
- Pillow: 10.2.0
## Research
- The PIL Image `open` method in `PIL.Image.py` states,
"This is a lazy operation;…the file remains open and the actual image data is not read"
- `_import_image` in `openpyxl/drawing/image.py` is called three times:
- Once from `Image.__init__`
- Once when `Image._data` is explicitly called from `sample.py`
- Once when `Image._data` is called to save the workbook.
- The second call to `Image._data` fails with the ValueError.
- `Image.__init__` leaves the file handle open.
- `Image._data` closes the file handle.
## Proposed Solution
- I believe the `fp.close()` statement in `Image._data` should only be called when a new `BytesIO` stream is created in the `else` section of the `_data` method.
I've tested this and it is working in my environment but there may be side effects I don't understand.
```python
def _data(self):
"""
Return image data, convert to supported types if necessary
"""
img = _import_image(self.ref)
# don't convert these file formats
if self.format in ['gif', 'jpeg', 'png']:
img.fp.seek(0)
fp = img.fp
data = fp.read()
else:
fp = BytesIO()
img.save(fp, format="png")
fp.seek(0)
data = fp.read()
fp.close()
return data
```
This seems to also fix #2100: trying to save the file twice
## Version 3.2
Version 3.2 code requires the same change.
See Also:
- #2100: Excel file containing image gets corrupted when trying to save the excel file twice.
- #1989: File corrupted when saving workbook twice
- #1843: add image from other worksheet error
[sample.xlsx](/uploads/44241fb47e2a101aee7253107890f262/sample.xlsx)https://foss.heptapod.net/openpyxl/openpyxl/-/issues/2140Sheet Id is not correctly parsed, so sheet is skipped2024-02-05T13:27:15ZTiberio Galbiati (NO)Sheet Id is not correctly parsed, so sheet is skippedVersion in use
"version": "==3.1.2"
I was trying to load a workbook with one sheet, however the parser gets the sheet id==None, so the sheet is skipped
![Screenshot_2024-02-05_at_09.49.14](/uploads/9e8b2e9611d9de527c7c19aa75c82b13/Scre...Version in use
"version": "==3.1.2"
I was trying to load a workbook with one sheet, however the parser gets the sheet id==None, so the sheet is skipped
![Screenshot_2024-02-05_at_09.49.14](/uploads/9e8b2e9611d9de527c7c19aa75c82b13/Screenshot_2024-02-05_at_09.49.14.png)
## How to reproduce
Try load_workbook() with an excel file which has only one sheet, and the workbook xml looks like the following
### file xl>workbook.xml
```xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<workbook xmlns="http://purl.oclc.org/ooxml/spreadsheetml/main"
xmlns:r="http://purl.oclc.org/ooxml/officeDocument/relationships"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x15 xr xr6 xr10 xr2"
xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main"
xmlns:xr="http://schemas.microsoft.com/office/spreadsheetml/2014/revision"
xmlns:xr6="http://schemas.microsoft.com/office/spreadsheetml/2016/revision6"
xmlns:xr10="http://schemas.microsoft.com/office/spreadsheetml/2016/revision10"
xmlns:xr2="http://schemas.microsoft.com/office/spreadsheetml/2015/revision2" conformance="strict">
<fileVersion appName="xl" lastEdited="7" lowestEdited="7" rupBuild="26130"/>
<workbookPr dateCompatibility="0" defaultThemeVersion="166925"/>
<mc:AlternateContent xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
<mc:Choice Requires="x15">
<x15ac:absPath url="redacted"
xmlns:x15ac="http://schemas.microsoft.com/office/spreadsheetml/2010/11/ac"/>
</mc:Choice>
</mc:AlternateContent>
<xr:revisionPtr revIDLastSave="0" documentId="13_ncr:9_{5BF45F4F-316A-460A-8AC6-261162188940}"
xr6:coauthVersionLast="47" xr6:coauthVersionMax="47"
xr10:uidLastSave="{00000000-0000-0000-0000-000000000000}"/>
<bookViews>
<workbookView xWindow="12012" yWindow="-17580" windowWidth="30936" windowHeight="16776"
xr2:uid="{10D53B35-014D-4AD7-AA1E-DEB5905FF54A}"/>
</bookViews>
<sheets>
<sheet name="redacted" sheetId="1" r:id="rId1"/>
</sheets>
<calcPr calcId="191029"/>
<extLst>
<ext uri="{79F54976-1DA5-4618-B147-4CDE4B953A38}"
xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main">
<x14:workbookPr/>
</ext>
<ext uri="{140A7094-0E35-4892-8432-C4D2E57EDEB5}"
xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main">
<x15:workbookPr chartTrackingRefBase="1"/>
</ext>
<ext uri="{B58B0392-4F1F-4190-BB64-5DF3571DCE5F}"
xmlns:xcalcf="http://schemas.microsoft.com/office/spreadsheetml/2018/calcfeatures">
<xcalcf:calcFeatures>
<xcalcf:feature name="microsoft.com:RD"/>
<xcalcf:feature name="microsoft.com:Single"/>
<xcalcf:feature name="microsoft.com:FV"/>
<xcalcf:feature name="microsoft.com:CNMTM"/>
<xcalcf:feature name="microsoft.com:LET_WF"/>
<xcalcf:feature name="microsoft.com:LAMBDA_WF"/>
<xcalcf:feature name="microsoft.com:ARRAYTEXT_WF"/>
</xcalcf:calcFeatures>
</ext>
</extLst>
</workbook>
```https://foss.heptapod.net/openpyxl/openpyxl/-/issues/2135TypeError: expected <class 'openpyxl.styles.fills.Fill'>2024-01-30T09:59:15Zhb fuTypeError: expected <class 'openpyxl.styles.fills.Fill'>`python
class Fill(Serialisable):
"""Base class"""
tagname = "fill"
@classmethod
def from_tree(cls, el):
children = [c for c in el]
if not children:
return
ch...`python
class Fill(Serialisable):
"""Base class"""
tagname = "fill"
@classmethod
def from_tree(cls, el):
children = [c for c in el]
if not children:
return
child = children[0]
if "patternFill" in child.tag:
return PatternFill._from_tree(child)
return super(Fill, GradientFill).from_tree(child)
`
`python
def _convert(expected_type, value):
"""
Check value is of or can be converted to expected type.
"""
if not isinstance(value, expected_type):
try:
value = expected_type(value)
except:
raise TypeError('expected ' + str(expected_type))
return value
`
在from_tree返回None时,_convert没有办法实现Fill的init,Fill没有__init__方法https://foss.heptapod.net/openpyxl/openpyxl/-/issues/2132Add support for svgBlip extension2024-01-15T14:46:24ZAlexander SedovAdd support for svgBlip extensionWe use openpyxl at our company, and it's a lovely experience. However, one feature the base package is currently lacking is support for svgBlip (part of MS-ODRAWXML extension). It's an extension for Images that allows to specify SVG sour...We use openpyxl at our company, and it's a lovely experience. However, one feature the base package is currently lacking is support for svgBlip (part of MS-ODRAWXML extension). It's an extension for Images that allows to specify SVG source in addition to raster data.
Currently, I've written a bunch of moderately horrible monkey-patching (~70 lines) to get the job done, however, I'd like to make the code upstream-ready. Sadly that cannot really be done as a separate package, since to work, it requires changes to Blip (to serialize extLst tag properly) and SpreadsheetDrawing (maybe not strictly necessary - there might be a better place to populate the extension list - see also #1839).
If there's an interest in that and willingness to do a review, I would love to contribute my code.https://foss.heptapod.net/openpyxl/openpyxl/-/issues/2130Read xlsx file contains ole objects and save it make xlsx file corrupted or o...2024-01-18T11:23:12ZPandaaaa906Read xlsx file contains ole objects and save it make xlsx file corrupted or ole objects missing```python
from openpyxl.reader.excel import load_workbook
xlsx_fp = r"D:\xslx_with_ole.xlsx"
out_fp = r"D:\xslx_with_ole_processed.xlsx"
wb = load_workbook(xlsx_fp, keep_vba=True) # cause corrupted file
wb = load_workbook(xlsx_fp) ...```python
from openpyxl.reader.excel import load_workbook
xlsx_fp = r"D:\xslx_with_ole.xlsx"
out_fp = r"D:\xslx_with_ole_processed.xlsx"
wb = load_workbook(xlsx_fp, keep_vba=True) # cause corrupted file
wb = load_workbook(xlsx_fp) # cause ole missing
wb.save(out_fp)
```https://foss.heptapod.net/openpyxl/openpyxl/-/issues/2127BarChart `set_categories` shows unexpected, buggy behaviors2024-02-08T10:38:20ZGwonsoo CheBarChart `set_categories` shows unexpected, buggy behaviorsHi,
Below is a [code snippet](https://openpyxl.readthedocs.io/en/stable/charts/bar.html#vertical-horizontal-and-stacked-bar-charts) from the openpyxl document that shows the problem:
```
from openpyxl import Workbook
from openpyxl.chart...Hi,
Below is a [code snippet](https://openpyxl.readthedocs.io/en/stable/charts/bar.html#vertical-horizontal-and-stacked-bar-charts) from the openpyxl document that shows the problem:
```
from openpyxl import Workbook
from openpyxl.chart import (
Reference,
Series,
BarChart3D,
)
wb = Workbook()
ws = wb.active
rows = [
(None, 2013, 2014),
("Apples", 5, 4),
("Oranges", 6, 2),
("Pears", 8, 3)
]
for row in rows:
ws.append(row)
data = Reference(ws, min_col=2, min_row=1, max_col=3, max_row=4)
titles = Reference(ws, min_col=1, min_row=2, max_row=4)
chart = BarChart3D()
chart.title = "3D Bar Chart"
chart.add_data(data=data, titles_from_data=True) // here
chart.set_categories(titles) // here
ws.add_chart(chart, "E5")
wb.save("bar3d.xlsx")
```
The chart should be like this:
![Good](/uploads/7556f47d4a7e03c5f1742069f321986a/Good.png)
The problem is that if you change the order of `chart.add_data` and `chart.set_categories`, the categories (i.e., the labels for the x-axis items) don't show up properly in the resulting chart; they are labeled as integers (1, 2, ...), not the text (Apples, Oranges, ...). So, there's an unexpected, hidden dependency between `chart.add_data` and `chart.set_categories`, which is highly misleading and hard to find. Or put it differently, `chart.add_data` seems to override what `chart.set_categories` has done.
After changing the order of two commands, the chart looks like this:
![Bad](/uploads/6113a3a6fcb0735f7b3a54a0e9a1c471/Bad.png)
I think it's good to make it explicit and warn the users in the document.
Thanks a lot.
Best wishes,
Gwonsoohttps://foss.heptapod.net/openpyxl/openpyxl/-/issues/2125Hidden column not marked as such in column_dimensions2024-02-20T15:28:17ZSylvain ThénaultHidden column not marked as such in column_dimensionsIn the attached file ([test_openpyxl_hidden.xlsx](/uploads/85682868b9824f80d5fde5af7341872d/test_openpyxl_hidden.xlsx)), column AD is hidden while `sheet.column_dimensions["AD"].hidden == False`
Other hidden columns seem properly detected.In the attached file ([test_openpyxl_hidden.xlsx](/uploads/85682868b9824f80d5fde5af7341872d/test_openpyxl_hidden.xlsx)), column AD is hidden while `sheet.column_dimensions["AD"].hidden == False`
Other hidden columns seem properly detected.https://foss.heptapod.net/openpyxl/openpyxl/-/issues/2121loading a workbook fail when PrintTitles is NoneType2024-01-12T13:55:16ZAmmarloading a workbook fail when PrintTitles is NoneType**--- Logging error ---**
``` bash
Traceback (most recent call last):
File "d:\...\app\controller\functions.py", line 135, in excel2sqlite
wb = openpyxl.load_workbook(filename=path, data_only=True)
^^^^^^^^^^^^^^^^^^^^^^^^...**--- Logging error ---**
``` bash
Traceback (most recent call last):
File "d:\...\app\controller\functions.py", line 135, in excel2sqlite
wb = openpyxl.load_workbook(filename=path, data_only=True)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\...\Python\Python311\site-packages\openpyxl\reader\excel.py", line 346, in load_workbook
reader.read()
File "C:\...\Python\Python311\site-packages\openpyxl\reader\excel.py", line 303, in read
self.parser.assign_names()
File "C:\...\Python\Python311\site-packages\openpyxl\reader\workbook.py", line 111, in assign_names
titles = PrintTitles.from_string(defn.value)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\...\Python\Python311\site-packages\openpyxl\worksheet\print_settings.py", line 133, in from_string
return cls(cols=cols, rows=rows, title=title)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\...\Python\Python311\site-packages\openpyxl\worksheet\print_settings.py", line 112, in __init__
self.title = title
^^^^^^^^^^
File "C:\...\Python\Python311\site-packages\openpyxl\descriptors\base.py", line 46, in __set__
raise TypeError(msg)
TypeError: <class 'openpyxl.worksheet.print_settings.PrintTitles'>.title should be <class 'str'> but value is <class 'NoneType'>
```
**I added an if condition to the method _PrintTitles.from_string_ and it worked:**
``` python
@classmethod
def from_string(cls, value):
kw = dict((k, v) for match in TITLES_REGEX.finditer(value)
for k, v in match.groupdict().items() if v)
if not kw:
raise ValueError(f"{value} is not a valid print titles definition")
cols = rows = None
if "cols" in kw:
cols = ColRange(kw["cols"])
if "rows" in kw:
rows = RowRange(kw["rows"])
title = kw.get("quoted") or kw.get("notquoted")
title = title if title is not None else ""
return cls(cols=cols, rows=rows, title=title)
```https://foss.heptapod.net/openpyxl/openpyxl/-/issues/2118Add Python 3.13 to CI2023-12-01T09:42:38ZCharlieCAdd Python 3.13 to CICurrently stuck because lxml can't be built fix in place but will need new release https://bugs.launchpad.net/lxml/+bug/2040307. Possibly affects Pillow as well, though it seems that builds now.Currently stuck because lxml can't be built fix in place but will need new release https://bugs.launchpad.net/lxml/+bug/2040307. Possibly affects Pillow as well, though it seems that builds now.https://foss.heptapod.net/openpyxl/openpyxl/-/issues/2114Parsing support for Python in Excel2023-11-24T01:31:33ZSarah KaiserParsing support for Python in ExcelRecently the Excel developers launched a public preview of a new feature where you can run Python code in cells of an Excel workbook. From my initial testing there is no issues parsing and working with workbooks with the Python functions...Recently the Excel developers launched a public preview of a new feature where you can run Python code in cells of an Excel workbook. From my initial testing there is no issues parsing and working with workbooks with the Python functions, but it could be nice to be able to at least access the strings/code snippets that were originally used to get the stored value in the sheet. Mainly just looking to see if I could get a text string that represented the code, not necessarily write back in yet. I am interested in trying to figure out how to do this, is this a feature the team would be interested in?