🌐 AI搜索 & 代理 主页
Skip to content

Commit 88ff3ca

Browse files
committed
comments: add Comments.__iter__()
1 parent 6c0024c commit 88ff3ca

File tree

4 files changed

+37
-5
lines changed

4 files changed

+37
-5
lines changed

features/doc-comments.feature

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ Feature: Document.comments
2525
| 4 |
2626

2727

28-
@wip
2928
Scenario: Comments.__iter__()
3029
Given a Comments object with 4 comments
3130
Then iterating comments yields 4 Comment objects

src/docx/blkcntnr.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@
1919

2020
if TYPE_CHECKING:
2121
import docx.types as t
22+
from docx.oxml.comments import CT_Comment
2223
from docx.oxml.document import CT_Body
2324
from docx.oxml.section import CT_HdrFtr
2425
from docx.oxml.table import CT_Tc
2526
from docx.shared import Length
2627
from docx.styles.style import ParagraphStyle
2728
from docx.table import Table
2829

29-
BlockItemElement: TypeAlias = "CT_Body | CT_HdrFtr | CT_Tc"
30+
BlockItemElement: TypeAlias = "CT_Body | CT_Comment | CT_HdrFtr | CT_Tc"
3031

3132

3233
class BlockItemContainer(StoryChild):

src/docx/comments.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
from __future__ import annotations
44

5-
from typing import TYPE_CHECKING
5+
from typing import TYPE_CHECKING, Iterator
66

77
from docx.blkcntnr import BlockItemContainer
88

99
if TYPE_CHECKING:
10-
from docx.oxml.comments import CT_Comments
10+
from docx.oxml.comments import CT_Comment, CT_Comments
1111
from docx.parts.comments import CommentsPart
1212

1313

@@ -18,6 +18,13 @@ def __init__(self, comments_elm: CT_Comments, comments_part: CommentsPart):
1818
self._comments_elm = comments_elm
1919
self._comments_part = comments_part
2020

21+
def __iter__(self) -> Iterator[Comment]:
22+
"""Iterator over the comments in this collection."""
23+
return (
24+
Comment(comment_elm, self._comments_part)
25+
for comment_elm in self._comments_elm.comment_lst
26+
)
27+
2128
def __len__(self) -> int:
2229
"""The number of comments in this collection."""
2330
return len(self._comments_elm.comment_lst)
@@ -36,3 +43,7 @@ class Comment(BlockItemContainer):
3643
Note that certain content like tables may not be displayed in the Word comment sidebar due to
3744
space limitations. Such "over-sized" content can still be viewed in the review pane.
3845
"""
46+
47+
def __init__(self, comment_elm: CT_Comment, comments_part: CommentsPart):
48+
super().__init__(comment_elm, comments_part)
49+
self._comment_elm = comment_elm

tests/test_comments.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import pytest
88

9-
from docx.comments import Comments
9+
from docx.comments import Comment, Comments
1010
from docx.opc.constants import CONTENT_TYPE as CT
1111
from docx.opc.packuri import PackURI
1212
from docx.oxml.comments import CT_Comments
@@ -42,6 +42,27 @@ def it_knows_how_many_comments_it_contains(self, cxml: str, count: int, package_
4242

4343
assert len(comments) == count
4444

45+
def it_is_iterable_over_the_comments_it_contains(self, package_: Mock):
46+
comments_elm = cast(CT_Comments, element("w:comments/(w:comment,w:comment)"))
47+
comments = Comments(
48+
comments_elm,
49+
CommentsPart(
50+
PackURI("/word/comments.xml"),
51+
CT.WML_COMMENTS,
52+
comments_elm,
53+
package_,
54+
),
55+
)
56+
57+
comment_iter = iter(comments)
58+
59+
comment1 = next(comment_iter)
60+
assert type(comment1) is Comment, "expected a `Comment` object"
61+
comment2 = next(comment_iter)
62+
assert type(comment2) is Comment, "expected a `Comment` object"
63+
with pytest.raises(StopIteration):
64+
next(comment_iter)
65+
4566
# -- fixtures --------------------------------------------------------------------------------
4667

4768
@pytest.fixture

0 commit comments

Comments
 (0)