Skip to content

Commit c39cf5f

Browse files
committed
bmk: add Bookmarks.next_id
1 parent fbb0639 commit c39cf5f

File tree

3 files changed

+27
-8
lines changed

3 files changed

+27
-8
lines changed

docx/bookmark.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,6 @@ def __iter__(self):
4646
def __len__(self):
4747
return len(self._finder.bookmark_pairs)
4848

49-
@lazyproperty
50-
def _finder(self):
51-
"""_DocumentBookmarkFinder instance for this document."""
52-
return _DocumentBookmarkFinder(self._document_part)
53-
5449
def get(self, name):
5550
"""Get bookmark based on its name.
5651
@@ -64,7 +59,15 @@ def get(self, name):
6459
@property
6560
def next_id(self):
6661
"""Return the next available int bookmark-id, unique in document-wide scope."""
67-
raise NotImplementedError
62+
bookmark_ids = tuple(bookmark.id for bookmark in self)
63+
if not bookmark_ids:
64+
return 1
65+
return max(bookmark_ids) + 1
66+
67+
@lazyproperty
68+
def _finder(self):
69+
"""_DocumentBookmarkFinder instance for this document."""
70+
return _DocumentBookmarkFinder(self._document_part)
6871

6972

7073
class _Bookmark(object):

features/doc-document.feature

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
Feature: Document properties and methods
2-
In order manipulate a Word document
2+
In order to manipulate a Word document
33
As a developer using python-docx
44
I need properties and methods on the Document object
55

6-
@wip
76
Scenario: Document.start_bookmark()
87
Given a Document object as document
98
When I assign bookmark = document.start_bookmark("Target")

tests/test_bookmark.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,15 @@ def but_it_raises_KeyError_when_no_bookmark_by_that_name(self, bookmark_, _iter_
121121
bookmarks.get("barfoo")
122122
assert e.value.args[0] == "Requested bookmark not found."
123123

124+
def it_knows_the_next_available_bookmark_id(self, next_id_fixture, _iter_):
125+
mock_bookmarks, expected_value = next_id_fixture
126+
_iter_.return_value = iter(mock_bookmarks)
127+
bookmarks = Bookmarks(None)
128+
129+
next_id = bookmarks.next_id
130+
131+
assert next_id is expected_value
132+
124133
def it_provides_access_to_its_bookmark_finder_to_help(
125134
self, document_part_, _DocumentBookmarkFinder_, finder_
126135
):
@@ -151,6 +160,14 @@ def contains_fixture(self, request):
151160
bookmark_.name = member_names[idx]
152161
return mock_bookmarks, name, expected_value
153162

163+
@pytest.fixture(params=[((), 1), ((1, 2, 3), 4), ((1, 3), 4), ((2, 42), 43)])
164+
def next_id_fixture(self, request):
165+
bookmark_ids, expected_value = request.param
166+
mock_bookmarks = tuple(
167+
instance_mock(request, _Bookmark, id=bmid) for bmid in bookmark_ids
168+
)
169+
return mock_bookmarks, expected_value
170+
154171
# fixture components ---------------------------------------------
155172

156173
@pytest.fixture

0 commit comments

Comments
 (0)