diff --git a/docx/table.py b/docx/table.py index b3bc090fb..00e620e28 100644 --- a/docx/table.py +++ b/docx/table.py @@ -168,6 +168,11 @@ def _cells(self): col_count = self._column_count cells = [] for tc in self._tbl.iter_tcs(): + previousRowIncomplete = (tc.left == 0) and (len(cells) % col_count > 0) + if previousRowIncomplete: + missingCellCount = col_count - (len(cells) % col_count) + for i in range(0, missingCellCount): + cells.append(_Cell("w:tc", self)) for grid_span_idx in range(tc.grid_span): if tc.vMerge == ST_Merge.CONTINUE: cells.append(cells[-col_count]) diff --git a/tests/test_table.py b/tests/test_table.py index 1d2183fd6..efde43ccf 100644 --- a/tests/test_table.py +++ b/tests/test_table.py @@ -69,6 +69,11 @@ def it_provides_access_to_the_cells_in_a_row(self, row_cells_fixture): row_cells = table.row_cells(row_idx) assert row_cells == expected_cells + def it_detects_the_beginning_of_new_rows(self, inconsistet_col_span_fixture): + table, row_idx, col_idx, expected_text = inconsistet_col_span_fixture + cell = table.cell(row_idx, col_idx) + assert cell.text == expected_text + def it_knows_its_alignment_setting(self, alignment_get_fixture): table, expected_value = alignment_get_fixture assert table.alignment == expected_value @@ -269,6 +274,20 @@ def row_cells_fixture(self, _cells_, _column_count_): expected_cells = [3, 4, 5] return table, row_idx, expected_cells + @pytest.fixture + def inconsistet_col_span_fixture(self): + # the second row is missing one column + tbl_cxml = 'w:tbl/(w:tblGrid/(w:gridCol,w:gridCol,w:gridCol)' \ + + ',w:tr/(w:tc,w:tc/w:tcPr/w:gridSpan{w:val=2})' \ + + ',w:tr/(w:tc,w:tc/w:tcPr/w:gridSpan{w:val=1})' \ + + ',w:tr/(w:tc/w:p/w:r/w:t"correct cell",w:tc/w:tcPr/w:gridSpan{w:val=2})' \ + + ')' + table = Table(element(tbl_cxml), None) + row_idx = 2 + col_idx = 0 + expected_text = "correct cell" + return table, row_idx, col_idx, expected_text + @pytest.fixture def style_get_fixture(self, part_prop_): style_id = 'Barbaz'