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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy