From ce390d3e79c773cb239d8a40dfbe5f2163aa2c35 Mon Sep 17 00:00:00 2001 From: mithunvoe Date: Thu, 11 Jun 2026 00:47:10 +0600 Subject: [PATCH] fix: map highlight w:val="none" to None instead of raising `w:val="none"` is a valid `ST_HighlightColor` value that Word writes when a highlight is explicitly cleared from a run. It has no `WD_COLOR_INDEX` member, so reading `Font.highlight_color` on such a run raised `ValueError: WD_COLOR_INDEX has no XML mapping for 'none'` from `BaseXmlEnum.from_xml()`, which aborts parsing of any document containing the value. `none` semantically means "not highlighted", which python-docx already represents as `None` (the value returned when no `w:highlight` element is present), and which the `highlight_val` setter writes by removing the element. Map the explicit `none` value to `None` in the getter to match. `none` is the only `ST_HighlightColor` value absent from `WD_COLOR_INDEX`, so this closes the gap completely. --- src/docx/oxml/text/font.py | 8 +++++++- tests/text/test_font.py | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/docx/oxml/text/font.py b/src/docx/oxml/text/font.py index 32eb567ba..84909bfea 100644 --- a/src/docx/oxml/text/font.py +++ b/src/docx/oxml/text/font.py @@ -8,7 +8,7 @@ from docx.enum.dml import MSO_THEME_COLOR from docx.enum.text import WD_COLOR_INDEX, WD_UNDERLINE -from docx.oxml.ns import nsdecls +from docx.oxml.ns import nsdecls, qn from docx.oxml.parser import parse_xml from docx.oxml.simpletypes import ( ST_HexColor, @@ -159,6 +159,12 @@ def highlight_val(self) -> WD_COLOR_INDEX | None: highlight = self.highlight if highlight is None: return None + # -- `w:val="none"` is a valid `ST_HighlightColor` value meaning "no + # -- highlight". It has no `WD_COLOR_INDEX` member, so map it to `None` + # -- (the same value used when no `w:highlight` element is present) + # -- rather than raising on the unmapped value. + if highlight.get(qn("w:val")) == "none": + return None return highlight.val @highlight_val.setter diff --git a/tests/text/test_font.py b/tests/text/test_font.py index 471c5451b..231152c71 100644 --- a/tests/text/test_font.py +++ b/tests/text/test_font.py @@ -381,6 +381,7 @@ def it_can_change_its_underline_type( ("w:r/w:rPr", None), ("w:r/w:rPr/w:highlight{w:val=default}", WD_COLOR.AUTO), ("w:r/w:rPr/w:highlight{w:val=blue}", WD_COLOR.BLUE), + ("w:r/w:rPr/w:highlight{w:val=none}", None), ], ) def it_knows_its_highlight_color(self, r_cxml: str, expected_value: WD_COLOR | None):