Skip to content

Commit e2aec42

Browse files
committed
comments: add Comments.get()
To get a comment by id, None when not found.
1 parent 88ff3ca commit e2aec42

File tree

3 files changed

+32
-0
lines changed

3 files changed

+32
-0
lines changed

src/docx/comments.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ def __len__(self) -> int:
2929
"""The number of comments in this collection."""
3030
return len(self._comments_elm.comment_lst)
3131

32+
def get(self, comment_id: int) -> Comment | None:
33+
"""Return the comment identified by `comment_id`, or |None| if not found."""
34+
comment_elm = self._comments_elm.get_comment_by_id(comment_id)
35+
return Comment(comment_elm, self._comments_part) if comment_elm is not None else None
36+
3237

3338
class Comment(BlockItemContainer):
3439
"""Proxy for a single comment in the document.

src/docx/oxml/comments.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ class CT_Comments(BaseOxmlElement):
1919

2020
comment = ZeroOrMore("w:comment")
2121

22+
def get_comment_by_id(self, comment_id: int) -> CT_Comment | None:
23+
"""Return the `w:comment` element identified by `comment_id`, or |None| if not found."""
24+
comment_elms = self.xpath(f"(./w:comment[@w:id='{comment_id}'])[1]")
25+
return comment_elms[0] if comment_elms else None
26+
2227

2328
class CT_Comment(BaseOxmlElement):
2429
"""`w:comment` element, representing a single comment.

tests/test_comments.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# pyright: reportPrivateUsage=false
2+
13
"""Unit test suite for the docx.comments module."""
24

35
from __future__ import annotations
@@ -63,6 +65,26 @@ def it_is_iterable_over_the_comments_it_contains(self, package_: Mock):
6365
with pytest.raises(StopIteration):
6466
next(comment_iter)
6567

68+
def it_can_get_a_comment_by_id(self, package_: Mock):
69+
comments_elm = cast(
70+
CT_Comments,
71+
element("w:comments/(w:comment{w:id=1},w:comment{w:id=2},w:comment{w:id=3})"),
72+
)
73+
comments = Comments(
74+
comments_elm,
75+
CommentsPart(
76+
PackURI("/word/comments.xml"),
77+
CT.WML_COMMENTS,
78+
comments_elm,
79+
package_,
80+
),
81+
)
82+
83+
comment = comments.get(2)
84+
85+
assert type(comment) is Comment, "expected a `Comment` object"
86+
assert comment._comment_elm is comments_elm.comment_lst[1]
87+
6688
# -- fixtures --------------------------------------------------------------------------------
6789

6890
@pytest.fixture

0 commit comments

Comments
 (0)