Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 19175ad

Browse files
committed
comments: add Comment.paragraphs
Actual implementation is primarily inherited from `BlockItemContainer`, but support for those operations must be present in `CT_Comment` and it's worth testing explicitly.
1 parent cfb87e7 commit 19175ad

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

features/cmt-props.feature

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ Feature: Get comment properties
2424
Then comment.timestamp is the date and time the comment was authored
2525

2626

27-
@wip
2827
Scenario: Comment.paragraphs[0].text
2928
Given a Comment object
3029
When I assign para_text = comment.paragraphs[0].text

src/docx/oxml/comments.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,15 @@
33
from __future__ import annotations
44

55
import datetime as dt
6+
from typing import TYPE_CHECKING, Callable
67

78
from docx.oxml.simpletypes import ST_DateTime, ST_DecimalNumber, ST_String
89
from docx.oxml.xmlchemy import BaseOxmlElement, OptionalAttribute, RequiredAttribute, ZeroOrMore
910

11+
if TYPE_CHECKING:
12+
from docx.oxml.table import CT_Tbl
13+
from docx.oxml.text.paragraph import CT_P
14+
1015

1116
class CT_Comments(BaseOxmlElement):
1217
"""`w:comments` element, the root element for the comments part.
@@ -36,6 +41,7 @@ class CT_Comment(BaseOxmlElement):
3641
content, including multiple rich-text paragraphs, hyperlinks, images, and tables.
3742
"""
3843

44+
# -- attributes on `w:comment` --
3945
id: int = RequiredAttribute("w:id", ST_DecimalNumber) # pyright: ignore[reportAssignmentType]
4046
author: str = RequiredAttribute("w:author", ST_String) # pyright: ignore[reportAssignmentType]
4147
initials: str | None = OptionalAttribute( # pyright: ignore[reportAssignmentType]
@@ -44,3 +50,20 @@ class CT_Comment(BaseOxmlElement):
4450
date: dt.datetime | None = OptionalAttribute( # pyright: ignore[reportAssignmentType]
4551
"w:date", ST_DateTime
4652
)
53+
54+
# -- children --
55+
56+
p = ZeroOrMore("w:p", successors=())
57+
tbl = ZeroOrMore("w:tbl", successors=())
58+
59+
# -- type-declarations for methods added by metaclass --
60+
61+
add_p: Callable[[], CT_P]
62+
p_lst: list[CT_P]
63+
tbl_lst: list[CT_Tbl]
64+
_insert_tbl: Callable[[CT_Tbl], CT_Tbl]
65+
66+
@property
67+
def inner_content_elements(self) -> list[CT_P | CT_Tbl]:
68+
"""Generate all `w:p` and `w:tbl` elements in this comment."""
69+
return self.xpath("./w:p | ./w:tbl")

tests/test_comments.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,18 @@ def it_knows_the_date_and_time_it_was_authored(self, comments_part_: Mock):
123123

124124
assert comment.timestamp == dt.datetime(2023, 10, 1, 12, 34, 56, tzinfo=dt.timezone.utc)
125125

126+
def it_provides_access_to_the_paragraphs_it_contains(self, comments_part_: Mock):
127+
comment_elm = cast(
128+
CT_Comment,
129+
element('w:comment{w:id=42}/(w:p/w:r/w:t"First para",w:p/w:r/w:t"Second para")'),
130+
)
131+
comment = Comment(comment_elm, comments_part_)
132+
133+
paragraphs = comment.paragraphs
134+
135+
assert len(paragraphs) == 2
136+
assert [para.text for para in paragraphs] == ["First para", "Second para"]
137+
126138
# -- fixtures --------------------------------------------------------------------------------
127139

128140
@pytest.fixture

0 commit comments

Comments
 (0)