Skip to content

Commit c07bda9

Browse files
author
Steve Canny
committed
tbl: add _ColumnCollection magic methods
Along the way: * refactored Describe_RowCollection for enhanced precision. * replaced iter(list_comprehensions) in __iter__ methods with a generator expression.
1 parent c7e8c7e commit c07bda9

3 files changed

Lines changed: 84 additions & 22 deletions

File tree

docx/table.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def __getitem__(self, idx):
7575
return _Cell(tc)
7676

7777
def __iter__(self):
78-
return iter([_Cell(tc) for tc in self._tr.tc_lst])
78+
return (_Cell(tc) for tc in self._tr.tc_lst)
7979

8080
def __len__(self):
8181
return len(self._tr.tc_lst)
@@ -98,6 +98,32 @@ def __init__(self, tbl):
9898
super(_ColumnCollection, self).__init__()
9999
self._tbl = tbl
100100

101+
def __getitem__(self, idx):
102+
"""
103+
Provide indexed access, e.g. 'columns[0]'
104+
"""
105+
try:
106+
gridCol = self._gridCol_lst[idx]
107+
except IndexError:
108+
msg = "column index [%d] is out of range" % idx
109+
raise IndexError(msg)
110+
return _Column(gridCol)
111+
112+
def __iter__(self):
113+
return (_Column(gridCol) for gridCol in self._gridCol_lst)
114+
115+
def __len__(self):
116+
return len(self._gridCol_lst)
117+
118+
@property
119+
def _gridCol_lst(self):
120+
"""
121+
Sequence containing ``<w:gridCol>`` elements for this table, each
122+
representing a table column.
123+
"""
124+
tblGrid = self._tbl.tblGrid
125+
return tblGrid.gridCol_lst
126+
101127

102128
class _Row(object):
103129
"""
@@ -135,7 +161,7 @@ def __getitem__(self, idx):
135161
return _Row(tr)
136162

137163
def __iter__(self):
138-
return iter([_Row(tr) for tr in self._tbl.tr_lst])
164+
return (_Row(tr) for tr in self._tbl.tr_lst)
139165

140166
def __len__(self):
141167
return len(self._tbl.tr_lst)

features/tbl-item-access.feature

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,11 @@ Feature: Access table rows, columns, and cells
1313
Then I can iterate over the row collection
1414
And I can access a collection row by index
1515

16-
@wip
1716
Scenario: Access table column collection
1817
Given a table having two columns
1918
Then I can access the column collection of the table
2019
And the length of the column collection is 2
2120

22-
@wip
2321
Scenario: Access column in column collection
2422
Given a column collection having two columns
2523
Then I can iterate over the column collection

tests/test_table.py

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,45 @@ def cell_count_fixture(self):
104104
return cells, cell_count
105105

106106

107+
class Describe_ColumnCollection(object):
108+
109+
def it_knows_how_many_columns_it_contains(self, columns_fixture):
110+
columns, column_count = columns_fixture
111+
assert len(columns) == column_count
112+
113+
def it_can_interate_over_its__Column_instances(self, columns_fixture):
114+
columns, column_count = columns_fixture
115+
actual_count = 0
116+
for column in columns:
117+
assert isinstance(column, _Column)
118+
actual_count += 1
119+
assert actual_count == column_count
120+
121+
def it_provides_indexed_access_to_columns(self, columns_fixture):
122+
columns, column_count = columns_fixture
123+
for idx in range(-column_count, column_count):
124+
column = columns[idx]
125+
assert isinstance(column, _Column)
126+
127+
def it_raises_on_indexed_access_out_of_range(self, columns_fixture):
128+
columns, column_count = columns_fixture
129+
too_low = -1 - column_count
130+
too_high = column_count
131+
with pytest.raises(IndexError):
132+
columns[too_low]
133+
with pytest.raises(IndexError):
134+
columns[too_high]
135+
136+
# fixtures -------------------------------------------------------
137+
138+
@pytest.fixture
139+
def columns_fixture(self):
140+
column_count = 2
141+
tbl = _tbl_bldr(rows=2, cols=column_count).element
142+
columns = _ColumnCollection(tbl)
143+
return columns, column_count
144+
145+
107146
class Describe_Row(object):
108147

109148
def it_provides_access_to_the_row_cells(self, cells_access_fixture):
@@ -122,42 +161,41 @@ def cells_access_fixture(self):
122161

123162
class Describe_RowCollection(object):
124163

125-
def it_contains__Row_instances(self, row_count_fixture):
126-
table, row_count = row_count_fixture
164+
def it_knows_how_many_rows_it_contains(self, rows_fixture):
165+
rows, row_count = rows_fixture
166+
assert len(rows) == row_count
167+
168+
def it_can_iterate_over_its__Row_instances(self, rows_fixture):
169+
rows, row_count = rows_fixture
127170
actual_count = 0
128-
for row in table.rows:
171+
for row in rows:
129172
assert isinstance(row, _Row)
130173
actual_count += 1
131174
assert actual_count == row_count
132175

133-
def it_knows_how_many_rows_it_contains(self, row_count_fixture):
134-
table, row_count = row_count_fixture
135-
rows = table.rows
136-
assert len(rows) == row_count
137-
138-
def it_provides_indexed_access_to_rows(self, row_count_fixture):
139-
table, row_count = row_count_fixture
176+
def it_provides_indexed_access_to_rows(self, rows_fixture):
177+
rows, row_count = rows_fixture
140178
for idx in range(-row_count, row_count):
141-
row = table.rows[idx]
179+
row = rows[idx]
142180
assert isinstance(row, _Row)
143181

144-
def it_raises_on_indexed_access_out_of_range(self, row_count_fixture):
145-
table, row_count = row_count_fixture
182+
def it_raises_on_indexed_access_out_of_range(self, rows_fixture):
183+
rows, row_count = rows_fixture
146184
with pytest.raises(IndexError):
147185
too_low = -1 - row_count
148-
table.rows[too_low]
186+
rows[too_low]
149187
with pytest.raises(IndexError):
150188
too_high = row_count
151-
table.rows[too_high]
189+
rows[too_high]
152190

153191
# fixtures -------------------------------------------------------
154192

155193
@pytest.fixture
156-
def row_count_fixture(self):
194+
def rows_fixture(self):
157195
row_count = 2
158196
tbl = _tbl_bldr(rows=row_count, cols=2).element
159-
table = Table(tbl)
160-
return table, row_count
197+
rows = _RowCollection(tbl)
198+
return rows, row_count
161199

162200

163201
# fixtures -----------------------------------------------------------

0 commit comments

Comments
 (0)