8000 rfctr: improve typing for tables · python-openxml/python-docx@5a22c52 · GitHub
[go: up one dir, main page]

Skip to content
Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 5a22c52

Browse files
committed
rfctr: improve typing for tables
1 parent 630ecbf commit 5a22c52

17 files changed

+480
-425
lines changed

pyrightconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"ignore": [
77
],
88
"include": [
9-
"src/docx/",
9+
"src/docx",
1010
"tests"
1111
],
1212
"pythonPlatform": "All",

requirements-dev.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
-r requirements-test.txt
22
build
3+
ruff
34
setuptools>=61.0.0
45
tox
56
twine
7+
types-lxml

requirements-test.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
behave>=1.2.3
33
pyparsing>=2.0.1
44
pytest>=2.5
5+
pytest-xdist
56
ruff

src/docx/opc/oxml.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# pyright: reportPrivateUsage=false
2+
13
"""Temporary stand-in for main oxml module.
24
35
This module came across with the PackageReader transplant. Probably much will get
@@ -27,7 +29,7 @@
2729
# ===========================================================================
2830

2931

30-
def parse_xml(text: str) -> etree._Element: # pyright: ignore[reportPrivateUsage]
32+
def parse_xml(text: str) -> etree._Element:
3133
"""`etree.fromstring()` replacement that uses oxml parser."""
3234
return etree.fromstring(text, oxml_parser)
3335

@@ -44,7 +46,7 @@ def qn(tag):
4446
return "{%s}%s" % (uri, tagroot)
4547

4648

47-
def serialize_part_xml(part_elm):
49+
def serialize_part_xml(part_elm: etree._Element):
4850
"""Serialize `part_elm` etree element to XML suitable for storage as an XML part.
4951
5052
That is to say, no insignificant whitespace added for readability, and an

src/docx/oxml/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@
149149
CT_TblGridCol,
150150
CT_TblLayoutType,
151151
CT_TblPr,
152+
CT_TblPrEx,
152153
CT_TblWidth,
153154
CT_Tc,
154155
CT_TcPr,
@@ -164,6 +165,7 @@
164165
register_element_cls("w:tblGrid", CT_TblGrid)
165166
register_element_cls("w:tblLayout", CT_TblLayoutType)
166167
register_element_cls("w:tblPr", CT_TblPr)
168+
register_element_cls("w:tblPrEx", CT_TblPrEx)
167169
register_element_cls("w:tblStyle", CT_String)
168170
register_element_cls("w:tc", CT_Tc)
169171
register_element_cls("w:tcPr", CT_TcPr)

src/docx/oxml/document.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class CT_Body(BaseOxmlElement):
4444

4545
p = ZeroOrMore("w:p", successors=("w:sectPr",))
4646
tbl = ZeroOrMore("w:tbl", successors=("w:sectPr",))
47-
sectPr: CT_SectPr | None = ZeroOrOne( # pyright: ignore[reportGeneralTypeIssues]
47+
sectPr: CT_SectPr | None = ZeroOrOne( # pyright: ignore[reportAssignmentType]
4848
"w:sectPr", successors=()
4949
)
5050

src/docx/oxml/parser.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# pyright: reportImportCycles=false
2+
13
"""XML parser for python-docx."""
24

35
from __future__ import annotations
@@ -43,7 +45,7 @@ def OxmlElement(
4345
nsptag_str: str,
4446
attrs: Dict[str, str] | None = None,
4547
nsdecls: Dict[str, str] | None = None,
46-
) -> BaseOxmlElement:
48+
) -> BaseOxmlElement | etree._Element: # pyright: ignore[reportPrivateUsage]
4749
"""Return a 'loose' lxml element having the tag specified by `nsptag_str`.
4850
4951
The tag in `nsptag_str` must contain the standard namespace prefix, e.g. `a:tbl`.

src/docx/oxml/section.py

Lines changed: 25 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -51,55 +51,49 @@ def inner_content_elements(self) -> List[CT_P | CT_Tbl]:
5151
class CT_HdrFtrRef(BaseOxmlElement):
5252
"""`w:headerReference` and `w:footerReference` elements."""
5353

54-
type_: WD_HEADER_FOOTER = (
55-
RequiredAttribute( # pyright: ignore[reportGeneralTypeIssues]
56-
"w:type", WD_HEADER_FOOTER
57-
)
58-
)
59-
rId: str = RequiredAttribute( # pyright: ignore[reportGeneralTypeIssues]
60-
"r:id", XsdString
54+
type_: WD_HEADER_FOOTER = RequiredAttribute( # pyright: ignore[reportAssignmentType]
55+
"w:type", WD_HEADER_FOOTER
6156
)
57+
rId: str = RequiredAttribute("r:id", XsdString) # pyright: ignore[reportAssignmentType]
6258

6359

6460
class CT_PageMar(BaseOxmlElement):
6561
"""``<w:pgMar>`` element, defining page margins."""
6662

67-
top: Length | None = OptionalAttribute( # pyright: ignore[reportGeneralTypeIssues]
63+
top: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType]
6864
"w:top", ST_SignedTwipsMeasure
6965
)
70-
right: Length | None = OptionalAttribute( # pyright: ignore
66+
right: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType]
7167
"w:right", ST_TwipsMeasure
7268
)
73-
bottom: Length | None = OptionalAttribute( # pyright: ignore
69+
bottom: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType]
7470
"w:bottom", ST_SignedTwipsMeasure
7571
)
76-
left: Length | None = OptionalAttribute( # pyright: ignore[reportGeneralTypeIssues]
72+
left: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType]
7773
"w:left", ST_TwipsMeasure
7874
)
79-
header: Length | None = OptionalAttribute( # pyright: ignore
75+
header: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType]
8076
"w:header", ST_TwipsMeasure
8177
)
82-
footer: Length | None = OptionalAttribute( # pyright: ignore
78+
footer: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType]
8379
"w:footer", ST_TwipsMeasure
8480
)
85-
gutter: Length | None = OptionalAttribute( # pyright: ignore
81+
gutter: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType]
8682
"w:gutter", ST_TwipsMeasure
8783
)
8884

8985

9086
class CT_PageSz(BaseOxmlElement):
9187
"""``<w:pgSz>`` element, defining page dimensions and orientation."""
9288

93-
w: Length | None = OptionalAttribute( # pyright: ignore[reportGeneralTypeIssues]
89+
w: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType]
9490
"w:w", ST_TwipsMeasure
9591
)
96-
h: Length | None = OptionalAttribute( # pyright: ignore[reportGeneralTypeIssues]
92+
h: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType]
9793
"w:h", ST_TwipsMeasure
9894
)
99-
orient: WD_ORIENTATION = (
100-
OptionalAttribute( # pyright: ignore[reportGeneralTypeIssues]
101-
"w:orient", WD_ORIENTATION, default=WD_ORIENTATION.PORTRAIT
102-
)
95+
orient: WD_ORIENTATION = OptionalAttribute( # pyright: ignore[reportAssignmentType]
96+
"w:orient", WD_ORIENTATION, default=WD_ORIENTATION.PORTRAIT
10397
)
10498

10599

@@ -139,16 +133,16 @@ class CT_SectPr(BaseOxmlElement):
139133
)
140134
headerReference = ZeroOrMore("w:headerReference", successors=_tag_seq)
141135
footerReference = ZeroOrMore("w:footerReference", successors=_tag_seq)
142-
type: CT_SectType | None = ZeroOrOne( # pyright: ignore[reportGeneralTypeIssues]
136+
type: CT_SectType | None = ZeroOrOne( # pyright: ignore[reportAssignmentType]
143137
"w:type", successors=_tag_seq[3:]
144138
)
145-
pgSz: CT_PageSz | None = ZeroOrOne( # pyright: ignore[reportGeneralTypeIssues]
139+
pgSz: CT_PageSz | None = ZeroOrOne( # pyright: ignore[reportAssignmentType]
146140
"w:pgSz", successors=_tag_seq[4:]
147141
)
148-
pgMar: CT_PageMar | None = ZeroOrOne( # pyright: ignore[reportGeneralTypeIssues]
142+
pgMar: CT_PageMar | None = ZeroOrOne( # pyright: ignore[reportAssignmentType]
149143
"w:pgMar", successors=_tag_seq[5:]
150144
)
151-
titlePg: CT_OnOff | None = ZeroOrOne( # pyright: ignore[reportGeneralTypeIssues]
145+
titlePg: CT_OnOff | None = ZeroOrOne( # pyright: ignore[reportAssignmentType]
152146
"w:titlePg", successors=_tag_seq[14:]
153147
)
154148
del _tag_seq
@@ -187,9 +181,7 @@ def bottom_margin(self) -> Length | None:
187181
@bottom_margin.setter
188182
def bottom_margin(self, value: int | Length | None):
189183
pgMar = self.get_or_add_pgMar()
190-
pgMar.bottom = (
191-
value if value is None or isinstance(value, Length) else Length(value)
192-
)
184+
pgMar.bottom = value if value is None or isinstance(value, Length) else Length(value)
193185

194186
def clone(self) -> CT_SectPr:
195187
"""Return an exact duplicate of this ``<w:sectPr>`` element tree suitable for
@@ -217,9 +209,7 @@ def footer(self) -> Length | None:
217209
@footer.setter
218210
def footer(self, value: int | Length | None):
219211
pgMar = self.get_or_add_pgMar()
220-
pgMar.footer = (
221-
value if value is None or isinstance(value, Length) else Length(value)
222-
)
212+
pgMar.footer = value if value is None or isinstance(value, Length) else Length(value)
223213

224214
def get_footerReference(self, type_: WD_HEADER_FOOTER) -> CT_HdrFtrRef | None:
225215
"""Return footerReference element of `type_` or None if not present."""
@@ -251,9 +241,7 @@ def gutter(self) -> Length | None:
251241
@gutter.setter
252242
def gutter(self, value: int | Length | None):
253243
pgMar = self.get_or_add_pgMar()
254-
pgMar.gutter = (
255-
value if value is None or isinstance(value, Length) else Length(value)
256-
)
244+
pgMar.gutter = value if value is None or isinstance(value, Length) else Length(value)
257245

258246
@property
259247
def header(self) -> Length | None:
@@ -270,9 +258,7 @@ def header(self) -> Length | None:
270258
@header.setter
271259
def header(self, value: int | Length | None):
272260
pgMar = self.get_or_add_pgMar()
273-
pgMar.header = (
274-
value if value is None or isinstance(value, Length) else Length(value)
275-
)
261+
pgMar.header = value if value is None or isinstance(value, Length) else Length(value)
276262

277263
def iter_inner_content(self) -> Iterator[CT_P | CT_Tbl]:
278264
"""Generate all `w:p` and `w:tbl` elements in this section.
@@ -295,9 +281,7 @@ def left_margin(self) -> Length | None:
295281
@left_margin.setter
296282
def left_margin(self, value: int | Length | None):
297283
pgMar = self.get_or_add_pgMar()
298-
pgMar.left = (
299-
value if value is None or isinstance(value, Length) else Length(value)
300-
)
284+
pgMar.left = value if value is None or isinstance(value, Length) else Length(value)
301285

302286
@property
303287
def orientation(self) -> WD_ORIENTATION:
@@ -442,8 +426,8 @@ def top_margin(self, value: Length | None):
442426
class CT_SectType(BaseOxmlElement):
443427
"""``<w:sectType>`` element, defining the section start type."""
444428

445-
val: WD_SECTION_START | None = ( # pyright: ignore[reportGeneralTypeIssues]
446-
OptionalAttribute("w:val", WD_SECTION_START)
429+
val: WD_SECTION_START | None = OptionalAttribute( # pyright: ignore[reportAssignmentType]
430+
"w:val", WD_SECTION_START
447431
)
448432

449433

src/docx/oxml/shared.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class CT_DecimalNumber(BaseOxmlElement):
1515
containing a text representation of a decimal number (e.g. 42) in its ``val``
1616
attribute."""
1717

18-
val = RequiredAttribute("w:val", ST_DecimalNumber)
18+
val: int = RequiredAttribute("w:val", ST_DecimalNumber) # pyright: ignore[reportAssignmentType]
1919

2020
@classmethod
2121
def new(cls, nsptagname, val):
@@ -42,9 +42,7 @@ class CT_String(BaseOxmlElement):
4242
In those cases, it containing a style name in its `val` attribute.
4343
"""
4444

45-
val: str = RequiredAttribute( # pyright: ignore[reportGeneralTypeIssues]
46-
"w:val", ST_String
47-
)
45+
val: str = RequiredAttribute("w:val", ST_String) # pyright: ignore[reportGeneralTypeIssues]
4846

4947
@classmethod
5048
def new(cls, nsptagname: str, val: str):

0 commit comments

Comments
 (0)
0