python-docx-oss 0.3.1__py3-none-any.whl → 0.3.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
docx/__init__.py CHANGED
@@ -13,7 +13,7 @@ from docx.api import Document
13
13
  if TYPE_CHECKING:
14
14
  from docx.opc.part import Part
15
15
 
16
- __version__ = "0.3.1"
16
+ __version__ = "0.3.2"
17
17
 
18
18
 
19
19
  __all__ = ["Document"]
@@ -37,9 +37,9 @@ class CT_Hyperlink(BaseOxmlElement):
37
37
  return self.xpath("./w:r/w:lastRenderedPageBreak")
38
38
 
39
39
  @property
40
- def text(self) -> str: # pyright: ignore[reportIncompatibleMethodOverride]
40
+ def texts(self) -> str:
41
41
  """The textual content of this hyperlink.
42
42
 
43
43
  `CT_Hyperlink` stores the hyperlink-text as one or more `w:r` children.
44
44
  """
45
- return "".join(r.text for r in self.xpath("w:r"))
45
+ return "".join(r.texts for r in self.xpath("w:r"))
@@ -93,13 +93,13 @@ class CT_P(BaseOxmlElement):
93
93
  pPr.style = style
94
94
 
95
95
  @property
96
- def text(self): # pyright: ignore[reportIncompatibleMethodOverride]
96
+ def texts(self) -> str:
97
97
  """The textual content of this paragraph.
98
98
 
99
99
  Inner-content child elements like `w:r` and `w:hyperlink` are translated to
100
100
  their text equivalent.
101
101
  """
102
- return "".join(e.text for e in self.xpath("w:r | w:hyperlink"))
102
+ return "".join(e.texts for e in self.xpath("w:r | w:hyperlink"))
103
103
 
104
104
  def _insert_pPr(self, pPr: CT_PPr) -> CT_PPr:
105
105
  self.insert(0, pPr)
docx/oxml/text/run.py CHANGED
@@ -127,29 +127,25 @@ class CT_R(BaseOxmlElement):
127
127
  rPr.style = style
128
128
 
129
129
  @property
130
- def text(self) -> str:
130
+ def texts(self) -> str:
131
131
  """The textual content of this run.
132
132
 
133
133
  Inner-content child elements like `w:tab` are translated to their text
134
134
  equivalent.
135
+
136
+ Note: We intentionally do NOT define `@property def text` on CT_R or any
137
+ other oxml element, because doing so overrides lxml's Cython descriptor
138
+ `_Element.text`, which corrupts lxml `itertext()` on parent elements (such
139
+ as bare `_Element` revision tags `w:ins`, `w:del`, etc.).
135
140
  """
136
141
  return "".join(
137
142
  str(e) for e in self.xpath("w:br | w:cr | w:noBreakHyphen | w:ptab | w:t | w:tab")
138
143
  )
139
144
 
140
- @text.setter
141
- def text(self, text: str): # pyright: ignore[reportIncompatibleMethodOverride]
142
- self.clear_content()
143
- _RunContentAppender.append_to_run_from_text(self, text)
144
-
145
- @property
146
- def texts(self) -> str:
147
- """Alias for `text` property for compatibility with python-docx-oss."""
148
- return self.text
149
-
150
145
  @texts.setter
151
146
  def texts(self, text: str):
152
- self.text = text
147
+ self.clear_content()
148
+ _RunContentAppender.append_to_run_from_text(self, text)
153
149
 
154
150
  def _insert_rPr(self, rPr: CT_RPr) -> CT_RPr:
155
151
  self.insert(0, rPr)
docx/oxml/xmlchemy.py CHANGED
@@ -5,7 +5,7 @@
5
5
  from __future__ import annotations
6
6
 
7
7
  import re
8
- from typing import TYPE_CHECKING, Any, Callable, Iterator, Sequence, Type, TypeVar
8
+ from typing import TYPE_CHECKING, Any, Callable, Sequence, Type, TypeVar
9
9
 
10
10
  from lxml import etree
11
11
  from lxml.etree import ElementBase, _Element # pyright: ignore[reportPrivateUsage]
@@ -653,11 +653,6 @@ class ZeroOrOneChoice(_BaseChildElement):
653
653
  return "_remove_%s" % self._prop_name
654
654
 
655
655
 
656
- # -- raw lxml text/tail accessors, used to bypass `.text` property overrides --
657
- _raw_text = _Element.text.__get__
658
- _raw_tail = _Element.tail.__get__
659
-
660
-
661
656
  # -- lxml typing isn't quite right here, just ignore this error on _Element --
662
657
  class BaseOxmlElement(etree.ElementBase, metaclass=MetaOxmlElement):
663
658
  """Effective base class for all custom element classes.
@@ -688,22 +683,6 @@ class BaseOxmlElement(etree.ElementBase, metaclass=MetaOxmlElement):
688
683
  self.append(elm)
689
684
  return elm
690
685
 
691
- def itertext(self, tag: Any | None = None, *tags: Any, with_tail: bool = True) -> Iterator[str]:
692
- """Iterate over text content of this element and its descendants.
693
-
694
- Bypasses the overridden `.text` properties on custom oxml element classes (such as
695
- `CT_P`, `CT_R`, `CT_Hyperlink`), which would otherwise duplicate text, so standard
696
- lxml `itertext()` semantics are preserved.
697
- """
698
- for node in self.iter(tag, *tags):
699
- text = _raw_text(node)
700
- if text:
701
- yield text
702
- if with_tail and node is not self:
703
- tail = _raw_tail(node)
704
- if tail:
705
- yield tail
706
-
707
686
  def remove_all(self, *tagnames: str) -> None:
708
687
  """Remove child elements with tagname (e.g. "a:p") in `tagnames`."""
709
688
  for tagname in tagnames:
docx/table.py CHANGED
@@ -281,7 +281,7 @@ class _Cell(BlockItemContainer):
281
281
  tc.clear_content()
282
282
  p = tc.add_p()
283
283
  r = p.add_r()
284
- r.text = text
284
+ r.texts = text
285
285
 
286
286
  @property
287
287
  def vertical_alignment(self):
docx/text/hyperlink.py CHANGED
@@ -98,7 +98,7 @@ class Hyperlink(Parented):
98
98
  respectively. Note that rendered page-breaks can occur within a hyperlink but
99
99
  they are not reflected in this text.
100
100
  """
101
- return self._hyperlink.text
101
+ return self._hyperlink.texts
102
102
 
103
103
  @property
104
104
  def url(self) -> str:
docx/text/paragraph.py CHANGED
@@ -160,7 +160,7 @@ class Paragraph(StoryChild):
160
160
  character is mapped to a line break. Paragraph-level formatting, such as style,
161
161
  is preserved. All run-level formatting, such as bold or italic, is removed.
162
162
  """
163
- return self._p.text
163
+ return self._p.texts
164
164
 
165
165
  @text.setter
166
166
  def text(self, text: str | None):
docx/text/run.py CHANGED
@@ -233,11 +233,11 @@ class Run(StoryChild):
233
233
  `<w:cr/>` element. Any existing run content is replaced. Run formatting is
234
234
  preserved.
235
235
  """
236
- return self._r.text
236
+ return self._r.texts
237
237
 
238
238
  @text.setter
239
239
  def text(self, text: str):
240
- self._r.text = text
240
+ self._r.texts = text
241
241
 
242
242
  @property
243
243
  def underline(self) -> bool | WD_UNDERLINE | None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-docx-oss
3
- Version: 0.3.1
3
+ Version: 0.3.2
4
4
  Summary: Create, read, and update Microsoft Word .docx files.
5
5
  Author: Ethan St Lee
6
6
  License-Expression: MIT
@@ -155,6 +155,11 @@ available through `Document.add_float_picture()` and `Run.add_float_picture()`.
155
155
 
156
156
  - The project maintains broad compatibility with the public `python-docx` API while
157
157
  following its own versioning and product roadmap.
158
+ - Clean lxml integration: Low-level OXML elements avoid shadowing lxml's Cython
159
+ `_Element.text` descriptor (using `.texts` internally). This guarantees that standard
160
+ `element.itertext()` on parent elements and untyped revision nodes (`w:ins`, `w:del`,
161
+ `w:txbxContent`) never duplicates text, while high-level proxy APIs (`paragraph.text`,
162
+ `run.text`) remain fully compatible with `python-docx`.
158
163
  - Compatibility does not extend to every private or internal `python-docx` API. Test
159
164
  those integrations before migrating production systems.
160
165
  - The SDK focuses exclusively on DOCX. It is not a general XLSX/PPTX Office suite.
@@ -1,4 +1,4 @@
1
- docx/__init__.py,sha256=AL2CZNiK_a766gdK59Vvj4oV-6swa9kKNaap3FfZKco,2102
1
+ docx/__init__.py,sha256=X3x8P22c_YHltfHJxey1Nh8592hDDCnPKEr6ErJn4Ls,2102
2
2
  docx/api.py,sha256=jIojXW4IRDEXQqaqvmOZbzBvNeyRXv9ntHByxd-Kb0M,1518
3
3
  docx/blkcntnr.py,sha256=_xe7Uz3RBCz4TPKXpIzRxtGg-1YPb3gAG9YvsSUyoLU,3525
4
4
  docx/comments.py,sha256=MmaP7U9mZOUFsRhaZNIbXatqOOA8-pOC6UlqWAuTHsc,6385
@@ -10,7 +10,7 @@ docx/section.py,sha256=r2SLP6EXCtHPmv8PtaTuYZg1Wy8l9MoVHlA9JHT3SiA,18412
10
10
  docx/settings.py,sha256=tWJUOj3KABgk_3bXoxhIHVWVY5HmmKKl2tsqic2YN_c,1082
11
11
  docx/shape.py,sha256=5agasreXHsVIOdd1z8d-3erPvlsbBRJQjHQ0ILSfeaI,2969
12
12
  docx/shared.py,sha256=N6YIJKiQev-0XIC0ND9fJg1eVt1mG_MELnTawf_e-9g,13506
13
- docx/table.py,sha256=EFxbVD3aEbLOqdes5cpGt3xXbPzbZLFG0Sl5OPHSrhY,19477
13
+ docx/table.py,sha256=b2Z8Q8E3IIMLNh6IQCQmUHrD8Hs0HGpwqVS8hJOqLlU,19478
14
14
  docx/types.py,sha256=BgnXlRS-roPaNF1pbQX4ZO1AHqIIjIN7qMwAcaDniSE,848
15
15
  docx/dml/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  docx/dml/color.py,sha256=O7xeVwtCbOPW1aNKSHEBqcxpYnOUFMjKKv2vc2riJGo,4439
@@ -70,15 +70,15 @@ docx/oxml/shared.py,sha256=iAqDOcy-DnOm5GGsSZXLSemNejSqCjlzhB86lPEtDYM,1857
70
70
  docx/oxml/simpletypes.py,sha256=2pD4vgEZThJpCB4M-L8hP7uTIXglndlZRdNruvDZwm0,13019
71
71
  docx/oxml/styles.py,sha256=1U24kcC9hhzMPzNcg19RVCUJl1_qWauXCJIHG_Kp0Io,10643
72
72
  docx/oxml/table.py,sha256=qS46a_Ts3KzNygUNeUxaTIVNDJZbbWNJqMseo3ZVaRA,33610
73
- docx/oxml/xmlchemy.py,sha256=5cahsGwUamMOWLo2CzdVZb6mrlFWgZbDGpxXef4NZ4g,27042
73
+ docx/oxml/xmlchemy.py,sha256=QFJNxaM6YQeozA238LNhRu_1j_NqZgta7aiPxCsQ0Rs,26192
74
74
  docx/oxml/dml/CT_ExtensionList.py,sha256=drQvDl9Zo10H1JMtHdI8AUxlX0U0NFPKwIyHAlUhDTk,1216
75
75
  docx/oxml/text/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
76
76
  docx/oxml/text/font.py,sha256=s5MJwoei24s1xdhtsI1P02wqI6mLpvkLTCXr73EWNWI,11900
77
- docx/oxml/text/hyperlink.py,sha256=tx6SQiYaa123-a0JfUS80mtACOYwNoy24Trga2Shgn8,1467
77
+ docx/oxml/text/hyperlink.py,sha256=wcyip51zHHPPCLFRVBGmItFf6xxOYI8QD0Jyvjrzx4c,1416
78
78
  docx/oxml/text/pagebreak.py,sha256=1iK12GAowZpFRjVAmnZ_Mpqn7O0PqPSrVc2myUc4KM4,11192
79
- docx/oxml/text/paragraph.py,sha256=op4Cy4LjcSIxDD1CQIKeRbUsBL5ABVR8cYKb3KynlmQ,3538
79
+ docx/oxml/text/paragraph.py,sha256=eIopq-H6EbtCPxWbiS_wBSf8RvZeQ2Q7OJv7-Hyt3gM,3494
80
80
  docx/oxml/text/parfmt.py,sha256=5TYCf-QfcwlECXUkrLSYFfewFA1JieKGTtm3X01fu64,12221
81
- docx/oxml/text/run.py,sha256=W8vwOomvk1oGzAq2BqDgyVftKsSi5LK9_vlADVcMgpg,11238
81
+ docx/oxml/text/run.py,sha256=pz8GAWT0uUq-V70fxFGKt1Q64zHGQW_d59GjyXfc4cA,11275
82
82
  docx/parts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
83
83
  docx/parts/comments.py,sha256=Dmxh_i8ADRo-wLfO9LV0Lyho5XC_76oU1NJN8itw8lc,1760
84
84
  docx/parts/customxml.py,sha256=hbwDmPwR-1RRLOOFhmiPd0B-dNwpfZFrOxIaGU4UlG4,1920
@@ -122,14 +122,14 @@ docx/templates/default-docx-template/word/_rels/document.xml.rels,sha256=Tyt7R9i
122
122
  docx/templates/default-docx-template/word/theme/theme1.xml,sha256=46irfbnKevylb18oIKVui2YAFsZHdzVVsGCwoCrHaUE,10939
123
123
  docx/text/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
124
124
  docx/text/font.py,sha256=AJI05dO5nUSXsutxHNsquZkqdCA33x68ovi3IV4C1nc,14854
125
- docx/text/hyperlink.py,sha256=H7YGCH85i7EDcPQcYoLh4MOx_w-xNSucA5bAgI3HtVQ,5257
125
+ docx/text/hyperlink.py,sha256=bWU9yHEDrHK5Vngj35EuSJkANd593-6LgJji1Vo6FTo,5258
126
126
  docx/text/pagebreak.py,sha256=sI1yMVotkBtn1u5DJ9L04FkC01QoAwcyVSdgGPAkJIY,4950
127
- docx/text/paragraph.py,sha256=N3F62_JRQZYaumuoaJXKCDnRSw2DIiOwzyMPV2Jd7GI,6828
127
+ docx/text/paragraph.py,sha256=5caYCpNr9D-6pnk0aE5_HBkx5Bkc3VUWaj6u115Z9i8,6829
128
128
  docx/text/parfmt.py,sha256=70M75HFo7ydpqmIdZjkV711muyrsBGdr4WZscF3YVJY,10339
129
- docx/text/run.py,sha256=tsW8dXOE4VnqEM7cJz_uU2Vq3qgdnrMGzyDq9x5jvE4,10800
129
+ docx/text/run.py,sha256=QtIRn3mW_MMLgbRIfJhRmnKpDfcq7VnJEQKn1pfsY78,10802
130
130
  docx/text/tabstops.py,sha256=bJN98GWW22f4Sqg0dQbyUcnuOn65fHsNZuCGswI03_c,3896
131
- python_docx_oss-0.3.1.dist-info/licenses/LICENSE,sha256=lf2yZv-riPwFeah3IMDeG0zqI6fXcV9T9YOToeG54NM,1164
132
- python_docx_oss-0.3.1.dist-info/METADATA,sha256=dSJ6OR23JAVG4Y1y-ABz0aWEhB2zuIZG-YpWzhuNoK8,7900
133
- python_docx_oss-0.3.1.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
134
- python_docx_oss-0.3.1.dist-info/top_level.txt,sha256=zkbrD3gmyqHpD_XhHe7lCbr2M5vT229nJ4UFqF5VjIs,5
135
- python_docx_oss-0.3.1.dist-info/RECORD,,
131
+ python_docx_oss-0.3.2.dist-info/licenses/LICENSE,sha256=lf2yZv-riPwFeah3IMDeG0zqI6fXcV9T9YOToeG54NM,1164
132
+ python_docx_oss-0.3.2.dist-info/METADATA,sha256=CGUTu6udBAci7DEXVSKAbXjhl-vIHavNFmjcIidrSrY,8303
133
+ python_docx_oss-0.3.2.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
134
+ python_docx_oss-0.3.2.dist-info/top_level.txt,sha256=zkbrD3gmyqHpD_XhHe7lCbr2M5vT229nJ4UFqF5VjIs,5
135
+ python_docx_oss-0.3.2.dist-info/RECORD,,