Repository navigation
fix(xlsx): clip merged-cell and hyperlink ranges while loading workbooks - #4979
Merged
Merged
Conversation
openpyxl creates one MergedCell object for each covered cell of a merged range while it loads a worksheet. A single short <mergeCell> element such as A1:XFD1048576 can make it create billions of objects, and the table detection then widens to the same range. Load workbooks through openpyxl's ExcelReader with a per-workbook budget of covered merged cells. Ranges within the budget load unchanged. A range that does not fit is clipped to the cells with values in its worksheet, and to its top-left cell if it still does not fit. The hook is set on the workbook and worksheet instances of this load only. Signed-off-by: Michele Dolfi <dol@zurich.ibm.com>
openpyxl binds a ranged <hyperlink ref> by looking up the range on the worksheet. This creates a cell and a Hyperlink copy for every cell of the range, and sets the link target as the value of each empty cell, so the cells also become table data. A short element such as A1:J100000 makes openpyxl and the table detection do work for one million cells. Clip the range lookups that openpyxl does while a worksheet loads with the same approach as merged ranges, and a separate budget of 10,000 hyperlink cells per workbook. Ranges within the budget load unchanged. The worksheet methods are shadowed on the instances of this load only. Signed-off-by: Michele Dolfi <dol@zurich.ibm.com>
Contributor
|
✅ DCO Check Passed Thanks @dolfim-ibm, all your commits are properly signed off. 🎉 |
Contributor
Merge Protections🟢 Merge protection satisfied — ready to merge. Show 1 satisfied protection🟢 Enforce conventional commitMake sure that we follow https://www.conventionalcommits.org/en/v1.0.0/
|
Contributor
AI triage (advisory)Checked commit Warning The AI analysis did not finish. Only the deterministic checks are shown. Topic labels added: CI safety: not assessed. Possibly related pull requests
The |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
PeterStaar-IBM
approved these changes
Oct 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
While openpyxl loads a worksheet, it creates one
MergedCellobject for each covered cell of a merged range, and one cell with its ownHyperlinkcopy for each cell of a hyperlink range. A hyperlink also sets its target as the value of each empty cell, so these cells become table data. One short element such as<mergeCell ref="A1:XFD1048576"/>or<hyperlink ref="A1:J100000"/>makes openpyxl and the table detection do work for millions of cells.Changes
ExcelReader, with per-workbook budgets of 100,000 merged cells and 10,000 hyperlink cells._clean_merge_range,iter_rows,iter_cols) are set on the worksheet instances of this load only and removed afterwards. No openpyxl class or module attribute changes.Review note
The hooks rely on openpyxl 3.1.x internals (
ExcelReader.read_worksheets,Workbook.create_sheet,Worksheet._clean_merge_range). The tests with a whole-sheet merged range and a large hyperlink range measure the memory, so they fail if a future openpyxl version stops calling these hooks.Tests