From 73bc297bf0a22474b02cd43874ae23c2d864d34c Mon Sep 17 00:00:00 2001 From: Rene Nejsum Date: Tue, 21 Jun 2016 22:15:21 +0200 Subject: [PATCH 001/115] Added customprops --- docx/__init__.py | 2 + docx/document.py | 8 ++ docx/opc/constants.py | 3 + docx/opc/customprops.py | 47 +++++++++ docx/opc/package.py | 22 +++++ docx/opc/parts/customprops.py | 74 ++++++++++++++ docx/oxml/__init__.py | 3 + docx/oxml/customprops.py | 155 +++++++++++++++++++++++++++++ docx/oxml/ns.py | 1 + docx/parts/document.py | 8 ++ tests/opc/test_customprops.py | 180 ++++++++++++++++++++++++++++++++++ 11 files changed, 503 insertions(+) create mode 100644 docx/opc/customprops.py create mode 100644 docx/opc/parts/customprops.py create mode 100644 docx/oxml/customprops.py create mode 100644 tests/opc/test_customprops.py diff --git a/docx/__init__.py b/docx/__init__.py index 7083abe5..07017b77 100644 --- a/docx/__init__.py +++ b/docx/__init__.py @@ -10,6 +10,7 @@ from docx.opc.constants import CONTENT_TYPE as CT, RELATIONSHIP_TYPE as RT from docx.opc.part import PartFactory from docx.opc.parts.coreprops import CorePropertiesPart +from docx.opc.parts.customprops import CustomPropertiesPart from docx.parts.document import DocumentPart from docx.parts.image import ImagePart @@ -26,6 +27,7 @@ def part_class_selector(content_type, reltype): PartFactory.part_class_selector = part_class_selector PartFactory.part_type_for[CT.OPC_CORE_PROPERTIES] = CorePropertiesPart +PartFactory.part_type_for[CT.OPC_CUSTOM_PROPERTIES] = CustomPropertiesPart PartFactory.part_type_for[CT.WML_DOCUMENT_MAIN] = DocumentPart PartFactory.part_type_for[CT.WML_NUMBERING] = NumberingPart PartFactory.part_type_for[CT.WML_SETTINGS] = SettingsPart diff --git a/docx/document.py b/docx/document.py index ba94a799..21546a7a 100644 --- a/docx/document.py +++ b/docx/document.py @@ -108,6 +108,14 @@ def core_properties(self): """ return self._part.core_properties + @property + def custom_properties(self): + """ + A |CustomProperties| object providing read/write access to the custom + properties of this document. + """ + return self._part.custom_properties + @property def inline_shapes(self): """ diff --git a/docx/opc/constants.py b/docx/opc/constants.py index b90aa394..1bcf16f6 100644 --- a/docx/opc/constants.py +++ b/docx/opc/constants.py @@ -77,6 +77,9 @@ class CONTENT_TYPE(object): OPC_CORE_PROPERTIES = ( 'application/vnd.openxmlformats-package.core-properties+xml' ) + OPC_CUSTOM_PROPERTIES = ( + 'application/vnd.openxmlformats-officedocument.custom-properties+xml' + ) OPC_DIGITAL_SIGNATURE_CERTIFICATE = ( 'application/vnd.openxmlformats-package.digital-signature-certificat' 'e' diff --git a/docx/opc/customprops.py b/docx/opc/customprops.py new file mode 100644 index 00000000..944cb3bb --- /dev/null +++ b/docx/opc/customprops.py @@ -0,0 +1,47 @@ +# encoding: utf-8 + +""" +The :mod:`pptx.packaging` module coheres around the concerns of reading and +writing presentations to and from a .pptx file. +""" + +from __future__ import ( + absolute_import, division, print_function, unicode_literals +) + +from lxml import etree + +NS_VT = "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes" + +class CustomProperties(object): + """ + Corresponds to part named ``/docProps/custom.xml``, containing the custom + document properties for this document package. + """ + def __init__(self, element): + self._element = element + + def __getitem__( self, item ): + # print(etree.tostring(self._element, pretty_print=True)) + prop = self.lookup(item) + if prop is not None : + return prop[0].text + + def __setitem__( self, key, value ): + prop = self.lookup(key) + if prop is None : + prop = etree.SubElement( self._element, "property" ) + elm = etree.SubElement(prop, '{%s}lpwstr' % NS_VT, nsmap = {'vt':NS_VT} ) + prop.set("name", key) + prop.set("fmtid", "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}") + prop.set("pid", "%s" % str(len(self._element) + 1)) + else: + elm = prop[0] + elm.text = value + # etree.tostring(prop, pretty_print=True) + + def lookup(self, item): + for child in self._element : + if child.get("name") == item : + return child + return None \ No newline at end of file diff --git a/docx/opc/package.py b/docx/opc/package.py index b0ea37ea..f99d1727 100644 --- a/docx/opc/package.py +++ b/docx/opc/package.py @@ -11,6 +11,7 @@ from .packuri import PACKAGE_URI from .part import PartFactory from .parts.coreprops import CorePropertiesPart +from .parts.customprops import CustomPropertiesPart from .pkgreader import PackageReader from .pkgwriter import PackageWriter from .rel import Relationships @@ -43,6 +44,14 @@ def core_properties(self): """ return self._core_properties_part.core_properties + @property + def custom_properties(self): + """ + |CustomProperties| object providing read/write access to the Dublin + Core properties for this document. + """ + return self._custom_properties_part.custom_properties + def iter_rels(self): """ Generate exactly one reference to each relationship in the package by @@ -172,6 +181,19 @@ def _core_properties_part(self): self.relate_to(core_properties_part, RT.CORE_PROPERTIES) return core_properties_part + @property + def _custom_properties_part(self): + """ + |CustomPropertiesPart| object related to this package. Creates + a default custom properties part if one is not present (not common). + """ + try: + return self.part_related_by(RT.CUSTOM_PROPERTIES) + except KeyError: + custom_properties_part = CustomPropertiesPart.default(self) + self.relate_to(custom_properties_part, RT.CUSTOM_PROPERTIES) + return custom_properties_part + class Unmarshaller(object): """ diff --git a/docx/opc/parts/customprops.py b/docx/opc/parts/customprops.py new file mode 100644 index 00000000..e6ec3616 --- /dev/null +++ b/docx/opc/parts/customprops.py @@ -0,0 +1,74 @@ +# encoding: utf-8 + +""" +Custom properties part, corresponds to ``/docProps/custom.xml`` part in package. +""" + +from __future__ import ( + absolute_import, division, print_function, unicode_literals +) + +from lxml import etree + +from datetime import datetime + +from ..constants import CONTENT_TYPE as CT +from ..customprops import CustomProperties +from ...oxml.customprops import CT_CustomProperties +from ..packuri import PackURI +from ..part import XmlPart + +# configure XML parser +parser_lookup = etree.ElementDefaultClassLookup(element=CT_CustomProperties) +ct_parser = etree.XMLParser(remove_blank_text=True) +ct_parser.set_element_class_lookup(parser_lookup) + + +def ct_parse_xml(xml): + """ + Return root lxml element obtained by parsing XML character string in + *xml*, which can be either a Python 2.x string or unicode. The custom + parser is used, so custom element classes are produced for elements in + *xml* that have them. + """ + root_element = etree.fromstring(xml, ct_parser) + return root_element + + + +class CustomPropertiesPart(XmlPart): + """ + Corresponds to part named ``/docProps/custom.xml``, containing the custom + document properties for this document package. + """ + @classmethod + def default(cls, package): + """ + Return a new |CustomPropertiesPart| object initialized with default + values for its base properties. + """ + custom_properties_part = cls._new(package) + custom_properties = custom_properties_part.custom_properties + return custom_properties_part + + @property + def custom_properties(self): + """ + A |CustomProperties| object providing read/write access to the custom + properties contained in this custom properties part. + """ + return CustomProperties(self.element) + + @classmethod + def load(cls, partname, content_type, blob, package): + element = ct_parse_xml(blob) + return cls(partname, content_type, element, package) + + @classmethod + def _new(cls, package): + partname = PackURI('/docProps/custom.xml') + content_type = CT.OPC_CUSTOM_PROPERTIES + customProperties = CT_CustomProperties.new() + return CustomPropertiesPart( + partname, content_type, customProperties, package + ) diff --git a/docx/oxml/__init__.py b/docx/oxml/__init__.py index 2731302e..6d82f964 100644 --- a/docx/oxml/__init__.py +++ b/docx/oxml/__init__.py @@ -70,6 +70,9 @@ def OxmlElement(nsptag_str, attrs=None, nsdecls=None): from .coreprops import CT_CoreProperties register_element_cls('cp:coreProperties', CT_CoreProperties) +from .customprops import CT_CustomProperties +#register_element_cls('Properties', CT_CustomProperties) + from .document import CT_Body, CT_Document register_element_cls('w:body', CT_Body) register_element_cls('w:document', CT_Document) diff --git a/docx/oxml/customprops.py b/docx/oxml/customprops.py new file mode 100644 index 00000000..2c7ef343 --- /dev/null +++ b/docx/oxml/customprops.py @@ -0,0 +1,155 @@ +# encoding: utf-8 + +""" +lxml custom element classes for core properties-related XML elements. +""" + +from __future__ import ( + absolute_import, division, print_function, unicode_literals +) + +import re + +from datetime import datetime, timedelta +from lxml import etree +from .ns import nsdecls, qn +from .xmlchemy import BaseOxmlElement, ZeroOrOne + +class CT_CustomProperties(BaseOxmlElement): + """ + ```` element, the root element of the Custom Properties + part stored as ``/docProps/custom.xml``. String elements are + limited in length to 255 unicode characters. + """ + + _customProperties_tmpl = ( + '\n' % nsdecls('vt') + ) + + @classmethod + def new(cls): + """ + Return a new ```` element + """ + xml = cls._customProperties_tmpl + customProperties = ct_parse_xml(xml) + return customProperties + + def _datetime_of_element(self, property_name): + element = getattr(self, property_name) + if element is None: + return None + datetime_str = element.text + try: + return self._parse_W3CDTF_to_datetime(datetime_str) + except ValueError: + # invalid datetime strings are ignored + return None + + def _get_or_add(self, prop_name): + """ + Return element returned by 'get_or_add_' method for *prop_name*. + """ + get_or_add_method_name = 'get_or_add_%s' % prop_name + get_or_add_method = getattr(self, get_or_add_method_name) + element = get_or_add_method() + return element + + @classmethod + def _offset_dt(cls, dt, offset_str): + """ + Return a |datetime| instance that is offset from datetime *dt* by + the timezone offset specified in *offset_str*, a string like + ``'-07:00'``. + """ + match = cls._offset_pattern.match(offset_str) + if match is None: + raise ValueError( + "'%s' is not a valid offset string" % offset_str + ) + sign, hours_str, minutes_str = match.groups() + sign_factor = -1 if sign == '+' else 1 + hours = int(hours_str) * sign_factor + minutes = int(minutes_str) * sign_factor + td = timedelta(hours=hours, minutes=minutes) + return dt + td + + _offset_pattern = re.compile('([+-])(\d\d):(\d\d)') + + @classmethod + def _parse_W3CDTF_to_datetime(cls, w3cdtf_str): + # valid W3CDTF date cases: + # yyyy e.g. '2003' + # yyyy-mm e.g. '2003-12' + # yyyy-mm-dd e.g. '2003-12-31' + # UTC timezone e.g. '2003-12-31T10:14:55Z' + # numeric timezone e.g. '2003-12-31T10:14:55-08:00' + templates = ( + '%Y-%m-%dT%H:%M:%S', + '%Y-%m-%d', + '%Y-%m', + '%Y', + ) + # strptime isn't smart enough to parse literal timezone offsets like + # '-07:30', so we have to do it ourselves + parseable_part = w3cdtf_str[:19] + offset_str = w3cdtf_str[19:] + dt = None + for tmpl in templates: + try: + dt = datetime.strptime(parseable_part, tmpl) + except ValueError: + continue + if dt is None: + tmpl = "could not parse W3CDTF datetime string '%s'" + raise ValueError(tmpl % w3cdtf_str) + if len(offset_str) == 6: + return cls._offset_dt(dt, offset_str) + return dt + + def _set_element_datetime(self, prop_name, value): + """ + Set date/time value of child element having *prop_name* to *value*. + """ + if not isinstance(value, datetime): + tmpl = ( + "property requires object, got %s" + ) + raise ValueError(tmpl % type(value)) + element = self._get_or_add(prop_name) + dt_str = value.strftime('%Y-%m-%dT%H:%M:%SZ') + element.text = dt_str + if prop_name in ('created', 'modified'): + # These two require an explicit 'xsi:type="dcterms:W3CDTF"' + # attribute. The first and last line are a hack required to add + # the xsi namespace to the root element rather than each child + # element in which it is referenced + self.set(qn('xsi:foo'), 'bar') + element.set(qn('xsi:type'), 'dcterms:W3CDTF') + del self.attrib[qn('xsi:foo')] + + def _set_element_text(self, prop_name, value): + """ + Set string value of *name* property to *value*. + """ + value = str(value) + if len(value) > 255: + tmpl = ( + "exceeded 255 char limit for property, got:\n\n'%s'" + ) + raise ValueError(tmpl % value) + element = self._get_or_add(prop_name) + element.text = value + + def _text_of_element(self, property_name): + """ + Return the text in the element matching *property_name*, or an empty + string if the element is not present or contains no text. + """ + element = getattr(self, property_name) + if element is None: + return '' + if element.text is None: + return '' + return element.text + diff --git a/docx/oxml/ns.py b/docx/oxml/ns.py index e6f6a4ac..27f3bf1a 100644 --- a/docx/oxml/ns.py +++ b/docx/oxml/ns.py @@ -12,6 +12,7 @@ 'c': ('http://schemas.openxmlformats.org/drawingml/2006/chart'), 'cp': ('http://schemas.openxmlformats.org/package/2006/metadata/core-pr' 'operties'), + 'vt' : ("http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"), 'dc': ('http://purl.org/dc/elements/1.1/'), 'dcmitype': ('http://purl.org/dc/dcmitype/'), 'dcterms': ('http://purl.org/dc/terms/'), diff --git a/docx/parts/document.py b/docx/parts/document.py index 01266b3b..66154b04 100644 --- a/docx/parts/document.py +++ b/docx/parts/document.py @@ -36,6 +36,14 @@ def core_properties(self): """ return self.package.core_properties + @property + def custom_properties(self): + """ + A |CustomProperties| object providing read/write access to the custom + properties of this document. + """ + return self.package.custom_properties + @property def document(self): """ diff --git a/tests/opc/test_customprops.py b/tests/opc/test_customprops.py new file mode 100644 index 00000000..2be6409f --- /dev/null +++ b/tests/opc/test_customprops.py @@ -0,0 +1,180 @@ +# encoding: utf-8 + +""" +Unit test suite for the docx.opc.customprops module +""" + +from __future__ import ( + absolute_import, division, print_function, unicode_literals +) + +import pytest + +from datetime import datetime + +from docx.opc.coreprops import CoreProperties +from docx.oxml import parse_xml + + +class DescribeCustomProperties(object): + + def it_knows_the_string_property_values(self, text_prop_get_fixture): + core_properties, prop_name, expected_value = text_prop_get_fixture + actual_value = getattr(core_properties, prop_name) + assert actual_value == expected_value + + def it_can_change_the_string_property_values(self, text_prop_set_fixture): + core_properties, prop_name, value, expected_xml = text_prop_set_fixture + setattr(core_properties, prop_name, value) + assert core_properties._element.xml == expected_xml + + def it_knows_the_date_property_values(self, date_prop_get_fixture): + core_properties, prop_name, expected_datetime = date_prop_get_fixture + actual_datetime = getattr(core_properties, prop_name) + assert actual_datetime == expected_datetime + + def it_can_change_the_date_property_values(self, date_prop_set_fixture): + core_properties, prop_name, value, expected_xml = ( + date_prop_set_fixture + ) + setattr(core_properties, prop_name, value) + assert core_properties._element.xml == expected_xml + + def it_knows_the_revision_number(self, revision_get_fixture): + core_properties, expected_revision = revision_get_fixture + assert core_properties.revision == expected_revision + + def it_can_change_the_revision_number(self, revision_set_fixture): + core_properties, revision, expected_xml = revision_set_fixture + core_properties.revision = revision + assert core_properties._element.xml == expected_xml + + # fixtures ------------------------------------------------------- + + @pytest.fixture(params=[ + ('created', datetime(2012, 11, 17, 16, 37, 40)), + ('last_printed', datetime(2014, 6, 4, 4, 28)), + ('modified', None), + ]) + def date_prop_get_fixture(self, request, core_properties): + prop_name, expected_datetime = request.param + return core_properties, prop_name, expected_datetime + + @pytest.fixture(params=[ + ('created', 'dcterms:created', datetime(2001, 2, 3, 4, 5), + '2001-02-03T04:05:00Z', ' xsi:type="dcterms:W3CDTF"'), + ('last_printed', 'cp:lastPrinted', datetime(2014, 6, 4, 4), + '2014-06-04T04:00:00Z', ''), + ('modified', 'dcterms:modified', datetime(2005, 4, 3, 2, 1), + '2005-04-03T02:01:00Z', ' xsi:type="dcterms:W3CDTF"'), + ]) + def date_prop_set_fixture(self, request): + prop_name, tagname, value, str_val, attrs = request.param + coreProperties = self.coreProperties(None, None) + core_properties = CoreProperties(parse_xml(coreProperties)) + expected_xml = self.coreProperties(tagname, str_val, attrs) + return core_properties, prop_name, value, expected_xml + + @pytest.fixture(params=[ + ('42', 42), (None, 0), ('foobar', 0), ('-17', 0), ('32.7', 0) + ]) + def revision_get_fixture(self, request): + str_val, expected_revision = request.param + tagname = '' if str_val is None else 'cp:revision' + coreProperties = self.coreProperties(tagname, str_val) + core_properties = CoreProperties(parse_xml(coreProperties)) + return core_properties, expected_revision + + @pytest.fixture(params=[ + (42, '42'), + ]) + def revision_set_fixture(self, request): + value, str_val = request.param + coreProperties = self.coreProperties(None, None) + core_properties = CoreProperties(parse_xml(coreProperties)) + expected_xml = self.coreProperties('cp:revision', str_val) + return core_properties, value, expected_xml + + @pytest.fixture(params=[ + ('author', 'python-docx'), + ('category', ''), + ('comments', ''), + ('content_status', 'DRAFT'), + ('identifier', 'GXS 10.2.1ab'), + ('keywords', 'foo bar baz'), + ('language', 'US-EN'), + ('last_modified_by', 'Steve Canny'), + ('subject', 'Spam'), + ('title', 'Word Document'), + ('version', '1.2.88'), + ]) + def text_prop_get_fixture(self, request, core_properties): + prop_name, expected_value = request.param + return core_properties, prop_name, expected_value + + @pytest.fixture(params=[ + ('author', 'dc:creator', 'scanny'), + ('category', 'cp:category', 'silly stories'), + ('comments', 'dc:description', 'Bar foo to you'), + ('content_status', 'cp:contentStatus', 'FINAL'), + ('identifier', 'dc:identifier', 'GT 5.2.xab'), + ('keywords', 'cp:keywords', 'dog cat moo'), + ('language', 'dc:language', 'GB-EN'), + ('last_modified_by', 'cp:lastModifiedBy', 'Billy Bob'), + ('subject', 'dc:subject', 'Eggs'), + ('title', 'dc:title', 'Dissertation'), + ('version', 'cp:version', '81.2.8'), + ]) + def text_prop_set_fixture(self, request): + prop_name, tagname, value = request.param + coreProperties = self.coreProperties(None, None) + core_properties = CoreProperties(parse_xml(coreProperties)) + expected_xml = self.coreProperties(tagname, value) + return core_properties, prop_name, value, expected_xml + + # fixture components --------------------------------------------- + + def coreProperties(self, tagname, str_val, attrs=''): + tmpl = ( + '%s\n' + ) + if not tagname: + child_element = '' + elif not str_val: + child_element = '\n <%s%s/>\n' % (tagname, attrs) + else: + child_element = ( + '\n <%s%s>%s\n' % (tagname, attrs, str_val, tagname) + ) + return tmpl % child_element + + @pytest.fixture + def core_properties(self): + element = parse_xml( + b'' + b'\n\n' + b' DRAFT\n' + b' python-docx\n' + b' 2012-11-17T11:07:' + b'40-05:30\n' + b' \n' + b' GXS 10.2.1ab\n' + b' US-EN\n' + b' 2014-06-04T04:28:00Z\n' + b' foo bar baz\n' + b' Steve Canny\n' + b' 4\n' + b' Spam\n' + b' Word Document\n' + b' 1.2.88\n' + b'\n' + ) + return CoreProperties(element) From 6666509eaee1244e603dd266f6f57891df27fcb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Ko=CC=88ller?= Date: Fri, 23 Nov 2018 11:40:05 +0100 Subject: [PATCH 002/115] add tests, fix type handling --- docx/opc/customprops.py | 35 +++- docx/oxml/__init__.py | 10 +- docx/oxml/customprops.py | 5 +- features/doc-customprops.feature | 28 +++ features/steps/customprops.py | 89 ++++++++ .../steps/test_files/doc-customprops.docx | Bin 0 -> 7922 bytes .../steps/test_files/doc-no-customprops.docx | Bin 0 -> 11394 bytes tests/opc/parts/test_customprops.py | 51 +++++ tests/opc/test_customprops.py | 194 +++++------------- 9 files changed, 262 insertions(+), 150 deletions(-) create mode 100644 features/doc-customprops.feature create mode 100644 features/steps/customprops.py create mode 100644 features/steps/test_files/doc-customprops.docx create mode 100644 features/steps/test_files/doc-no-customprops.docx create mode 100644 tests/opc/parts/test_customprops.py diff --git a/docx/opc/customprops.py b/docx/opc/customprops.py index 944cb3bb..dcac276e 100644 --- a/docx/opc/customprops.py +++ b/docx/opc/customprops.py @@ -9,6 +9,7 @@ absolute_import, division, print_function, unicode_literals ) +import numbers from lxml import etree NS_VT = "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes" @@ -22,23 +23,47 @@ def __init__(self, element): self._element = element def __getitem__( self, item ): - # print(etree.tostring(self._element, pretty_print=True)) prop = self.lookup(item) if prop is not None : - return prop[0].text + # print(etree.tostring(prop, pretty_print=True)) + elm = prop[0] + if elm.tag == '{%s}i4' % NS_VT: + try: + return int(elm.text) + except: + return elm.text + elif elm.tag == '{%s}bool' % NS_VT: + return True if elm.text == '1' else False + return elm.text def __setitem__( self, key, value ): prop = self.lookup(key) if prop is None : + elmType = 'lpwstr' + if isinstance(value, bool): + elmType = 'bool' + value = str(1 if value else 0) + elif isinstance(value, numbers.Number): + elmType = 'i4' + value = str(int(value)) prop = etree.SubElement( self._element, "property" ) - elm = etree.SubElement(prop, '{%s}lpwstr' % NS_VT, nsmap = {'vt':NS_VT} ) + elm = etree.SubElement(prop, '{%s}%s' %(NS_VT, elmType), nsmap = {'vt':NS_VT} ) + elm.text = value prop.set("name", key) prop.set("fmtid", "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}") prop.set("pid", "%s" % str(len(self._element) + 1)) else: elm = prop[0] - elm.text = value - # etree.tostring(prop, pretty_print=True) + if elm.tag == '{%s}i4' % NS_VT: + elm.text = str(int(value)) + elif elm.tag == '{%s}bool' % NS_VT: + elm.text = str(1 if value else 0) + else: + elm.text = '%s' % str(value) + print(etree.tostring(prop, pretty_print=True)) + + def __len__( self ): + return len(self._element) def lookup(self, item): for child in self._element : diff --git a/docx/oxml/__init__.py b/docx/oxml/__init__.py index 6d82f964..6121a1e1 100644 --- a/docx/oxml/__init__.py +++ b/docx/oxml/__init__.py @@ -39,6 +39,14 @@ def register_element_cls(tag, cls): namespace = element_class_lookup.get_namespace(nsmap[nspfx]) namespace[tagroot] = cls +def register_element_cls_ns(tag, ns, cls): + """ + Register *cls* to be constructed when the oxml parser encounters an + element with matching *tag*. *tag* is a string of the form + ``nspfx:tagroot``, e.g. ``'w:document'``. + """ + namespace = element_class_lookup.get_namespace(ns) + namespace[tag] = cls def OxmlElement(nsptag_str, attrs=None, nsdecls=None): """ @@ -71,7 +79,7 @@ def OxmlElement(nsptag_str, attrs=None, nsdecls=None): register_element_cls('cp:coreProperties', CT_CoreProperties) from .customprops import CT_CustomProperties -#register_element_cls('Properties', CT_CustomProperties) +register_element_cls_ns('Properties', 'http://schemas.openxmlformats.org/officeDocument/2006/custom-properties', CT_CustomProperties) from .document import CT_Body, CT_Document register_element_cls('w:body', CT_Body) diff --git a/docx/oxml/customprops.py b/docx/oxml/customprops.py index 2c7ef343..3be69e4d 100644 --- a/docx/oxml/customprops.py +++ b/docx/oxml/customprops.py @@ -14,10 +14,11 @@ from lxml import etree from .ns import nsdecls, qn from .xmlchemy import BaseOxmlElement, ZeroOrOne +from . import parse_xml class CT_CustomProperties(BaseOxmlElement): """ - ```` element, the root element of the Custom Properties + ```` element, the root element of the Custom Properties part stored as ``/docProps/custom.xml``. String elements are limited in length to 255 unicode characters. """ @@ -32,7 +33,7 @@ def new(cls): Return a new ```` element """ xml = cls._customProperties_tmpl - customProperties = ct_parse_xml(xml) + customProperties = parse_xml(xml) return customProperties def _datetime_of_element(self, property_name): diff --git a/features/doc-customprops.feature b/features/doc-customprops.feature new file mode 100644 index 00000000..2dcec28a --- /dev/null +++ b/features/doc-customprops.feature @@ -0,0 +1,28 @@ +Feature: Read and write custom document properties + In order to find documents and make them manageable by digital means + As a developer using python-docx + I need to access and modify the Dublin Core metadata for a document + + + Scenario: read the custom properties of a document + Given a document having known custom properties + Then I can access the custom properties object + And the custom property values match the known values + + + Scenario: change the custom properties of a document + Given a document having known custom properties + When I assign new values to the custom properties + Then the custom property values match the new values + + + Scenario: a default custom properties part is added if doc doesn't have one + Given a document having no custom properties part + When I access the custom properties object + Then a custom properties part with no values is added + + + Scenario: set custom properties on a document that doesn't have one + Given a document having no custom properties part + When I assign new values to the custom properties + Then the custom property values match the new values diff --git a/features/steps/customprops.py b/features/steps/customprops.py new file mode 100644 index 00000000..d3c06c9d --- /dev/null +++ b/features/steps/customprops.py @@ -0,0 +1,89 @@ +# encoding: utf-8 + +""" +Gherkin step implementations for custom properties-related features. +""" + +from __future__ import ( + absolute_import, division, print_function, unicode_literals +) + +from datetime import datetime, timedelta + +from behave import given, then, when + +from docx import Document +from docx.opc.customprops import CustomProperties + +from helpers import test_docx + + +# given =================================================== + +@given('a document having known custom properties') +def given_a_document_having_known_custom_properties(context): + context.document = Document(test_docx('doc-customprops')) + + +@given('a document having no custom properties part') +def given_a_document_having_no_custom_properties_part(context): + context.document = Document(test_docx('doc-no-customprops')) + + +# when ==================================================== + +@when('I access the custom properties object') +def when_I_access_the_custom_properties_object(context): + context.document.custom_properties + + +@when("I assign new values to the custom properties") +def when_I_assign_new_values_to_the_custom_properties(context): + context.propvals = ( + ('CustomPropBool', False), + ('CustomPropInt', 1), + ('CustomPropString', 'Lorem ipsum'), + ) + custom_properties = context.document.custom_properties + for name, value in context.propvals: + custom_properties[name] = value + + +# then ==================================================== + +@then('a custom properties part with no values is added') +def then_a_custom_properties_part_with_no_values_is_added(context): + custom_properties = context.document.custom_properties + assert len(custom_properties) == 0 + + +@then('I can access the custom properties object') +def then_I_can_access_the_custom_properties_object(context): + document = context.document + custom_properties = document.custom_properties + assert isinstance(custom_properties, CustomProperties) + + +@then('the custom property values match the known values') +def then_the_custom_property_values_match_the_known_values(context): + known_propvals = ( + ('CustomPropBool', True), + ('CustomPropInt', 13), + ('CustomPropString', 'Test String'), + ) + custom_properties = context.document.custom_properties + for name, expected_value in known_propvals: + value = custom_properties[name] + assert value == expected_value, ( + "got '%s' for custom property '%s'" % (value, name) + ) + + +@then('the custom property values match the new values') +def then_the_custom_property_values_match_the_new_values(context): + custom_properties = context.document.custom_properties + for name, expected_value in context.propvals: + value = custom_properties[name] + assert value == expected_value, ( + "got '%s' for custom property '%s'" % (value, name) + ) diff --git a/features/steps/test_files/doc-customprops.docx b/features/steps/test_files/doc-customprops.docx new file mode 100644 index 0000000000000000000000000000000000000000..a3dc7a027350607fc79dee5ef7aa29355665a7fc GIT binary patch literal 7922 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

>9!)DBQj43=}|5!4c+&rZJ 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\n' + '\n' + ' \n' + ' %s\n' + ' \n' + '' + ) + return tmpl %(prop_name, str_type, str_value, str_type) + + @pytest.fixture + def custom_properties_blank(self): + element = parse_xml( + '' + '\n' ) - if not tagname: - child_element = '' - elif not str_val: - child_element = '\n <%s%s/>\n' % (tagname, attrs) - else: - child_element = ( - '\n <%s%s>%s\n' % (tagname, attrs, str_val, tagname) - ) - return tmpl % child_element + return CustomProperties(element) @pytest.fixture - def core_properties(self): + def custom_properties_default(self): element = parse_xml( - b'' - b'\n\n' - b' DRAFT\n' - b' python-docx\n' - b' 2012-11-17T11:07:' - b'40-05:30\n' - b' \n' - b' GXS 10.2.1ab\n' - b' US-EN\n' - b' 2014-06-04T04:28:00Z\n' - b' foo bar baz\n' - b' Steve Canny\n' - b' 4\n' - b' Spam\n' - b' Word Document\n' - b' 1.2.88\n' - b'\n' + b'\n' + b'\n' + b' 1\n' + b' 13\n' + b' Test String\n' + b'\n' ) - return CoreProperties(element) + return CustomProperties(element) From f48abe819e1bfb3aaf3ec840ea3a9d19a8c7e8de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Ko=CC=88ller?= Date: Fri, 7 Dec 2018 11:04:24 +0100 Subject: [PATCH 003/115] remove debug console print on custom properties --- docx/opc/customprops.py | 1 - 1 file changed, 1 deletion(-) diff --git a/docx/opc/customprops.py b/docx/opc/customprops.py index dcac276e..95e3fb7b 100644 --- a/docx/opc/customprops.py +++ b/docx/opc/customprops.py @@ -60,7 +60,6 @@ def __setitem__( self, key, value ): elm.text = str(1 if value else 0) else: elm.text = '%s' % str(value) - print(etree.tostring(prop, pretty_print=True)) def __len__( self ): return len(self._element) From bdca8ec0d7963e1d5a1cb0ad205b1c7be77f3122 Mon Sep 17 00:00:00 2001 From: Bar Hochman Date: Wed, 20 Oct 2021 12:40:31 +0300 Subject: [PATCH 004/115] updated dependencies, added py38 to support in setup.py --- requirements.txt | 12 ++++++------ setup.py | 4 ++++ tox.ini | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/requirements.txt b/requirements.txt index de244afa..8f05ded3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ -behave>=1.2.3 -flake8>=2.0 -lxml>=3.1.0 -mock>=1.0.1 -pyparsing>=2.0.1 -pytest>=2.5 +behave>=1.2.6 +flake8>=4.0.1 +lxml>=4.6.3 +mock>=4.0.3 +pyparsing>=2.4.7 +pytest>=6.2.5 diff --git a/setup.py b/setup.py index 7c34edcc..bc8840da 100644 --- a/setup.py +++ b/setup.py @@ -52,6 +52,10 @@ def text_of(relpath): "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8" "Topic :: Office/Business :: Office Suites", "Topic :: Software Development :: Libraries", ] diff --git a/tox.ini b/tox.ini index 6ced79b7..4f8f147c 100644 --- a/tox.ini +++ b/tox.ini @@ -12,7 +12,7 @@ python_classes = Test Describe python_functions = it_ they_ and_it_ but_it_ [tox] -envlist = py26, py27, py34, py35, py36, py38 +envlist = py26, py27, py34, py35, py36, py37, py38 [testenv] deps = From 8578c4d6944b5a7a09a458f27df2fd610a137534 Mon Sep 17 00:00:00 2001 From: samzhangjy Date: Tue, 15 Feb 2022 12:21:37 +0800 Subject: [PATCH 005/115] added cache for table cells --- docx/table.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docx/table.py b/docx/table.py index b3bc090f..1482947f 100644 --- a/docx/table.py +++ b/docx/table.py @@ -19,6 +19,8 @@ class Table(Parented): def __init__(self, tbl, parent): super(Table, self).__init__(parent) self._element = self._tbl = tbl + self._cached_cells = [] + self._update_cache = True def add_column(self, width): """ @@ -31,6 +33,7 @@ def add_column(self, width): for tr in self._tbl.tr_lst: tc = tr.add_tc() tc.width = width + self._update_cache = True return _Column(gridCol, self) def add_row(self): @@ -42,6 +45,7 @@ def add_row(self): for gridCol in tbl.tblGrid.gridCol_lst: tc = tr.add_tc() tc.width = gridCol.w + self._update_cache = True return _Row(tr, self) @property @@ -165,6 +169,8 @@ def _cells(self): If the table contains a span, one or more |_Cell| object references are repeated. """ + if not self._update_cache: + return self._cached_cells col_count = self._column_count cells = [] for tc in self._tbl.iter_tcs(): @@ -175,6 +181,8 @@ def _cells(self): cells.append(cells[-1]) else: cells.append(_Cell(tc, self)) + self._cached_cells = cells + self._update_cache = False return cells @property From 263c82f5a8fc3dcdb629d5a759db98d3ae0c5a72 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 10 Jun 2022 16:48:08 +0800 Subject: [PATCH 006/115] Default numbering (#4) * default NumberingPart * add default-numbering.xml --- docx/parts/document.py | 2 +- docx/parts/numbering.py | 29 +++++++++++++++++++++++----- docx/templates/default-numbering.xml | 20 +++++++++++++++++++ 3 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 docx/templates/default-numbering.xml diff --git a/docx/parts/document.py b/docx/parts/document.py index 27d61d56..c75ec0dd 100644 --- a/docx/parts/document.py +++ b/docx/parts/document.py @@ -107,7 +107,7 @@ def numbering_part(self): try: return self.part_related_by(RT.NUMBERING) except KeyError: - numbering_part = NumberingPart.new() + numbering_part = NumberingPart.default(self.package) self.relate_to(numbering_part, RT.NUMBERING) return numbering_part diff --git a/docx/parts/numbering.py b/docx/parts/numbering.py index e324c5aa..890d94d5 100644 --- a/docx/parts/numbering.py +++ b/docx/parts/numbering.py @@ -3,12 +3,14 @@ """ |NumberingPart| and closely related objects """ +from __future__ import absolute_import, division, print_function, unicode_literals -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +import os +from ..opc.constants import CONTENT_TYPE as CT +from ..opc.packuri import PackURI from ..opc.part import XmlPart +from ..oxml import parse_xml from ..shared import lazyproperty @@ -17,13 +19,29 @@ class NumberingPart(XmlPart): Proxy for the numbering.xml part containing numbering definitions for a document or glossary. """ + @classmethod - def new(cls): + def default(cls, package): """ Return newly created empty numbering part, containing only the root ```` element. """ - raise NotImplementedError + partname = PackURI("/word/numbering.xml") + content_type = CT.WML_NUMBERING + element = parse_xml(cls._default_numbering_xml()) + return cls(partname, content_type, element, package) + + @classmethod + def _default_numbering_xml(cls): + """ + Return a bytestream containing XML for a default numbering part. + """ + path = os.path.join( + os.path.split(__file__)[0], "..", "templates", "default-numbering.xml" + ) + with open(path, "rb") as f: + xml_bytes = f.read() + return xml_bytes @lazyproperty def numbering_definitions(self): @@ -39,6 +57,7 @@ class _NumberingDefinitions(object): Collection of |_NumberingDefinition| instances corresponding to the ```` elements in a numbering part. """ + def __init__(self, numbering_elm): super(_NumberingDefinitions, self).__init__() self._numbering = numbering_elm diff --git a/docx/templates/default-numbering.xml b/docx/templates/default-numbering.xml new file mode 100644 index 00000000..e050b35d --- /dev/null +++ b/docx/templates/default-numbering.xml @@ -0,0 +1,20 @@ + + + From e75319761b9a2a962eb0ca41e5a6ff0d45044f02 Mon Sep 17 00:00:00 2001 From: Ethan Date: Tue, 14 Jun 2022 15:20:29 +0800 Subject: [PATCH 007/115] fix py38 __dict__ TypeError (#6) --- docx/oxml/xmlchemy.py | 199 +++++++++++++++++++++++++----------------- 1 file changed, 117 insertions(+), 82 deletions(-) diff --git a/docx/oxml/xmlchemy.py b/docx/oxml/xmlchemy.py index 46dbf462..8be2e599 100644 --- a/docx/oxml/xmlchemy.py +++ b/docx/oxml/xmlchemy.py @@ -7,10 +7,10 @@ from __future__ import absolute_import -from lxml import etree - import re +from lxml import etree + from docx.compat import Unicode from docx.oxml import OxmlElement from docx.oxml.exceptions import InvalidXmlError @@ -23,7 +23,7 @@ def serialize_for_reading(element): Serialize *element* to human-readable XML suitable for tests. No XML declaration. """ - xml = etree.tostring(element, encoding='unicode', pretty_print=True) + xml = etree.tostring(element, encoding="unicode", pretty_print=True) return XmlString(xml) @@ -39,7 +39,7 @@ class XmlString(Unicode): # front attrs | text # close - _xml_elm_line_patt = re.compile(r'( *)([^<]*)?$') + _xml_elm_line_patt = re.compile(r"( *)([^<]*)?$") def __eq__(self, other): lines = self.splitlines() @@ -95,14 +95,34 @@ class MetaOxmlElement(type): """ Metaclass for BaseOxmlElement """ - def __init__(cls, clsname, bases, clsdict): + + def __init__(self, _, __, clsdict): dispatchable = ( - OneAndOnlyOne, OneOrMore, OptionalAttribute, RequiredAttribute, - ZeroOrMore, ZeroOrOne, ZeroOrOneChoice + OneAndOnlyOne, + OneOrMore, + OptionalAttribute, + RequiredAttribute, + ZeroOrMore, + ZeroOrOne, + ZeroOrOneChoice, ) for key, value in clsdict.items(): if isinstance(value, dispatchable): - value.populate_class_members(cls, key) + value.populate_class_members(self, key) + + @classmethod + def create(cls): + """ + cls.__dict__ sometimes contains '__dict__' inside it. + That __dict__ proxy is then improperly copied to the new_class by type() + which results in the new_class having a broken cls().__dict__ attribute. + Attempting to access an instance's __dict__ attribute (new_class().__dict__) + will raise the TypeError: + descriptor '__dict__' for 'xxx' objects doesn't apply to a 'yyy' object. + """ + cls_dict = dict(cls.__dict__) + cls_dict.pop("__dict__", None) + return cls("BaseOxmlElement", (etree.ElementBase,), cls_dict) class BaseAttribute(object): @@ -110,6 +130,7 @@ class BaseAttribute(object): Base class for OptionalAttribute and RequiredAttribute, providing common methods. """ + def __init__(self, attr_name, simple_type): super(BaseAttribute, self).__init__() self._attr_name = attr_name @@ -136,7 +157,7 @@ def _add_attr_property(self): @property def _clark_name(self): - if ':' in self._attr_name: + if ":" in self._attr_name: return qn(self._attr_name) return self._attr_name @@ -147,6 +168,7 @@ class OptionalAttribute(BaseAttribute): attribute returns a default value when not present for reading. When assigned |None|, the attribute is removed. """ + def __init__(self, attr_name, simple_type, default=None): super(OptionalAttribute, self).__init__(attr_name, simple_type) self._default = default @@ -157,11 +179,13 @@ def _getter(self): Return a function object suitable for the "get" side of the attribute property descriptor. """ + def get_attr_value(obj): attr_str_value = obj.get(self._clark_name) if attr_str_value is None: return self._default return self._simple_type.from_xml(attr_str_value) + get_attr_value.__doc__ = self._docstring return get_attr_value @@ -172,10 +196,10 @@ def _docstring(self): for this attribute. """ return ( - '%s type-converted value of ``%s`` attribute, or |None| (or spec' - 'ified default value) if not present. Assigning the default valu' - 'e causes the attribute to be removed from the element.' % - (self._simple_type.__name__, self._attr_name) + "%s type-converted value of ``%s`` attribute, or |None| (or spec" + "ified default value) if not present. Assigning the default valu" + "e causes the attribute to be removed from the element." + % (self._simple_type.__name__, self._attr_name) ) @property @@ -184,6 +208,7 @@ def _setter(self): Return a function object suitable for the "set" side of the attribute property descriptor. """ + def set_attr_value(obj, value): if value is None or value == self._default: if self._clark_name in obj.attrib: @@ -191,6 +216,7 @@ def set_attr_value(obj, value): return str_value = self._simple_type.to_xml(value) obj.set(self._clark_name, str_value) + return set_attr_value @@ -203,20 +229,23 @@ class RequiredAttribute(BaseAttribute): |None| is assigned. Assigning |None| raises |TypeError| or |ValueError|, depending on the simple type of the attribute. """ + @property def _getter(self): """ Return a function object suitable for the "get" side of the attribute property descriptor. """ + def get_attr_value(obj): attr_str_value = obj.get(self._clark_name) if attr_str_value is None: raise InvalidXmlError( - "required '%s' attribute not present on element %s" % - (self._attr_name, obj.tag) + "required '%s' attribute not present on element %s" + % (self._attr_name, obj.tag) ) return self._simple_type.from_xml(attr_str_value) + get_attr_value.__doc__ = self._docstring return get_attr_value @@ -226,9 +255,9 @@ def _docstring(self): Return the string to use as the ``__doc__`` attribute of the property for this attribute. """ - return ( - '%s type-converted value of ``%s`` attribute.' % - (self._simple_type.__name__, self._attr_name) + return "%s type-converted value of ``%s`` attribute." % ( + self._simple_type.__name__, + self._attr_name, ) @property @@ -237,9 +266,11 @@ def _setter(self): Return a function object suitable for the "set" side of the attribute property descriptor. """ + def set_attr_value(obj, value): str_value = self._simple_type.to_xml(value) obj.set(self._clark_name, str_value) + return set_attr_value @@ -248,6 +279,7 @@ class _BaseChildElement(object): Base class for the child element classes corresponding to varying cardinalities, such as ZeroOrOne and ZeroOrMore. """ + def __init__(self, nsptagname, successors=()): super(_BaseChildElement, self).__init__() self._nsptagname = nsptagname @@ -266,6 +298,7 @@ def _add_adder(self): Add an ``_add_x()`` method to the element class for this child element. """ + def _add_child(obj, **attrs): new_method = getattr(obj, self._new_method_name) child = new_method() @@ -276,8 +309,8 @@ def _add_child(obj, **attrs): return child _add_child.__doc__ = ( - 'Add a new ``<%s>`` child element unconditionally, inserted in t' - 'he correct sequence.' % self._nsptagname + "Add a new ``<%s>`` child element unconditionally, inserted in t" + "he correct sequence." % self._nsptagname ) self._add_to_class(self._add_method_name, _add_child) @@ -289,7 +322,7 @@ def _add_creator(self): creator = self._creator creator.__doc__ = ( 'Return a "loose", newly created ``<%s>`` element having no attri' - 'butes, text, or children.' % self._nsptagname + "butes, text, or children." % self._nsptagname ) self._add_to_class(self._new_method_name, creator) @@ -307,13 +340,14 @@ def _add_inserter(self): Add an ``_insert_x()`` method to the element class for this child element. """ + def _insert_child(obj, child): obj.insert_element_before(child, *self._successors) return child _insert_child.__doc__ = ( - 'Return the passed ``<%s>`` element after inserting it as a chil' - 'd in the correct sequence.' % self._nsptagname + "Return the passed ``<%s>`` element after inserting it as a chil" + "d in the correct sequence." % self._nsptagname ) self._add_to_class(self._insert_method_name, _insert_child) @@ -322,26 +356,27 @@ def _add_list_getter(self): Add a read-only ``{prop_name}_lst`` property to the element class to retrieve a list of child elements matching this type. """ - prop_name = '%s_lst' % self._prop_name + prop_name = "%s_lst" % self._prop_name property_ = property(self._list_getter, None, None) setattr(self._element_cls, prop_name, property_) @lazyproperty def _add_method_name(self): - return '_add_%s' % self._prop_name + return "_add_%s" % self._prop_name def _add_public_adder(self): """ Add a public ``add_x()`` method to the parent element class. """ + def add_child(obj): private_add_method = getattr(obj, self._add_method_name) child = private_add_method() return child add_child.__doc__ = ( - 'Add a new ``<%s>`` child element unconditionally, inserted in t' - 'he correct sequence.' % self._nsptagname + "Add a new ``<%s>`` child element unconditionally, inserted in t" + "he correct sequence." % self._nsptagname ) self._add_to_class(self._public_add_method_name, add_child) @@ -360,8 +395,10 @@ def _creator(self): Return a function object that creates a new, empty element of the right type, having no attributes. """ + def new_child_element(obj): return OxmlElement(self._nsptagname) + return new_child_element @property @@ -371,17 +408,18 @@ def _getter(self): descriptor. This default getter returns the child element with matching tag name or |None| if not present. """ + def get_child_element(obj): return obj.find(qn(self._nsptagname)) + get_child_element.__doc__ = ( - '``<%s>`` child element or |None| if not present.' - % self._nsptagname + "``<%s>`` child element or |None| if not present." % self._nsptagname ) return get_child_element @lazyproperty def _insert_method_name(self): - return '_insert_%s' % self._prop_name + return "_insert_%s" % self._prop_name @property def _list_getter(self): @@ -389,11 +427,13 @@ def _list_getter(self): Return a function object suitable for the "get" side of a list property descriptor. """ + def get_child_element_list(obj): return obj.findall(qn(self._nsptagname)) + get_child_element_list.__doc__ = ( - 'A list containing each of the ``<%s>`` child elements, in the o' - 'rder they appear.' % self._nsptagname + "A list containing each of the ``<%s>`` child elements, in the o" + "rder they appear." % self._nsptagname ) return get_child_element_list @@ -405,15 +445,15 @@ def _public_add_method_name(self): provide a friendlier API to clients having domain appropriate parameter names for required attributes. """ - return 'add_%s' % self._prop_name + return "add_%s" % self._prop_name @lazyproperty def _remove_method_name(self): - return '_remove_%s' % self._prop_name + return "_remove_%s" % self._prop_name @lazyproperty def _new_method_name(self): - return '_new_%s' % self._prop_name + return "_new_%s" % self._prop_name class Choice(_BaseChildElement): @@ -421,12 +461,12 @@ class Choice(_BaseChildElement): Defines a child element belonging to a group, only one of which may appear as a child. """ + @property def nsptagname(self): return self._nsptagname - def populate_class_members( - self, element_cls, group_prop_name, successors): + def populate_class_members(self, element_cls, group_prop_name, successors): """ Add the appropriate methods to *element_cls*. """ @@ -445,50 +485,47 @@ def _add_get_or_change_to_method(self): Add a ``get_or_change_to_x()`` method to the element class for this child element. """ + def get_or_change_to_child(obj): child = getattr(obj, self._prop_name) if child is not None: return child - remove_group_method = getattr( - obj, self._remove_group_method_name - ) + remove_group_method = getattr(obj, self._remove_group_method_name) remove_group_method() add_method = getattr(obj, self._add_method_name) child = add_method() return child get_or_change_to_child.__doc__ = ( - 'Return the ``<%s>`` child, replacing any other group element if' - ' found.' + "Return the ``<%s>`` child, replacing any other group element if" " found." ) % self._nsptagname - self._add_to_class( - self._get_or_change_to_method_name, get_or_change_to_child - ) + self._add_to_class(self._get_or_change_to_method_name, get_or_change_to_child) @property def _prop_name(self): """ Calculate property name from tag name, e.g. a:schemeClr -> schemeClr. """ - if ':' in self._nsptagname: - start = self._nsptagname.index(':') + 1 + if ":" in self._nsptagname: + start = self._nsptagname.index(":") + 1 else: start = 0 return self._nsptagname[start:] @lazyproperty def _get_or_change_to_method_name(self): - return 'get_or_change_to_%s' % self._prop_name + return "get_or_change_to_%s" % self._prop_name @lazyproperty def _remove_group_method_name(self): - return '_remove_%s' % self._group_prop_name + return "_remove_%s" % self._group_prop_name class OneAndOnlyOne(_BaseChildElement): """ Defines a required child element for MetaOxmlElement. """ + def __init__(self, nsptagname): super(OneAndOnlyOne, self).__init__(nsptagname, None) @@ -496,9 +533,7 @@ def populate_class_members(self, element_cls, prop_name): """ Add the appropriate methods to *element_cls*. """ - super(OneAndOnlyOne, self).populate_class_members( - element_cls, prop_name - ) + super(OneAndOnlyOne, self).populate_class_members(element_cls, prop_name) self._add_getter() @property @@ -507,18 +542,17 @@ def _getter(self): Return a function object suitable for the "get" side of the property descriptor. """ + def get_child_element(obj): child = obj.find(qn(self._nsptagname)) if child is None: raise InvalidXmlError( - "required ``<%s>`` child element not present" % - self._nsptagname + "required ``<%s>`` child element not present" % self._nsptagname ) return child get_child_element.__doc__ = ( - 'Required ``<%s>`` child element.' - % self._nsptagname + "Required ``<%s>`` child element." % self._nsptagname ) return get_child_element @@ -528,13 +562,12 @@ class OneOrMore(_BaseChildElement): Defines a repeating child element for MetaOxmlElement that must appear at least once. """ + def populate_class_members(self, element_cls, prop_name): """ Add the appropriate methods to *element_cls*. """ - super(OneOrMore, self).populate_class_members( - element_cls, prop_name - ) + super(OneOrMore, self).populate_class_members(element_cls, prop_name) self._add_list_getter() self._add_creator() self._add_inserter() @@ -547,13 +580,12 @@ class ZeroOrMore(_BaseChildElement): """ Defines an optional repeating child element for MetaOxmlElement. """ + def populate_class_members(self, element_cls, prop_name): """ Add the appropriate methods to *element_cls*. """ - super(ZeroOrMore, self).populate_class_members( - element_cls, prop_name - ) + super(ZeroOrMore, self).populate_class_members(element_cls, prop_name) self._add_list_getter() self._add_creator() self._add_inserter() @@ -566,6 +598,7 @@ class ZeroOrOne(_BaseChildElement): """ Defines an optional child element for MetaOxmlElement. """ + def populate_class_members(self, element_cls, prop_name): """ Add the appropriate methods to *element_cls*. @@ -583,14 +616,16 @@ def _add_get_or_adder(self): Add a ``get_or_add_x()`` method to the element class for this child element. """ + def get_or_add_child(obj): child = getattr(obj, self._prop_name) if child is None: add_method = getattr(obj, self._add_method_name) child = add_method() return child + get_or_add_child.__doc__ = ( - 'Return the ``<%s>`` child element, newly added if not present.' + "Return the ``<%s>`` child element, newly added if not present." ) % self._nsptagname self._add_to_class(self._get_or_add_method_name, get_or_add_child) @@ -599,16 +634,18 @@ def _add_remover(self): Add a ``_remove_x()`` method to the element class for this child element. """ + def _remove_child(obj): obj.remove_all(self._nsptagname) + _remove_child.__doc__ = ( - 'Remove all ``<%s>`` child elements.' + "Remove all ``<%s>`` child elements." ) % self._nsptagname self._add_to_class(self._remove_method_name, _remove_child) @lazyproperty def _get_or_add_method_name(self): - return 'get_or_add_%s' % self._prop_name + return "get_or_add_%s" % self._prop_name class ZeroOrOneChoice(_BaseChildElement): @@ -616,6 +653,7 @@ class ZeroOrOneChoice(_BaseChildElement): Correspondes to an ``EG_*`` element group where at most one of its members may appear as a child. """ + def __init__(self, choices, successors=()): self._choices = choices self._successors = successors @@ -624,9 +662,7 @@ def populate_class_members(self, element_cls, prop_name): """ Add the appropriate methods to *element_cls*. """ - super(ZeroOrOneChoice, self).populate_class_members( - element_cls, prop_name - ) + super(ZeroOrOneChoice, self).populate_class_members(element_cls, prop_name) self._add_choice_getter() for choice in self._choices: choice.populate_class_members( @@ -649,16 +685,15 @@ def _add_group_remover(self): Add a ``_remove_eg_x()`` method to the element class for this choice group. """ + def _remove_choice_group(obj): for tagname in self._member_nsptagnames: obj.remove_all(tagname) _remove_choice_group.__doc__ = ( - 'Remove the current choice group child element if present.' - ) - self._add_to_class( - self._remove_choice_group_method_name, _remove_choice_group + "Remove the current choice group child element if present." ) + self._add_to_class(self._remove_choice_group_method_name, _remove_choice_group) @property def _choice_getter(self): @@ -666,11 +701,13 @@ def _choice_getter(self): Return a function object suitable for the "get" side of the property descriptor. """ + def get_group_member_element(obj): return obj.first_child_found_in(*self._member_nsptagnames) + get_group_member_element.__doc__ = ( - 'Return the child element belonging to this element group, or ' - '|None| if no member child is present.' + "Return the child element belonging to this element group, or " + "|None| if no member child is present." ) return get_group_member_element @@ -684,7 +721,7 @@ def _member_nsptagnames(self): @lazyproperty def _remove_choice_group_method_name(self): - return '_remove_%s' % self._prop_name + return "_remove_%s" % self._prop_name class _OxmlElementBase(etree.ElementBase): @@ -699,7 +736,9 @@ class _OxmlElementBase(etree.ElementBase): def __repr__(self): return "<%s '<%s>' at 0x%0x>" % ( - self.__class__.__name__, self._nsptag, id(self) + self.__class__.__name__, + self._nsptag, + id(self), ) def first_child_found_in(self, *tagnames): @@ -745,15 +784,11 @@ def xpath(self, xpath_str): Override of ``lxml`` _Element.xpath() method to provide standard Open XML namespace mapping (``nsmap``) in centralized location. """ - return super(BaseOxmlElement, self).xpath( - xpath_str, namespaces=nsmap - ) + return super(BaseOxmlElement, self).xpath(xpath_str, namespaces=nsmap) @property def _nsptag(self): return NamespacePrefixedTag.from_clark_name(self.tag) -BaseOxmlElement = MetaOxmlElement( - 'BaseOxmlElement', (etree.ElementBase,), dict(_OxmlElementBase.__dict__) -) +BaseOxmlElement = MetaOxmlElement.create() From 7fecc56927cb91090074db16727de013f2e5e15c Mon Sep 17 00:00:00 2001 From: Ethan Date: Tue, 14 Jun 2022 18:17:25 +0800 Subject: [PATCH 008/115] fix-autotest-and-bug (#7) --- docx/oxml/xmlchemy.py | 2 +- requirements.txt | 2 +- setup.py | 11 ++--------- tests/parts/test_document.py | 4 ++-- tox.ini | 21 ++------------------- 5 files changed, 8 insertions(+), 32 deletions(-) diff --git a/docx/oxml/xmlchemy.py b/docx/oxml/xmlchemy.py index 8be2e599..15517190 100644 --- a/docx/oxml/xmlchemy.py +++ b/docx/oxml/xmlchemy.py @@ -120,7 +120,7 @@ def create(cls): will raise the TypeError: descriptor '__dict__' for 'xxx' objects doesn't apply to a 'yyy' object. """ - cls_dict = dict(cls.__dict__) + cls_dict = dict(_OxmlElementBase.__dict__) cls_dict.pop("__dict__", None) return cls("BaseOxmlElement", (etree.ElementBase,), cls_dict) diff --git a/requirements.txt b/requirements.txt index 8f05ded3..63db5070 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ behave>=1.2.6 flake8>=4.0.1 -lxml>=4.6.3 +lxml>=4.9.0 mock>=4.0.3 pyparsing>=2.4.7 pytest>=6.2.5 diff --git a/setup.py b/setup.py index bc8840da..d7ad391e 100644 --- a/setup.py +++ b/setup.py @@ -46,16 +46,9 @@ def text_of(relpath): "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 2.6", - "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.3", - "Programming Language :: Python :: 3.4", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8" + "Programming Language :: Python :: 3.9" + "Programming Language :: Python :: 3.10" "Topic :: Office/Business :: Office Suites", "Topic :: Software Development :: Libraries", ] diff --git a/tests/parts/test_document.py b/tests/parts/test_document.py index d6f0e773..2d23a53e 100644 --- a/tests/parts/test_document.py +++ b/tests/parts/test_document.py @@ -122,12 +122,12 @@ def and_it_creates_a_numbering_part_if_not_present( self, part_related_by_, relate_to_, NumberingPart_, numbering_part_ ): part_related_by_.side_effect = KeyError - NumberingPart_.new.return_value = numbering_part_ + NumberingPart_.default.return_value = numbering_part_ document_part = DocumentPart(None, None, None, None) numbering_part = document_part.numbering_part - NumberingPart_.new.assert_called_once_with() + NumberingPart_.default.assert_called_once_with(None) relate_to_.assert_called_once_with(document_part, numbering_part_, RT.NUMBERING) assert numbering_part is numbering_part_ diff --git a/tox.ini b/tox.ini index 4f8f147c..a1319eb5 100644 --- a/tox.ini +++ b/tox.ini @@ -12,7 +12,7 @@ python_classes = Test Describe python_functions = it_ they_ and_it_ but_it_ [tox] -envlist = py26, py27, py34, py35, py36, py37, py38 +envlist = py38, py39, py310 [testenv] deps = @@ -22,22 +22,5 @@ deps = pytest commands = - py.test -qx + pytest -qx behave --format progress --stop --tags=-wip - -[testenv:py26] -deps = - importlib>=1.0.3 - behave - lxml - mock - pyparsing - pytest - -[testenv:py27] -deps = - behave - lxml - mock - pyparsing - pytest From 6420caf22e02910c62e4dc0a04d44c2b5615c860 Mon Sep 17 00:00:00 2001 From: Ethan Date: Wed, 15 Jun 2022 14:57:17 +0800 Subject: [PATCH 009/115] Update .travis.yml --- .travis.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6ce09e8e..a64ba631 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,7 @@ language: python python: - "3.8" - - "3.6" - - "2.7" -# command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors + - "3.9" + - "3.10" install: pip install -r requirements.txt -# command to run tests, e.g. python setup.py test -script: py.test +script: pytest From 8ea02d842d3674c7109f185d8c35a893a7152c25 Mon Sep 17 00:00:00 2001 From: Ethan Date: Wed, 15 Jun 2022 16:59:48 +0800 Subject: [PATCH 010/115] drop rels (#5) --- docx/opc/package.py | 40 ++++++++++++++++++++++++++++------------ docx/opc/part.py | 33 ++++++++++++++++++++------------- docx/opc/pkgwriter.py | 6 ++++-- 3 files changed, 52 insertions(+), 27 deletions(-) diff --git a/docx/opc/package.py b/docx/opc/package.py index bc51893b..328cd1a2 100644 --- a/docx/opc/package.py +++ b/docx/opc/package.py @@ -4,14 +4,16 @@ from __future__ import absolute_import, division, print_function, unicode_literals +from typing import Callable + from docx.opc.constants import RELATIONSHIP_TYPE as RT from docx.opc.packuri import PACKAGE_URI, PackURI -from docx.opc.part import PartFactory +from docx.opc.part import Part, PartFactory from docx.opc.parts.coreprops import CorePropertiesPart from docx.opc.parts.customprops import CustomPropertiesPart from docx.opc.pkgreader import PackageReader from docx.opc.pkgwriter import PackageWriter -from docx.opc.rel import Relationships +from docx.opc.rel import Relationships, _Relationship from docx.opc.shared import lazyproperty @@ -55,6 +57,7 @@ def iter_rels(self): Generate exactly one reference to each relationship in the package by performing a depth-first traversal of the rels graph. """ + def walk_rels(source, visited=None): visited = [] if visited is None else visited for rel in source.rels.values(): @@ -77,6 +80,7 @@ def iter_parts(self): Generate exactly one reference to each of the parts in the package by performing a depth-first traversal of the rels graph. """ + def walk_parts(source, visited=list()): for rel in source.rels.values(): if rel.is_external: @@ -147,13 +151,13 @@ def part_related_by(self, reltype): """ return self.rels.part_with_reltype(reltype) - @property - def parts(self): + @lazyproperty + def parts(self) -> list[Part]: """ Return a list containing a reference to each of the parts in this package. """ - return [part for part in self.iter_parts()] + return list(self.iter_parts()) def relate_to(self, part, reltype): """ @@ -164,13 +168,26 @@ def relate_to(self, part, reltype): return rel.rId @lazyproperty - def rels(self): + def rels(self) -> Relationships: """ Return a reference to the |Relationships| instance holding the collection of relationships for this package. """ return Relationships(PACKAGE_URI.baseURI) + @rels.setter + def rels(self, new_rels: Relationships): + self._rels = new_rels + + def drop_rels(self, cmp: Callable[[_Relationship], bool]) -> list[str]: + """ + Drop _Relationship by cmp function, related parts will be ignored when save. + """ + rids = [rid for rid, rel in self.rels.items() if cmp(rel)] + for rid in rids: + del self.rels[rid] + return rids + def save(self, pkg_file): """ Save this package to *pkg_file*, where *file* can be either a path to @@ -217,9 +234,7 @@ def unmarshal(pkg_reader, package, part_factory): contents of *pkg_reader*, delegating construction of each part to *part_factory*. Package relationships are added to *pkg*. """ - parts = Unmarshaller._unmarshal_parts( - pkg_reader, package, part_factory - ) + parts = Unmarshaller._unmarshal_parts(pkg_reader, package, part_factory) Unmarshaller._unmarshal_relationships(pkg_reader, package, parts) for part in parts.values(): part.after_unmarshal() @@ -247,7 +262,8 @@ def _unmarshal_relationships(pkg_reader, package, parts): target part in *parts*. """ for source_uri, srel in pkg_reader.iter_srels(): - source = package if source_uri == '/' else parts[source_uri] - target = (srel.target_ref if srel.is_external - else parts[srel.target_partname]) + source = package if source_uri == "/" else parts[source_uri] + target = ( + srel.target_ref if srel.is_external else parts[srel.target_partname] + ) source.load_rel(srel.reltype, target, srel.rId, srel.is_external) diff --git a/docx/opc/part.py b/docx/opc/part.py index 928d3c18..88e7c7bc 100644 --- a/docx/opc/part.py +++ b/docx/opc/part.py @@ -4,15 +4,16 @@ Open Packaging Convention (OPC) objects related to package parts. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import (absolute_import, division, print_function, + unicode_literals) +from typing import Callable + +from ..oxml import parse_xml from .compat import cls_method_fn from .oxml import serialize_part_xml -from ..oxml import parse_xml from .packuri import PackURI -from .rel import Relationships +from .rel import Relationships, _Relationship from .shared import lazyproperty @@ -22,6 +23,7 @@ class Part(object): intended to be subclassed in client code to implement specific part behaviors. """ + def __init__(self, partname, content_type, blob=None, package=None): super(Part, self).__init__() self._partname = partname @@ -74,6 +76,12 @@ def drop_rel(self, rId): if self._rel_ref_count(rId) < 2: del self.rels[rId] + def drop_rels(self, cmp: Callable[[_Relationship], bool]) -> list[str]: + rids = [rid for rid, rel in self.rels.items() if cmp(rel)] + for rid in rids: + del self.rels[rid] + return rids + @classmethod def load(cls, partname, content_type, blob, package): return cls(partname, content_type, blob, package) @@ -127,9 +135,8 @@ def relate_to(self, target, reltype, is_external=False): """ if is_external: return self.rels.get_or_add_ext_rel(reltype, target) - else: - rel = self.rels.get_or_add(reltype, target) - return rel.rId + rel = self.rels.get_or_add(reltype, target) + return rel.rId @property def related_parts(self): @@ -160,7 +167,7 @@ def _rel_ref_count(self, rId): Return the count of references in this part's XML to the relationship identified by *rId*. """ - rIds = self._element.xpath('//@r:id') + rIds = self._element.xpath("//@r:id") return len([_rId for _rId in rIds if _rId == rId]) @@ -177,6 +184,7 @@ class PartFactory(object): either of these, the class contained in ``PartFactory.default_part_type`` is used to construct the part, which is by default ``opc.package.Part``. """ + part_class_selector = None part_type_for = {} default_part_type = Part @@ -184,7 +192,7 @@ class PartFactory(object): def __new__(cls, partname, content_type, reltype, blob, package): PartClass = None if cls.part_class_selector is not None: - part_class_selector = cls_method_fn(cls, 'part_class_selector') + part_class_selector = cls_method_fn(cls, "part_class_selector") PartClass = part_class_selector(content_type, reltype) if PartClass is None: PartClass = cls._part_cls_for(content_type) @@ -209,10 +217,9 @@ class XmlPart(Part): of parsing and reserializing the XML payload and managing relationships to other parts. """ + def __init__(self, partname, content_type, element, package): - super(XmlPart, self).__init__( - partname, content_type, package=package - ) + super(XmlPart, self).__init__(partname, content_type, package=package) self._element = element @property diff --git a/docx/opc/pkgwriter.py b/docx/opc/pkgwriter.py index fccda6cd..1610cbb0 100644 --- a/docx/opc/pkgwriter.py +++ b/docx/opc/pkgwriter.py @@ -22,6 +22,7 @@ class PackageWriter(object): API method, :meth:`write`, is static, so this class is not intended to be instantiated. """ + @staticmethod def write(pkg_file, pkg_rels, parts): """ @@ -71,6 +72,7 @@ class _ContentTypesItem(object): single interface method is xml_for(), e.g. ``_ContentTypesItem.xml_for(parts)``. """ + def __init__(self): self._defaults = CaseInsensitiveDict() self._overrides = dict() @@ -91,8 +93,8 @@ def from_parts(cls, parts): ``[Content_Types].xml`` in an OPC package. """ cti = cls() - cti._defaults['rels'] = CT.OPC_RELATIONSHIPS - cti._defaults['xml'] = CT.XML + cti._defaults["rels"] = CT.OPC_RELATIONSHIPS + cti._defaults["xml"] = CT.XML for part in parts: cti._add_content_type(part.partname, part.content_type) return cti From 8d6a551192507a3360b6876b5941bcf461e4ddd2 Mon Sep 17 00:00:00 2001 From: Ethan Date: Wed, 15 Jun 2022 17:01:38 +0800 Subject: [PATCH 011/115] Revert "added cache for table cells" This reverts commit 8578c4d6944b5a7a09a458f27df2fd610a137534. --- docx/table.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/docx/table.py b/docx/table.py index 1482947f..b3bc090f 100644 --- a/docx/table.py +++ b/docx/table.py @@ -19,8 +19,6 @@ class Table(Parented): def __init__(self, tbl, parent): super(Table, self).__init__(parent) self._element = self._tbl = tbl - self._cached_cells = [] - self._update_cache = True def add_column(self, width): """ @@ -33,7 +31,6 @@ def add_column(self, width): for tr in self._tbl.tr_lst: tc = tr.add_tc() tc.width = width - self._update_cache = True return _Column(gridCol, self) def add_row(self): @@ -45,7 +42,6 @@ def add_row(self): for gridCol in tbl.tblGrid.gridCol_lst: tc = tr.add_tc() tc.width = gridCol.w - self._update_cache = True return _Row(tr, self) @property @@ -169,8 +165,6 @@ def _cells(self): If the table contains a span, one or more |_Cell| object references are repeated. """ - if not self._update_cache: - return self._cached_cells col_count = self._column_count cells = [] for tc in self._tbl.iter_tcs(): @@ -181,8 +175,6 @@ def _cells(self): cells.append(cells[-1]) else: cells.append(_Cell(tc, self)) - self._cached_cells = cells - self._update_cache = False return cells @property From 09911740056d6550c95bc18f9b3b33e7f8347748 Mon Sep 17 00:00:00 2001 From: Ethan Date: Wed, 15 Jun 2022 18:00:40 +0800 Subject: [PATCH 012/115] git ignore build --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e2444513..a15d9208 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ _scratch/ Session.vim /.tox/ +/build/ From e3a3ab9bb3fa6373e88e0003170041a69faa6145 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 16 Jun 2022 10:25:35 +0800 Subject: [PATCH 013/115] py-docx 0.0.1 --- HISTORY.rst | 271 ++--------------------------------------------- docx/__init__.py | 6 +- setup.py | 19 ++-- 3 files changed, 20 insertions(+), 276 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 2b33a4d5..5fd72cb8 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -3,268 +3,13 @@ Release History --------------- -0.8.11 (2021-05-15) +0.0.1 (2022-06-16) +++++++++++++++++++ -- Small build changes and Python 3.8 version changes like collections.abc location. - - -0.8.10 (2019-01-08) -+++++++++++++++++++ - -- Revert use of expanded package directory for default.docx to work around setup.py - problem with filenames containing square brackets. - - -0.8.9 (2019-01-08) -++++++++++++++++++ - -- Fix gap in MANIFEST.in that excluded default document template directory - - -0.8.8 (2019-01-07) -++++++++++++++++++ - -- Add support for headers and footers - - -0.8.7 (2018-08-18) -++++++++++++++++++ - -- Add _Row.height_rule -- Add _Row.height -- Add _Cell.vertical_alignment -- Fix #455: increment next_id, don't fill gaps -- Add #375: import docx failure on --OO optimization -- Add #254: remove default zoom percentage -- Add #266: miscellaneous documentation fixes -- Add #175: refine MANIFEST.ini -- Add #168: Unicode error on core-props in Python 2 - - -0.8.6 (2016-06-22) -++++++++++++++++++ - -- Add #257: add Font.highlight_color -- Add #261: add ParagraphFormat.tab_stops -- Add #303: disallow XML entity expansion - - -0.8.5 (2015-02-21) -++++++++++++++++++ - -- Fix #149: KeyError on Document.add_table() -- Fix #78: feature: add_table() sets cell widths -- Add #106: feature: Table.direction (i.e. right-to-left) -- Add #102: feature: add CT_Row.trPr - - -0.8.4 (2015-02-20) -++++++++++++++++++ - -- Fix #151: tests won't run on PyPI distribution -- Fix #124: default to inches on no TIFF resolution unit - - -0.8.3 (2015-02-19) -++++++++++++++++++ - -- Add #121, #135, #139: feature: Font.color - - -0.8.2 (2015-02-16) -++++++++++++++++++ - -- Fix #94: picture prints at wrong size when scaled -- Extract `docx.document.Document` object from `DocumentPart` - - Refactor `docx.Document` from an object into a factory function for new - `docx.document.Document object`. Extract methods from prior `docx.Document` - and `docx.parts.document.DocumentPart` to form the new API class and retire - `docx.Document` class. - -- Migrate `Document.numbering_part` to `DocumentPart.numbering_part`. The - `numbering_part` property is not part of the published API and is an - interim internal feature to be replaced in a future release, perhaps with - something like `Document.numbering_definitions`. In the meantime, it can - now be accessed using ``Document.part.numbering_part``. - - -0.8.1 (2015-02-10) -++++++++++++++++++ - -- Fix #140: Warning triggered on Document.add_heading/table() - - -0.8.0 (2015-02-08) -++++++++++++++++++ - -- Add styles. Provides general capability to access and manipulate paragraph, - character, and table styles. - -- Add ParagraphFormat object, accessible on Paragraph.paragraph_format, and - providing the following paragraph formatting properties: - - + paragraph alignment (justfification) - + space before and after paragraph - + line spacing - + indentation - + keep together, keep with next, page break before, and widow control - -- Add Font object, accessible on Run.font, providing character-level - formatting including: - - + typeface (e.g. 'Arial') - + point size - + underline - + italic - + bold - + superscript and subscript - -The following issues were retired: - -- Add feature #56: superscript/subscript -- Add feature #67: lookup style by UI name -- Add feature #98: Paragraph indentation -- Add feature #120: Document.styles - -**Backward incompatibilities** - -Paragraph.style now returns a Style object. Previously it returned the style -name as a string. The name can now be retrieved using the Style.name -property, for example, `paragraph.style.name`. - - -0.7.6 (2014-12-14) -++++++++++++++++++ - -- Add feature #69: Table.alignment -- Add feature #29: Document.core_properties - - -0.7.5 (2014-11-29) -++++++++++++++++++ - -- Add feature #65: _Cell.merge() - - -0.7.4 (2014-07-18) -++++++++++++++++++ - -- Add feature #45: _Cell.add_table() -- Add feature #76: _Cell.add_paragraph() -- Add _Cell.tables property (read-only) - - -0.7.3 (2014-07-14) -++++++++++++++++++ - -- Add Table.autofit -- Add feature #46: _Cell.width - - -0.7.2 (2014-07-13) -++++++++++++++++++ - -- Fix: Word does not interpret as line feed - - -0.7.1 (2014-07-11) -++++++++++++++++++ - -- Add feature #14: Run.add_picture() - - -0.7.0 (2014-06-27) -++++++++++++++++++ - -- Add feature #68: Paragraph.insert_paragraph_before() -- Add feature #51: Paragraph.alignment (read/write) -- Add feature #61: Paragraph.text setter -- Add feature #58: Run.add_tab() -- Add feature #70: Run.clear() -- Add feature #60: Run.text setter -- Add feature #39: Run.text and Paragraph.text interpret '\n' and '\t' chars - - -0.6.0 (2014-06-22) -++++++++++++++++++ - -- Add feature #15: section page size -- Add feature #66: add section -- Add page margins and page orientation properties on Section -- Major refactoring of oxml layer - - -0.5.3 (2014-05-10) -++++++++++++++++++ - -- Add feature #19: Run.underline property - - -0.5.2 (2014-05-06) -++++++++++++++++++ - -- Add feature #17: character style - - -0.5.1 (2014-04-02) -++++++++++++++++++ - -- Fix issue #23, `Document.add_picture()` raises ValueError when document - contains VML drawing. - - -0.5.0 (2014-03-02) -++++++++++++++++++ - -- Add 20 tri-state properties on Run, including all-caps, double-strike, - hidden, shadow, small-caps, and 15 others. - - -0.4.0 (2014-03-01) -++++++++++++++++++ - -- Advance from alpha to beta status. -- Add pure-python image header parsing; drop Pillow dependency - - -0.3.0a5 (2014-01-10) -++++++++++++++++++++++ - -- Hotfix: issue #4, Document.add_picture() fails on second and subsequent - images. - - -0.3.0a4 (2014-01-07) -++++++++++++++++++++++ - -- Complete Python 3 support, tested on Python 3.3 - - -0.3.0a3 (2014-01-06) -++++++++++++++++++++++ - -- Fix setup.py error on some Windows installs - - -0.3.0a1 (2014-01-05) -++++++++++++++++++++++ - -- Full object-oriented rewrite -- Feature-parity with prior version -- text: add paragraph, run, text, bold, italic -- table: add table, add row, add column -- styles: specify style for paragraph, table -- picture: add inline picture, auto-scaling -- breaks: add page break -- tests: full pytest and behave-based 2-layer test suite - - -0.3.0dev1 (2013-12-14) -++++++++++++++++++++++ - -- Round-trip .docx file, preserving all parts and relationships -- Load default "template" .docx on open with no filename -- Open from stream and save to stream (file-like object) -- Add paragraph at and of document +- Only support Python3.8, 3.9 and 3.10. +- Add custom properties support. PR-#2 +- Add drop_rels in Package. PR-#5 +- Add drop_rels in Part. PR-#5 +- Add default NumberingPart. PR-#4 +- Fix Python3.8+ __dict__ TypeError. PR-#6 +- Add some typehint. diff --git a/docx/__init__.py b/docx/__init__.py index 5b85616d..17b106bd 100644 --- a/docx/__init__.py +++ b/docx/__init__.py @@ -2,16 +2,16 @@ from docx.api import Document # noqa -__version__ = "0.8.11" +__version__ = "0.0.1" # register custom Part classes with opc package reader -from docx.opc.constants import CONTENT_TYPE as CT, RELATIONSHIP_TYPE as RT +from docx.opc.constants import CONTENT_TYPE as CT +from docx.opc.constants import RELATIONSHIP_TYPE as RT from docx.opc.part import PartFactory from docx.opc.parts.coreprops import CorePropertiesPart from docx.opc.parts.customprops import CustomPropertiesPart - from docx.parts.document import DocumentPart from docx.parts.hdrftr import FooterPart, HeaderPart from docx.parts.image import ImagePart diff --git a/setup.py b/setup.py index d7ad391e..7e5f552d 100644 --- a/setup.py +++ b/setup.py @@ -24,18 +24,18 @@ def text_of(relpath): version = re.search(r'__version__ = "([^"]+)"', text_of("docx/__init__.py")).group(1) -NAME = "python-docx" +NAME = "py-docx" VERSION = version DESCRIPTION = "Create and update Microsoft Word .docx files." -KEYWORDS = "docx office openxml word" -AUTHOR = "Steve Canny" -AUTHOR_EMAIL = "python-docx@googlegroups.com" -URL = "https://github.com/python-openxml/python-docx" +KEYWORDS = "docx office openxml word python-docx" +AUTHOR = "Ethan St. Lee" +AUTHOR_EMAIL = "ethan@ginolegaltech.cn" +URL = "https://github.com/lsaint/py-docx" LICENSE = text_of("LICENSE") PACKAGES = find_packages(exclude=["tests", "tests.*"]) PACKAGE_DATA = {"docx": ["templates/*.xml", "templates/*.docx"]} -INSTALL_REQUIRES = ["lxml>=2.3.2"] +INSTALL_REQUIRES = ["lxml>=4.9.0"] TEST_SUITE = "tests" TESTS_REQUIRE = ["behave", "mock", "pyparsing", "pytest"] @@ -45,10 +45,9 @@ def text_of(relpath): "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 3.8" - "Programming Language :: Python :: 3.9" - "Programming Language :: Python :: 3.10" + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", "Topic :: Office/Business :: Office Suites", "Topic :: Software Development :: Libraries", ] From 8d98d60b8ccd86bbee7aa43f3c94672b5e2b9e0a Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 16 Jun 2022 10:31:22 +0800 Subject: [PATCH 014/115] use twine instead of setup.py to upload --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f335818f..99f6c4bc 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ BEHAVE = behave MAKE = make PYTHON = python +TWINE = twine SETUP = $(PYTHON) ./setup.py .PHONY: accept clean coverage docs readme register sdist test upload @@ -43,4 +44,4 @@ sdist: $(SETUP) sdist upload: - $(SETUP) sdist upload + $(TWINE) upload dist/* From ac937a1cb5e956ad3942f40bf9e4db46e17e0b9b Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 16 Jun 2022 11:00:03 +0800 Subject: [PATCH 015/115] python-docx-oss v0.0.1 --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 7e5f552d..6eb95466 100644 --- a/setup.py +++ b/setup.py @@ -24,13 +24,13 @@ def text_of(relpath): version = re.search(r'__version__ = "([^"]+)"', text_of("docx/__init__.py")).group(1) -NAME = "py-docx" +NAME = "python-docx-oss" VERSION = version DESCRIPTION = "Create and update Microsoft Word .docx files." KEYWORDS = "docx office openxml word python-docx" AUTHOR = "Ethan St. Lee" AUTHOR_EMAIL = "ethan@ginolegaltech.cn" -URL = "https://github.com/lsaint/py-docx" +URL = "https://github.com/lsaint/python-docx-oss" LICENSE = text_of("LICENSE") PACKAGES = find_packages(exclude=["tests", "tests.*"]) PACKAGE_DATA = {"docx": ["templates/*.xml", "templates/*.docx"]} From 790576e6855abc6ff22c8829fb465ee7aba6c7dc Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 17 Jun 2022 18:47:50 +0800 Subject: [PATCH 016/115] unittest drop_rels (#8) * unittest drop_rels * TestOpcPackage --- requirements.txt | 1 + tests/image/test_image.py | 10 +-- tests/opc/test_part.py | 163 ++++++++++++++++++++----------------- tests/opc/test_phys_pkg.py | 66 ++++++++------- tests/parts/test_image.py | 35 ++++---- tests/test_package.py | 49 ++++++++--- tests/unitutil/file.py | 24 +++--- tox.ini | 3 +- 8 files changed, 193 insertions(+), 158 deletions(-) diff --git a/requirements.txt b/requirements.txt index 63db5070..dd248962 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,4 @@ lxml>=4.9.0 mock>=4.0.3 pyparsing>=2.4.7 pytest>=6.2.5 +pytest-mock>=3.7.0 diff --git a/tests/image/test_image.py b/tests/image/test_image.py index 07f9d066..d1ea618b 100644 --- a/tests/image/test_image.py +++ b/tests/image/test_image.py @@ -17,7 +17,7 @@ from docx.opc.constants import CONTENT_TYPE as CT from docx.shared import Emu, Length -from ..unitutil.file import test_file +from ..unitutil.file import testfile from ..unitutil.mock import ( ANY, class_mock, @@ -121,7 +121,7 @@ def it_correctly_characterizes_known_images(self, known_image_fixture): ext, content_type, px_width, px_height, horz_dpi, vert_dpi = ( characteristics ) - with open(test_file(image_path), 'rb') as stream: + with open(testfile(image_path), 'rb') as stream: image = Image.from_file(stream) assert image.content_type == content_type assert image.ext == ext @@ -154,7 +154,7 @@ def dpi_fixture(self, image_header_): @pytest.fixture def from_filelike_fixture(self, _from_stream_, image_): - image_path = test_file('python-icon.png') + image_path = testfile('python-icon.png') with open(image_path, 'rb') as f: blob = f.read() image_stream = BytesIO(blob) @@ -163,7 +163,7 @@ def from_filelike_fixture(self, _from_stream_, image_): @pytest.fixture def from_path_fixture(self, _from_stream_, BytesIO_, stream_, image_): filename = 'python-icon.png' - image_path = test_file(filename) + image_path = testfile(filename) with open(image_path, 'rb') as f: blob = f.read() return image_path, _from_stream_, stream_, blob, filename, image_ @@ -296,7 +296,7 @@ def it_raises_on_unrecognized_image_stream(self): ]) def call_fixture(self, request): image_filename, expected_class = request.param - image_path = test_file(image_filename) + image_path = testfile(image_filename) with open(image_path, 'rb') as f: blob = f.read() image_stream = BytesIO(blob) diff --git a/tests/opc/test_part.py b/tests/opc/test_part.py index cc60beaa..854b8ee6 100644 --- a/tests/opc/test_part.py +++ b/tests/opc/test_part.py @@ -2,31 +2,24 @@ """Unit test suite for docx.opc.part module""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import (absolute_import, division, print_function, + unicode_literals) import pytest from docx.opc.package import OpcPackage from docx.opc.packuri import PackURI from docx.opc.part import Part, PartFactory, XmlPart -from docx.opc.rel import _Relationship, Relationships +from docx.opc.rel import Relationships, _Relationship from docx.oxml.xmlchemy import BaseOxmlElement from ..unitutil.cxml import element -from ..unitutil.mock import ( - ANY, - class_mock, - cls_attr_mock, - function_mock, - initializer_mock, - instance_mock, - loose_mock, - Mock, -) +from ..unitutil.mock import (ANY, Mock, class_mock, cls_attr_mock, + function_mock, initializer_mock, instance_mock, + loose_mock) class DescribePart(object): - def it_can_be_constructed_by_PartFactory( self, partname_, content_type_, blob_, package_, __init_ ): @@ -71,7 +64,7 @@ def blob_fixture(self, blob_): @pytest.fixture def content_type_fixture(self): - content_type = 'content/type' + content_type = "content/type" part = Part(None, content_type, None, None) return part, content_type @@ -82,19 +75,18 @@ def package_get_fixture(self, package_): @pytest.fixture def part(self): - part = Part(None, None) - return part + return Part(None, None) @pytest.fixture def partname_get_fixture(self): - partname = PackURI('/part/name') + partname = PackURI("/part/name") part = Part(partname, None, None, None) return part, partname @pytest.fixture def partname_set_fixture(self): - old_partname = PackURI('/old/part/name') - new_partname = PackURI('/new/part/name') + old_partname = PackURI("/old/part/name") + new_partname = PackURI("/new/part/name") part = Part(old_partname, None, None, None) return part, new_partname @@ -122,7 +114,6 @@ def partname_(self, request): class DescribePartRelationshipManagementInterface(object): - def it_provides_access_to_its_relationships(self, rels_fixture): part, Relationships_, partname_, rels_ = rels_fixture rels = part.rels @@ -132,19 +123,15 @@ def it_provides_access_to_its_relationships(self, rels_fixture): def it_can_load_a_relationship(self, load_rel_fixture): part, rels_, reltype_, target_, rId_ = load_rel_fixture part.load_rel(reltype_, target_, rId_) - rels_.add_relationship.assert_called_once_with( - reltype_, target_, rId_, False - ) + rels_.add_relationship.assert_called_once_with(reltype_, target_, rId_, False) - def it_can_establish_a_relationship_to_another_part( - self, relate_to_part_fixture): + def it_can_establish_a_relationship_to_another_part(self, relate_to_part_fixture): part, target_, reltype_, rId_ = relate_to_part_fixture rId = part.relate_to(target_, reltype_) part.rels.get_or_add.assert_called_once_with(reltype_, target_) assert rId is rId_ - def it_can_establish_an_external_relationship( - self, relate_to_url_fixture): + def it_can_establish_an_external_relationship(self, relate_to_url_fixture): part, url_, reltype_, rId_ = relate_to_url_fixture rId = part.relate_to(url_, reltype_, is_external=True) part.rels.get_or_add_ext_rel.assert_called_once_with(reltype_, url_) @@ -168,22 +155,23 @@ def it_can_find_a_related_part_by_rId(self, related_parts_fixture): part, related_parts_ = related_parts_fixture assert part.related_parts is related_parts_ - def it_can_find_the_uri_of_an_external_relationship( - self, target_ref_fixture): + def it_can_find_the_uri_of_an_external_relationship(self, target_ref_fixture): part, rId_, url_ = target_ref_fixture url = part.target_ref(rId_) assert url == url_ # fixtures --------------------------------------------- - @pytest.fixture(params=[ - ('w:p', True), - ('w:p/r:a{r:id=rId42}', True), - ('w:p/r:a{r:id=rId42}/r:b{r:id=rId42}', False), - ]) + @pytest.fixture( + params=[ + ("w:p", True), + ("w:p/r:a{r:id=rId42}", True), + ("w:p/r:a{r:id=rId42}/r:b{r:id=rId42}", False), + ] + ) def drop_rel_fixture(self, request, part): part_cxml, rel_should_be_dropped = request.param - rId = 'rId42' + rId = "rId42" part._element = element(part_cxml) part._rels = {rId: None} return part, rId, rel_should_be_dropped @@ -194,15 +182,13 @@ def load_rel_fixture(self, part, rels_, reltype_, part_, rId_): return part, rels_, reltype_, part_, rId_ @pytest.fixture - def relate_to_part_fixture( - self, request, part, reltype_, part_, rels_, rId_): + def relate_to_part_fixture(self, request, part, reltype_, part_, rels_, rId_): part._rels = rels_ target_ = part_ return part, target_, reltype_, rId_ @pytest.fixture - def relate_to_url_fixture( - self, request, part, rels_, url_, reltype_, rId_): + def relate_to_url_fixture(self, request, part, rels_, url_, reltype_, rId_): part._rels = rels_ return part, url_, reltype_, rId_ @@ -242,15 +228,11 @@ def partname_(self, request): @pytest.fixture def Relationships_(self, request, rels_): - return class_mock( - request, 'docx.opc.part.Relationships', return_value=rels_ - ) + return class_mock(request, "docx.opc.part.Relationships", return_value=rels_) @pytest.fixture def rel_(self, request, rId_, url_): - return instance_mock( - request, _Relationship, rId=rId_, target_ref=url_ - ) + return instance_mock(request, _Relationship, rId=rId_, target_ref=url_) @pytest.fixture def rels_(self, request, part_, rel_, rId_, related_parts_): @@ -279,12 +261,14 @@ def url_(self, request): class DescribePartFactory(object): - - def it_constructs_part_from_selector_if_defined( - self, cls_selector_fixture): + def it_constructs_part_from_selector_if_defined(self, cls_selector_fixture): # fixture ---------------------- - (cls_selector_fn_, part_load_params, CustomPartClass_, - part_of_custom_type_) = cls_selector_fixture + ( + cls_selector_fn_, + part_load_params, + CustomPartClass_, + part_of_custom_type_, + ) = cls_selector_fixture partname, content_type, reltype, blob, package = part_load_params # exercise --------------------- PartFactory.part_class_selector = cls_selector_fn_ @@ -297,7 +281,8 @@ def it_constructs_part_from_selector_if_defined( assert part is part_of_custom_type_ def it_constructs_custom_part_type_for_registered_content_types( - self, part_args_, CustomPartClass_, part_of_custom_type_): + self, part_args_, CustomPartClass_, part_of_custom_type_ + ): # fixture ---------------------- partname, content_type, reltype, package, blob = part_args_ # exercise --------------------- @@ -310,7 +295,8 @@ def it_constructs_custom_part_type_for_registered_content_types( assert part is part_of_custom_type_ def it_constructs_part_using_default_class_when_no_custom_registered( - self, part_args_2_, DefaultPartClass_, part_of_default_type_): + self, part_args_2_, DefaultPartClass_, part_of_default_type_ + ): partname, content_type, reltype, blob, package = part_args_2_ part = PartFactory(partname, content_type, reltype, blob, package) DefaultPartClass_.load.assert_called_once_with( @@ -331,21 +317,29 @@ def blob_2_(self, request): @pytest.fixture def cls_method_fn_(self, request, cls_selector_fn_): return function_mock( - request, 'docx.opc.part.cls_method_fn', - return_value=cls_selector_fn_ + request, "docx.opc.part.cls_method_fn", return_value=cls_selector_fn_ ) @pytest.fixture def cls_selector_fixture( - self, request, cls_selector_fn_, cls_method_fn_, part_load_params, - CustomPartClass_, part_of_custom_type_): + self, + request, + cls_selector_fn_, + cls_method_fn_, + part_load_params, + CustomPartClass_, + part_of_custom_type_, + ): def reset_part_class_selector(): PartFactory.part_class_selector = original_part_class_selector + original_part_class_selector = PartFactory.part_class_selector request.addfinalizer(reset_part_class_selector) return ( - cls_selector_fn_, part_load_params, CustomPartClass_, - part_of_custom_type_ + cls_selector_fn_, + part_load_params, + CustomPartClass_, + part_of_custom_type_, ) @pytest.fixture @@ -355,7 +349,7 @@ def cls_selector_fn_(self, request, CustomPartClass_): cls_selector_fn_.return_value = CustomPartClass_ # Python 2 version cls_selector_fn_.__func__ = loose_mock( - request, name='__func__', return_value=cls_selector_fn_ + request, name="__func__", return_value=cls_selector_fn_ ) return cls_selector_fn_ @@ -369,15 +363,13 @@ def content_type_2_(self, request): @pytest.fixture def CustomPartClass_(self, request, part_of_custom_type_): - CustomPartClass_ = Mock(name='CustomPartClass', spec=Part) + CustomPartClass_ = Mock(name="CustomPartClass", spec=Part) CustomPartClass_.load.return_value = part_of_custom_type_ return CustomPartClass_ @pytest.fixture def DefaultPartClass_(self, request, part_of_default_type_): - DefaultPartClass_ = cls_attr_mock( - request, PartFactory, 'default_part_type' - ) + DefaultPartClass_ = cls_attr_mock(request, PartFactory, "default_part_type") DefaultPartClass_.load.return_value = part_of_default_type_ return DefaultPartClass_ @@ -390,8 +382,7 @@ def package_2_(self, request): return instance_mock(request, OpcPackage) @pytest.fixture - def part_load_params( - self, partname_, content_type_, reltype_, blob_, package_): + def part_load_params(self, partname_, content_type_, reltype_, blob_, package_): return partname_, content_type_, reltype_, blob_, package_ @pytest.fixture @@ -411,15 +402,13 @@ def partname_2_(self, request): return instance_mock(request, PackURI) @pytest.fixture - def part_args_( - self, request, partname_, content_type_, reltype_, package_, - blob_): + def part_args_(self, request, partname_, content_type_, reltype_, package_, blob_): return partname_, content_type_, reltype_, blob_, package_ @pytest.fixture def part_args_2_( - self, request, partname_2_, content_type_2_, reltype_2_, - package_2_, blob_2_): + self, request, partname_2_, content_type_2_, reltype_2_, package_2_, blob_2_ + ): return partname_2_, content_type_2_, reltype_2_, blob_2_, package_2_ @pytest.fixture @@ -432,7 +421,6 @@ def reltype_2_(self, request): class DescribeXmlPart(object): - def it_can_be_constructed_by_PartFactory( self, partname_, content_type_, blob_, package_, element_, parse_xml_, __init_ ): @@ -489,9 +477,7 @@ def package_(self, request): @pytest.fixture def parse_xml_(self, request, element_): - return function_mock( - request, 'docx.opc.part.parse_xml', return_value=element_ - ) + return function_mock(request, "docx.opc.part.parse_xml", return_value=element_) @pytest.fixture def partname_(self, request): @@ -499,6 +485,31 @@ def partname_(self, request): @pytest.fixture def serialize_part_xml_(self, request): - return function_mock( - request, 'docx.opc.part.serialize_part_xml' + return function_mock(request, "docx.opc.part.serialize_part_xml") + + +class TestPart: + def test_drop_rels(self, part_with_rels): + def cmp(rel): + return rel.target_part == "target1" + + ret = part_with_rels.drop_rels(cmp) + assert len(part_with_rels.rels) == 1 + assert part_with_rels.rels["rId2"].target_part == "target2" + assert ret == ["rId1"] + + @pytest.fixture + def part_with_rels(self, mocker, rels): + mocker.patch( + "docx.opc.part.Part.rels", + new_callable=mocker.PropertyMock, + return_value=rels, ) + return Part("null", None) + + @pytest.fixture + def rels(self): + rels = Relationships(None) + rels["rId1"] = _Relationship("rId1", "reltype1", "target1", "base1") + rels["rId2"] = _Relationship("rId2", "reltype2", "target2", "base2") + return rels diff --git a/tests/opc/test_phys_pkg.py b/tests/opc/test_phys_pkg.py index 7e62cfd8..25cf1554 100644 --- a/tests/opc/test_phys_pkg.py +++ b/tests/opc/test_phys_pkg.py @@ -19,45 +19,47 @@ from docx.opc.exceptions import PackageNotFoundError from docx.opc.packuri import PACKAGE_URI, PackURI from docx.opc.phys_pkg import ( - _DirPkgReader, PhysPkgReader, PhysPkgWriter, _ZipPkgReader, _ZipPkgWriter + _DirPkgReader, + PhysPkgReader, + PhysPkgWriter, + _ZipPkgReader, + _ZipPkgWriter, ) -from ..unitutil.file import absjoin, test_file_dir +from ..unitutil.file import absjoin, testfile_dir from ..unitutil.mock import class_mock, loose_mock, Mock -test_docx_path = absjoin(test_file_dir, 'test.docx') -dir_pkg_path = absjoin(test_file_dir, 'expanded_docx') +test_docx_path = absjoin(testfile_dir, "test.docx") +dir_pkg_path = absjoin(testfile_dir, "expanded_docx") zip_pkg_path = test_docx_path class DescribeDirPkgReader(object): - def it_is_used_by_PhysPkgReader_when_pkg_is_a_dir(self): phys_reader = PhysPkgReader(dir_pkg_path) assert isinstance(phys_reader, _DirPkgReader) - def it_doesnt_mind_being_closed_even_though_it_doesnt_need_it( - self, dir_reader): + def it_doesnt_mind_being_closed_even_though_it_doesnt_need_it(self, dir_reader): dir_reader.close() def it_can_retrieve_the_blob_for_a_pack_uri(self, dir_reader): - pack_uri = PackURI('/word/document.xml') + pack_uri = PackURI("/word/document.xml") blob = dir_reader.blob_for(pack_uri) sha1 = hashlib.sha1(blob).hexdigest() - assert sha1 == '0e62d87ea74ea2b8088fd11ee97b42da9b4c77b0' + assert sha1 == "0e62d87ea74ea2b8088fd11ee97b42da9b4c77b0" def it_can_get_the_content_types_xml(self, dir_reader): sha1 = hashlib.sha1(dir_reader.content_types_xml).hexdigest() - assert sha1 == '89aadbb12882dd3d7340cd47382dc2c73d75dd81' + assert sha1 == "89aadbb12882dd3d7340cd47382dc2c73d75dd81" def it_can_retrieve_the_rels_xml_for_a_source_uri(self, dir_reader): rels_xml = dir_reader.rels_xml_for(PACKAGE_URI) sha1 = hashlib.sha1(rels_xml).hexdigest() - assert sha1 == 'ebacdddb3e7843fdd54c2f00bc831551b26ac823' + assert sha1 == "ebacdddb3e7843fdd54c2f00bc831551b26ac823" def it_returns_none_when_part_has_no_rels_xml(self, dir_reader): - partname = PackURI('/ppt/viewProps.xml') + partname = PackURI("/ppt/viewProps.xml") rels_xml = dir_reader.rels_xml_for(partname) assert rels_xml is None @@ -67,32 +69,30 @@ def it_returns_none_when_part_has_no_rels_xml(self, dir_reader): def pkg_file_(self, request): return loose_mock(request) - @pytest.fixture(scope='class') + @pytest.fixture(scope="class") def dir_reader(self): return _DirPkgReader(dir_pkg_path) class DescribePhysPkgReader(object): - def it_raises_when_pkg_path_is_not_a_package(self): with pytest.raises(PackageNotFoundError): - PhysPkgReader('foobar') + PhysPkgReader("foobar") class DescribeZipPkgReader(object): - def it_is_used_by_PhysPkgReader_when_pkg_is_a_zip(self): phys_reader = PhysPkgReader(zip_pkg_path) assert isinstance(phys_reader, _ZipPkgReader) def it_is_used_by_PhysPkgReader_when_pkg_is_a_stream(self): - with open(zip_pkg_path, 'rb') as stream: + with open(zip_pkg_path, "rb") as stream: phys_reader = PhysPkgReader(stream) assert isinstance(phys_reader, _ZipPkgReader) def it_opens_pkg_file_zip_on_construction(self, ZipFile_, pkg_file_): _ZipPkgReader(pkg_file_) - ZipFile_.assert_called_once_with(pkg_file_, 'r') + ZipFile_.assert_called_once_with(pkg_file_, "r") def it_can_be_closed(self, ZipFile_): # mockery ---------------------- @@ -104,28 +104,28 @@ def it_can_be_closed(self, ZipFile_): zipf.close.assert_called_once_with() def it_can_retrieve_the_blob_for_a_pack_uri(self, phys_reader): - pack_uri = PackURI('/word/document.xml') + pack_uri = PackURI("/word/document.xml") blob = phys_reader.blob_for(pack_uri) sha1 = hashlib.sha1(blob).hexdigest() - assert sha1 == 'b9b4a98bcac7c5a162825b60c3db7df11e02ac5f' + assert sha1 == "b9b4a98bcac7c5a162825b60c3db7df11e02ac5f" def it_has_the_content_types_xml(self, phys_reader): sha1 = hashlib.sha1(phys_reader.content_types_xml).hexdigest() - assert sha1 == 'cd687f67fd6b5f526eedac77cf1deb21968d7245' + assert sha1 == "cd687f67fd6b5f526eedac77cf1deb21968d7245" def it_can_retrieve_rels_xml_for_source_uri(self, phys_reader): rels_xml = phys_reader.rels_xml_for(PACKAGE_URI) sha1 = hashlib.sha1(rels_xml).hexdigest() - assert sha1 == '90965123ed2c79af07a6963e7cfb50a6e2638565' + assert sha1 == "90965123ed2c79af07a6963e7cfb50a6e2638565" def it_returns_none_when_part_has_no_rels_xml(self, phys_reader): - partname = PackURI('/ppt/viewProps.xml') + partname = PackURI("/ppt/viewProps.xml") rels_xml = phys_reader.rels_xml_for(partname) assert rels_xml is None # fixtures --------------------------------------------- - @pytest.fixture(scope='class') + @pytest.fixture(scope="class") def phys_reader(self, request): phys_reader = _ZipPkgReader(zip_pkg_path) request.addfinalizer(phys_reader.close) @@ -137,17 +137,14 @@ def pkg_file_(self, request): class DescribeZipPkgWriter(object): - def it_is_used_by_PhysPkgWriter_unconditionally(self, tmp_docx_path): phys_writer = PhysPkgWriter(tmp_docx_path) assert isinstance(phys_writer, _ZipPkgWriter) def it_opens_pkg_file_zip_on_construction(self, ZipFile_): - pkg_file = Mock(name='pkg_file') + pkg_file = Mock(name="pkg_file") _ZipPkgWriter(pkg_file) - ZipFile_.assert_called_once_with( - pkg_file, 'w', compression=ZIP_DEFLATED - ) + ZipFile_.assert_called_once_with(pkg_file, "w", compression=ZIP_DEFLATED) def it_can_be_closed(self, ZipFile_): # mockery ---------------------- @@ -160,15 +157,15 @@ def it_can_be_closed(self, ZipFile_): def it_can_write_a_blob(self, pkg_file): # setup ------------------------ - pack_uri = PackURI('/part/name.xml') - blob = ''.encode('utf-8') + pack_uri = PackURI("/part/name.xml") + blob = "".encode("utf-8") # exercise --------------------- pkg_writer = PhysPkgWriter(pkg_file) pkg_writer.write(pack_uri, blob) pkg_writer.close() # verify ----------------------- written_blob_sha1 = hashlib.sha1(blob).hexdigest() - zipf = ZipFile(pkg_file, 'r') + zipf = ZipFile(pkg_file, "r") retrieved_blob = zipf.read(pack_uri.membername) zipf.close() retrieved_blob_sha1 = hashlib.sha1(retrieved_blob).hexdigest() @@ -185,11 +182,12 @@ def pkg_file(self, request): # fixtures ------------------------------------------------- + @pytest.fixture def tmp_docx_path(tmpdir): - return str(tmpdir.join('test_python-docx.docx')) + return str(tmpdir.join("test_python-docx.docx")) @pytest.fixture def ZipFile_(request): - return class_mock(request, 'docx.opc.phys_pkg.ZipFile') + return class_mock(request, "docx.opc.phys_pkg.ZipFile") diff --git a/tests/parts/test_image.py b/tests/parts/test_image.py index 1ab2490b..c94fb167 100644 --- a/tests/parts/test_image.py +++ b/tests/parts/test_image.py @@ -13,12 +13,11 @@ from docx.package import Package from docx.parts.image import ImagePart -from ..unitutil.file import test_file +from ..unitutil.file import testfile from ..unitutil.mock import ANY, initializer_mock, instance_mock, method_mock class DescribeImagePart(object): - def it_is_used_by_PartFactory_to_construct_image_part( self, image_part_load_, partname_, blob_, package_, image_part_ ): @@ -51,9 +50,9 @@ def it_knows_its_filename(self, filename_fixture): assert image_part.filename == expected_filename def it_knows_the_sha1_of_its_image(self): - blob = b'fO0Bar' + blob = b"fO0Bar" image_part = ImagePart(None, None, blob) - assert image_part.sha1 == '4921e7002ddfba690a937d54bda226a7b8bdeb68' + assert image_part.sha1 == "4921e7002ddfba690a937d54bda226a7b8bdeb68" # fixtures ------------------------------------------------------- @@ -61,33 +60,31 @@ def it_knows_the_sha1_of_its_image(self): def blob_(self, request): return instance_mock(request, str) - @pytest.fixture(params=['loaded', 'new']) + @pytest.fixture(params=["loaded", "new"]) def dimensions_fixture(self, request): - image_file_path = test_file('monty-truth.png') + image_file_path = testfile("monty-truth.png") image = Image.from_file(image_file_path) expected_cx, expected_cy = 1905000, 2717800 # case 1: image part is loaded by PartFactory w/no Image inst - if request.param == 'loaded': - partname = PackURI('/word/media/image1.png') + if request.param == "loaded": + partname = PackURI("/word/media/image1.png") content_type = CT.PNG - image_part = ImagePart.load( - partname, content_type, image.blob, None - ) + image_part = ImagePart.load(partname, content_type, image.blob, None) # case 2: image part is newly created from image file - elif request.param == 'new': + elif request.param == "new": image_part = ImagePart.from_image(image, None) return image_part, expected_cx, expected_cy - @pytest.fixture(params=['loaded', 'new']) + @pytest.fixture(params=["loaded", "new"]) def filename_fixture(self, request, image_): - partname = PackURI('/word/media/image666.png') - if request.param == 'loaded': + partname = PackURI("/word/media/image666.png") + if request.param == "loaded": image_part = ImagePart(partname, None, None, None) - expected_filename = 'image.png' - elif request.param == 'new': - image_.filename = 'foobar.PXG' + expected_filename = "image.png" + elif request.param == "new": + image_.filename = "foobar.PXG" image_part = ImagePart(partname, None, None, image_) expected_filename = image_.filename return image_part, expected_filename @@ -106,7 +103,7 @@ def image_part_(self, request): @pytest.fixture def image_part_load_(self, request): - return method_mock(request, ImagePart, 'load', autospec=False) + return method_mock(request, ImagePart, "load", autospec=False) @pytest.fixture def package_(self, request): diff --git a/tests/test_package.py b/tests/test_package.py index c4df206a..4f897997 100644 --- a/tests/test_package.py +++ b/tests/test_package.py @@ -7,7 +7,9 @@ import pytest from docx.image.image import Image +from docx.opc.package import OpcPackage from docx.opc.packuri import PackURI +from docx.opc.rel import Relationships, _Relationship from docx.package import ImageParts, Package from docx.parts.image import ImagePart @@ -16,7 +18,6 @@ class DescribePackage(object): - def it_can_get_or_add_an_image_part_containing_a_specified_image( self, image_parts_prop_, image_parts_, image_part_ ): @@ -30,7 +31,7 @@ def it_can_get_or_add_an_image_part_containing_a_specified_image( assert image_part is image_part_ def it_gathers_package_image_parts_after_unmarshalling(self): - package = Package.open(docx_path('having-images')) + package = Package.open(docx_path("having-images")) image_parts = package.image_parts assert len(image_parts) == 3 for image_part in image_parts: @@ -52,7 +53,6 @@ def image_parts_prop_(self, request): class DescribeImageParts(object): - def it_can_get_a_matching_image_part( self, Image_, image_, _get_by_sha1_, image_part_ ): @@ -104,20 +104,19 @@ def it_can_really_add_a_new_image_part( @pytest.fixture(params=[((2, 3), 1), ((1, 3), 2), ((1, 2), 3)]) def next_partname_fixture(self, request): - def image_part_with_partname_(n): partname = image_partname(n) return instance_mock(request, ImagePart, partname=partname) def image_partname(n): - return PackURI('/word/media/image%d.png' % n) + return PackURI("/word/media/image%d.png" % n) existing_partname_numbers, expected_partname_number = request.param image_parts = ImageParts() for n in existing_partname_numbers: image_part_ = image_part_with_partname_(n) image_parts.append(image_part_) - ext = 'png' + ext = "png" expected_image_partname = image_partname(expected_partname_number) return image_parts, ext, expected_image_partname @@ -125,15 +124,15 @@ def image_partname(n): @pytest.fixture def _add_image_part_(self, request): - return method_mock(request, ImageParts, '_add_image_part') + return method_mock(request, ImageParts, "_add_image_part") @pytest.fixture def _get_by_sha1_(self, request): - return method_mock(request, ImageParts, '_get_by_sha1') + return method_mock(request, ImageParts, "_get_by_sha1") @pytest.fixture def Image_(self, request): - return class_mock(request, 'docx.package.Image') + return class_mock(request, "docx.package.Image") @pytest.fixture def image_(self, request): @@ -141,7 +140,7 @@ def image_(self, request): @pytest.fixture def ImagePart_(self, request): - return class_mock(request, 'docx.package.ImagePart') + return class_mock(request, "docx.package.ImagePart") @pytest.fixture def image_part_(self, request): @@ -149,8 +148,36 @@ def image_part_(self, request): @pytest.fixture def _next_image_partname_(self, request): - return method_mock(request, ImageParts, '_next_image_partname') + return method_mock(request, ImageParts, "_next_image_partname") @pytest.fixture def partname_(self, request): return instance_mock(request, PackURI) + + +class TestOpcPackage: + def test_drop_rels(self, package_with_rels): + def cmp(rel): + return "2" in rel.reltype + + ret = package_with_rels.drop_rels(cmp) + assert len(package_with_rels.rels) == 2 + assert package_with_rels.rels["rId3"].reltype == "reltype3" + assert ret == ["rId2"] + + @pytest.fixture + def package_with_rels(self, mocker, rels): + mocker.patch( + "docx.opc.package.OpcPackage.rels", + new_callable=mocker.PropertyMock, + return_value=rels, + ) + return OpcPackage() + + @pytest.fixture + def rels(self): + rels = Relationships(None) + rels["rId1"] = _Relationship("rId1", "reltype1", "target1", "base1") + rels["rId2"] = _Relationship("rId2", "reltype2", "target2", "base2") + rels["rId3"] = _Relationship("rId3", "reltype3", "target3", "base3") + return rels diff --git a/tests/unitutil/file.py b/tests/unitutil/file.py index 8462e6c4..aa99b0b3 100644 --- a/tests/unitutil/file.py +++ b/tests/unitutil/file.py @@ -8,7 +8,7 @@ _thisdir = os.path.split(__file__)[0] -test_file_dir = os.path.abspath(os.path.join(_thisdir, '..', 'test_files')) +testfile_dir = os.path.abspath(os.path.join(_thisdir, "..", "test_files")) def abspath(relpath): @@ -24,7 +24,7 @@ def docx_path(name): """ Return the absolute path to test .docx file with root name *name*. """ - return absjoin(test_file_dir, '%s.docx' % name) + return absjoin(testfile_dir, "%s.docx" % name) def snippet_seq(name, offset=0, count=1024): @@ -33,11 +33,11 @@ def snippet_seq(name, offset=0, count=1024): file having *name*. Snippets are delimited by a blank line. If specified, *count* snippets starting at *offset* are returned. """ - path = os.path.join(test_file_dir, 'snippets', '%s.txt' % name) - with open(path, 'rb') as f: - text = f.read().decode('utf-8') - snippets = text.split('\n\n') - start, end = offset, offset+count + path = os.path.join(testfile_dir, "snippets", "%s.txt" % name) + with open(path, "rb") as f: + text = f.read().decode("utf-8") + snippets = text.split("\n\n") + start, end = offset, offset + count return tuple(snippets[start:end]) @@ -47,15 +47,15 @@ def snippet_text(snippet_file_name): *snippet_file_name*. """ snippet_file_path = os.path.join( - test_file_dir, 'snippets', '%s.txt' % snippet_file_name + testfile_dir, "snippets", "%s.txt" % snippet_file_name ) - with open(snippet_file_path, 'rb') as f: + with open(snippet_file_path, "rb") as f: snippet_bytes = f.read() - return snippet_bytes.decode('utf-8') + return snippet_bytes.decode("utf-8") -def test_file(name): +def testfile(name): """ Return the absolute path to test file having *name*. """ - return absjoin(test_file_dir, name) + return absjoin(testfile_dir, name) diff --git a/tox.ini b/tox.ini index a1319eb5..27f8e25b 100644 --- a/tox.ini +++ b/tox.ini @@ -9,7 +9,7 @@ max-line-length = 88 norecursedirs = doc docx *.egg-info features .git ref _scratch .tox python_files = test_*.py python_classes = Test Describe -python_functions = it_ they_ and_it_ but_it_ +python_functions = it_ they_ and_it_ but_it_ test_ [tox] envlist = py38, py39, py310 @@ -20,6 +20,7 @@ deps = lxml pyparsing pytest + pytest-mock commands = pytest -qx From 56ed84849c42f5ef94f890ca274e2e0fa647c11d Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 20 Jun 2022 19:01:25 +0800 Subject: [PATCH 017/115] add-xpath-namespaces-param (#9) --- docx/oxml/xmlchemy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docx/oxml/xmlchemy.py b/docx/oxml/xmlchemy.py index 15517190..72983dc2 100644 --- a/docx/oxml/xmlchemy.py +++ b/docx/oxml/xmlchemy.py @@ -779,12 +779,12 @@ def xml(self): """ return serialize_for_reading(self) - def xpath(self, xpath_str): + def xpath(self, xpath_str, namespaces=nsmap): """ Override of ``lxml`` _Element.xpath() method to provide standard Open XML namespace mapping (``nsmap``) in centralized location. """ - return super(BaseOxmlElement, self).xpath(xpath_str, namespaces=nsmap) + return super(BaseOxmlElement, self).xpath(xpath_str, namespaces=namespaces) @property def _nsptag(self): From ab9831fb91bdc8fe2c7120cd87e491b8bb04e0ca Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 24 Jun 2022 18:26:37 +0800 Subject: [PATCH 018/115] Custom xml (#10) * parts_with_reltype * customxml.py * custom xml part * CustomXmlPart.default * part element setter * 0.0.2 --- HISTORY.rst | 9 ++ docx/__init__.py | 7 +- docx/image/jpeg.py | 6 - docx/opc/coreprops.py | 7 +- docx/opc/customprops.py | 62 ++++---- docx/opc/package.py | 5 - docx/opc/packuri.py | 17 ++- docx/opc/part.py | 19 +-- docx/opc/parts/customprops.py | 22 +-- docx/opc/rel.py | 43 +++--- docx/oxml/__init__.py | 275 +++++++++++++++++----------------- docx/oxml/coreprops.py | 5 +- docx/parts/customxml.py | 61 ++++++++ docx/parts/document.py | 31 +++- setup.py | 2 +- 15 files changed, 313 insertions(+), 258 deletions(-) create mode 100644 docx/parts/customxml.py diff --git a/HISTORY.rst b/HISTORY.rst index 5fd72cb8..31500c2f 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -3,6 +3,15 @@ Release History --------------- +0.0.2 (2022-06-24) ++++++++++++++++++++ + +- Add custom xml support. PR-#10 +- Add Part __eq__. +- Add Part element setter. +- Add Relationships parts_with_reltype. + + 0.0.1 (2022-06-16) +++++++++++++++++++ diff --git a/docx/__init__.py b/docx/__init__.py index 17b106bd..0eb4fdd3 100644 --- a/docx/__init__.py +++ b/docx/__init__.py @@ -1,8 +1,6 @@ -# encoding: utf-8 - from docx.api import Document # noqa -__version__ = "0.0.1" +__version__ = "0.0.2" # register custom Part classes with opc package reader @@ -12,6 +10,7 @@ from docx.opc.part import PartFactory from docx.opc.parts.coreprops import CorePropertiesPart from docx.opc.parts.customprops import CustomPropertiesPart +from docx.parts.customxml import CustomXmlPart from docx.parts.document import DocumentPart from docx.parts.hdrftr import FooterPart, HeaderPart from docx.parts.image import ImagePart @@ -23,6 +22,8 @@ def part_class_selector(content_type, reltype): if reltype == RT.IMAGE: return ImagePart + elif reltype == RT.CUSTOM_XML: + return CustomXmlPart return None diff --git a/docx/image/jpeg.py b/docx/image/jpeg.py index 8a263b6c..4ce39b98 100644 --- a/docx/image/jpeg.py +++ b/docx/image/jpeg.py @@ -1,12 +1,7 @@ -# encoding: utf-8 - """ Objects related to parsing headers of JPEG image streams, both JFIF and Exif sub-formats. """ - -from __future__ import absolute_import, division, print_function - from ..compat import BytesIO from .constants import JPEG_MARKER_CODE, MIME_TYPE from .helpers import BIG_ENDIAN, StreamReader @@ -45,7 +40,6 @@ def from_stream(cls, stream): image in *stream*. """ markers = _JfifMarkers.from_stream(stream) - # print('\n%s' % markers) px_width = markers.sof.px_width px_height = markers.sof.px_height diff --git a/docx/opc/coreprops.py b/docx/opc/coreprops.py index 2d38dabd..02204dc0 100644 --- a/docx/opc/coreprops.py +++ b/docx/opc/coreprops.py @@ -1,20 +1,15 @@ -# encoding: utf-8 - """ The :mod:`pptx.packaging` module coheres around the concerns of reading and writing presentations to and from a .pptx file. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) - class CoreProperties(object): """ Corresponds to part named ``/docProps/core.xml``, containing the core document properties for this document package. """ + def __init__(self, element): self._element = element diff --git a/docx/opc/customprops.py b/docx/opc/customprops.py index 95e3fb7b..965bf255 100644 --- a/docx/opc/customprops.py +++ b/docx/opc/customprops.py @@ -1,71 +1,63 @@ -# encoding: utf-8 - -""" -The :mod:`pptx.packaging` module coheres around the concerns of reading and -writing presentations to and from a .pptx file. -""" - -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) - import numbers + from lxml import etree NS_VT = "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes" -class CustomProperties(object): + +class CustomProperties: """ Corresponds to part named ``/docProps/custom.xml``, containing the custom document properties for this document package. """ + def __init__(self, element): self._element = element - def __getitem__( self, item ): + def __getitem__(self, item): prop = self.lookup(item) - if prop is not None : - # print(etree.tostring(prop, pretty_print=True)) + if prop is not None: elm = prop[0] - if elm.tag == '{%s}i4' % NS_VT: + if elm.tag == "{%s}i4" % NS_VT: try: return int(elm.text) - except: + except Exception: return elm.text - elif elm.tag == '{%s}bool' % NS_VT: - return True if elm.text == '1' else False + elif elm.tag == "{%s}bool" % NS_VT: + return elm.text == "1" return elm.text - def __setitem__( self, key, value ): + def __setitem__(self, key, value): prop = self.lookup(key) - if prop is None : - elmType = 'lpwstr' + if prop is None: + elmType = "lpwstr" if isinstance(value, bool): - elmType = 'bool' + elmType = "bool" value = str(1 if value else 0) elif isinstance(value, numbers.Number): - elmType = 'i4' + elmType = "i4" value = str(int(value)) - prop = etree.SubElement( self._element, "property" ) - elm = etree.SubElement(prop, '{%s}%s' %(NS_VT, elmType), nsmap = {'vt':NS_VT} ) + prop = etree.SubElement(self._element, "property") + elm = etree.SubElement( + prop, "{%s}%s" % (NS_VT, elmType), nsmap={"vt": NS_VT} + ) elm.text = value prop.set("name", key) prop.set("fmtid", "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}") - prop.set("pid", "%s" % str(len(self._element) + 1)) + prop.set("pid", f"{str(len(self._element) + 1)}") else: elm = prop[0] - if elm.tag == '{%s}i4' % NS_VT: + if elm.tag == "{%s}i4" % NS_VT: elm.text = str(int(value)) - elif elm.tag == '{%s}bool' % NS_VT: + elif elm.tag == "{%s}bool" % NS_VT: elm.text = str(1 if value else 0) else: - elm.text = '%s' % str(value) + elm.text = f"{str(value)}" - def __len__( self ): + def __len__(self): return len(self._element) def lookup(self, item): - for child in self._element : - if child.get("name") == item : - return child - return None \ No newline at end of file + return next( + (child for child in self._element if child.get("name") == item), None + ) diff --git a/docx/opc/package.py b/docx/opc/package.py index 328cd1a2..49c9d810 100644 --- a/docx/opc/package.py +++ b/docx/opc/package.py @@ -1,9 +1,4 @@ -# encoding: utf-8 - """Objects that implement reading and writing OPC packages.""" - -from __future__ import absolute_import, division, print_function, unicode_literals - from typing import Callable from docx.opc.constants import RELATIONSHIP_TYPE as RT diff --git a/docx/opc/packuri.py b/docx/opc/packuri.py index 621ed92e..f20af84f 100644 --- a/docx/opc/packuri.py +++ b/docx/opc/packuri.py @@ -14,10 +14,11 @@ class PackURI(str): Provides access to pack URI components such as the baseURI and the filename slice. Behaves as |str| otherwise. """ - _filename_re = re.compile('([a-zA-Z]+)([1-9][0-9]*)?') + + _filename_re = re.compile("([a-zA-Z]+)([1-9][0-9]*)?") def __new__(cls, pack_uri_str): - if not pack_uri_str[0] == '/': + if not pack_uri_str[0] == "/": tmpl = "PackURI must begin with slash, got '%s'" raise ValueError(tmpl % pack_uri_str) return str.__new__(cls, pack_uri_str) @@ -49,7 +50,7 @@ def ext(self): """ # raw_ext is either empty string or starts with period, e.g. '.xml' raw_ext = posixpath.splitext(self)[1] - return raw_ext[1:] if raw_ext.startswith('.') else raw_ext + return raw_ext[1:] if raw_ext.startswith(".") else raw_ext @property def filename(self): @@ -95,7 +96,7 @@ def relative_ref(self, baseURI): """ # workaround for posixpath bug in 2.6, doesn't generate correct # relative path when *start* (second) parameter is root ('/') - if baseURI == '/': + if baseURI == "/": relpath = self[1:] else: relpath = posixpath.relpath(self, baseURI) @@ -108,10 +109,10 @@ def rels_uri(self): Only produces sensible output if the pack URI is a partname or the package pseudo-partname '/'. """ - rels_filename = '%s.rels' % self.filename - rels_uri_str = posixpath.join(self.baseURI, '_rels', rels_filename) + rels_filename = "%s.rels" % self.filename + rels_uri_str = posixpath.join(self.baseURI, "_rels", rels_filename) return PackURI(rels_uri_str) -PACKAGE_URI = PackURI('/') -CONTENT_TYPES_URI = PackURI('/[Content_Types].xml') +PACKAGE_URI = PackURI("/") +CONTENT_TYPES_URI = PackURI("/[Content_Types].xml") diff --git a/docx/opc/part.py b/docx/opc/part.py index 88e7c7bc..dcfca45e 100644 --- a/docx/opc/part.py +++ b/docx/opc/part.py @@ -1,12 +1,3 @@ -# encoding: utf-8 - -""" -Open Packaging Convention (OPC) objects related to package parts. -""" - -from __future__ import (absolute_import, division, print_function, - unicode_literals) - from typing import Callable from ..oxml import parse_xml @@ -17,7 +8,7 @@ from .shared import lazyproperty -class Part(object): +class Part: """ Base class for package parts. Provides common properties and methods, but intended to be subclassed in client code to implement specific part @@ -25,7 +16,6 @@ class Part(object): """ def __init__(self, partname, content_type, blob=None, package=None): - super(Part, self).__init__() self._partname = partname self._content_type = content_type self._blob = blob @@ -119,6 +109,9 @@ def partname(self, partname): raise TypeError(tmpl % type(partname).__name__) self._partname = partname + def __eq__(self, other): + return type(self) == type(other) and self.partname == other.partname + def part_related_by(self, reltype): """ Return part to which this part has a relationship of *reltype*. @@ -233,6 +226,10 @@ def element(self): """ return self._element + @element.setter + def element(self, e): + self._element = e + @classmethod def load(cls, partname, content_type, blob, package): element = parse_xml(blob) diff --git a/docx/opc/parts/customprops.py b/docx/opc/parts/customprops.py index e6ec3616..d1e1f5f8 100644 --- a/docx/opc/parts/customprops.py +++ b/docx/opc/parts/customprops.py @@ -1,20 +1,11 @@ -# encoding: utf-8 - """ Custom properties part, corresponds to ``/docProps/custom.xml`` part in package. """ - -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) - from lxml import etree -from datetime import datetime - +from ...oxml.customprops import CT_CustomProperties from ..constants import CONTENT_TYPE as CT from ..customprops import CustomProperties -from ...oxml.customprops import CT_CustomProperties from ..packuri import PackURI from ..part import XmlPart @@ -31,9 +22,7 @@ def ct_parse_xml(xml): parser is used, so custom element classes are produced for elements in *xml* that have them. """ - root_element = etree.fromstring(xml, ct_parser) - return root_element - + return etree.fromstring(xml, ct_parser) class CustomPropertiesPart(XmlPart): @@ -41,6 +30,7 @@ class CustomPropertiesPart(XmlPart): Corresponds to part named ``/docProps/custom.xml``, containing the custom document properties for this document package. """ + @classmethod def default(cls, package): """ @@ -66,9 +56,7 @@ def load(cls, partname, content_type, blob, package): @classmethod def _new(cls, package): - partname = PackURI('/docProps/custom.xml') + partname = PackURI("/docProps/custom.xml") content_type = CT.OPC_CUSTOM_PROPERTIES customProperties = CT_CustomProperties.new() - return CustomPropertiesPart( - partname, content_type, customProperties, package - ) + return CustomPropertiesPart(partname, content_type, customProperties, package) diff --git a/docx/opc/rel.py b/docx/opc/rel.py index 7dba2af8..3386d1d9 100644 --- a/docx/opc/rel.py +++ b/docx/opc/rel.py @@ -1,13 +1,6 @@ -# encoding: utf-8 - """ Relationship-related objects. """ - -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) - from .oxml import CT_Relationships @@ -15,6 +8,7 @@ class Relationships(dict): """ Collection object for |_Relationship| instances, having list semantics. """ + def __init__(self, baseURI): super(Relationships, self).__init__() self._baseURI = baseURI @@ -49,9 +43,7 @@ def get_or_add_ext_rel(self, reltype, target_ref): rel = self._get_matching(reltype, target_ref, is_external=True) if rel is None: rId = self._next_rId - rel = self.add_relationship( - reltype, target_ref, rId, is_external=True - ) + rel = self.add_relationship(reltype, target_ref, rId, is_external=True) return rel.rId def part_with_reltype(self, reltype): @@ -63,6 +55,15 @@ def part_with_reltype(self, reltype): rel = self._get_rel_of_type(reltype) return rel.target_part + def parts_with_reltype(self, reltype): + """ + Return target part of rel with matching *reltype*, raising |KeyError| + if not found and |ValueError| if more than one matching relationship + is found. + """ + rels = self._get_rel_of_type(reltype, multiple=True) + return [rel.target_part for rel in rels] + @property def related_parts(self): """ @@ -79,9 +80,7 @@ def xml(self): """ rels_elm = CT_Relationships.new() for rel in self.values(): - rels_elm.add_rel( - rel.rId, rel.reltype, rel.target_ref, rel.is_external - ) + rels_elm.add_rel(rel.rId, rel.reltype, rel.target_ref, rel.is_external) return rels_elm.xml def _get_matching(self, reltype, target, is_external=False): @@ -89,6 +88,7 @@ def _get_matching(self, reltype, target, is_external=False): Return relationship of matching *reltype*, *target*, and *is_external* from collection, or None if not found. """ + def matches(rel, reltype, target, is_external): if rel.reltype != reltype: return False @@ -104,16 +104,18 @@ def matches(rel, reltype, target, is_external): return rel return None - def _get_rel_of_type(self, reltype): + def _get_rel_of_type(self, reltype, multiple=False): """ Return single relationship of type *reltype* from the collection. Raises |KeyError| if no matching relationship is found. Raises |ValueError| if more than one matching relationship is found. """ matching = [rel for rel in self.values() if rel.reltype == reltype] - if len(matching) == 0: + if not matching: tmpl = "no relationship of type '%s' in collection" raise KeyError(tmpl % reltype) + if multiple: + return matching if len(matching) > 1: tmpl = "multiple relationships of type '%s' in collection" raise ValueError(tmpl % reltype) @@ -125,8 +127,8 @@ def _next_rId(self): Next available rId in collection, starting from 'rId1' and making use of any gaps in numbering, e.g. 'rId2' for rIds ['rId1', 'rId3']. """ - for n in range(1, len(self)+2): - rId_candidate = 'rId%d' % n # like 'rId19' + for n in range(1, len(self) + 2): + rId_candidate = "rId%d" % n # like 'rId19' if rId_candidate not in self: return rId_candidate @@ -135,6 +137,7 @@ class _Relationship(object): """ Value object for relationship to part. """ + def __init__(self, rId, reltype, target, baseURI, external=False): super(_Relationship, self).__init__() self._rId = rId @@ -158,8 +161,10 @@ def rId(self): @property def target_part(self): if self._is_external: - raise ValueError("target_part property on _Relationship is undef" - "ined when target mode is External") + raise ValueError( + "target_part property on _Relationship is undef" + "ined when target mode is External" + ) return self._target @property diff --git a/docx/oxml/__init__.py b/docx/oxml/__init__.py index d7680cbb..25994bf4 100644 --- a/docx/oxml/__init__.py +++ b/docx/oxml/__init__.py @@ -1,17 +1,11 @@ -# encoding: utf-8 - """ Initializes oxml sub-package, including registering custom element classes corresponding to Open XML elements. """ - -from __future__ import absolute_import - from lxml import etree from .ns import NamespacePrefixedTag, nsmap - # configure XML parser element_class_lookup = etree.ElementNamespaceClassLookup() oxml_parser = etree.XMLParser(remove_blank_text=True, resolve_entities=False) @@ -25,8 +19,7 @@ def parse_xml(xml): parser is used, so custom element classes are produced for elements in *xml* that have them. """ - root_element = etree.fromstring(xml, oxml_parser) - return root_element + return etree.fromstring(xml, oxml_parser) def register_element_cls(tag, cls): @@ -35,10 +28,11 @@ def register_element_cls(tag, cls): element with matching *tag*. *tag* is a string of the form ``nspfx:tagroot``, e.g. ``'w:document'``. """ - nspfx, tagroot = tag.split(':') + nspfx, tagroot = tag.split(":") namespace = element_class_lookup.get_namespace(nsmap[nspfx]) namespace[tagroot] = cls + def register_element_cls_ns(tag, ns, cls): """ Register *cls* to be constructed when the oxml parser encounters an @@ -48,6 +42,7 @@ def register_element_cls_ns(tag, ns, cls): namespace = element_class_lookup.get_namespace(ns) namespace[tag] = cls + def OxmlElement(nsptag_str, attrs=None, nsdecls=None): """ Return a 'loose' lxml element having the tag specified by *nsptag_str*. @@ -63,9 +58,7 @@ def OxmlElement(nsptag_str, attrs=None, nsdecls=None): nsptag = NamespacePrefixedTag(nsptag_str) if nsdecls is None: nsdecls = nsptag.nsmap - return oxml_parser.makeelement( - nsptag.clark_name, attrib=attrs, nsmap=nsdecls - ) + return oxml_parser.makeelement(nsptag.clark_name, attrib=attrs, nsmap=nsdecls) # =========================================================================== @@ -73,38 +66,42 @@ def OxmlElement(nsptag_str, attrs=None, nsdecls=None): # =========================================================================== from .shared import CT_DecimalNumber, CT_OnOff, CT_String # noqa + register_element_cls("w:evenAndOddHeaders", CT_OnOff) register_element_cls("w:titlePg", CT_OnOff) from .coreprops import CT_CoreProperties # noqa -register_element_cls('cp:coreProperties', CT_CoreProperties) + +register_element_cls("cp:coreProperties", CT_CoreProperties) from .customprops import CT_CustomProperties -register_element_cls_ns('Properties', 'http://schemas.openxmlformats.org/officeDocument/2006/custom-properties', CT_CustomProperties) + +register_element_cls_ns( + "Properties", + "http://schemas.openxmlformats.org/officeDocument/2006/custom-properties", + CT_CustomProperties, +) from .document import CT_Body, CT_Document -register_element_cls('w:body', CT_Body) -register_element_cls('w:document', CT_Document) + +register_element_cls("w:body", CT_Body) +register_element_cls("w:document", CT_Document) from .numbering import CT_Num, CT_Numbering, CT_NumLvl, CT_NumPr # noqa -register_element_cls('w:abstractNumId', CT_DecimalNumber) -register_element_cls('w:ilvl', CT_DecimalNumber) -register_element_cls('w:lvlOverride', CT_NumLvl) -register_element_cls('w:num', CT_Num) -register_element_cls('w:numId', CT_DecimalNumber) -register_element_cls('w:numPr', CT_NumPr) -register_element_cls('w:numbering', CT_Numbering) -register_element_cls('w:startOverride', CT_DecimalNumber) - -from .section import ( # noqa - CT_HdrFtr, - CT_HdrFtrRef, - CT_PageMar, - CT_PageSz, - CT_SectPr, - CT_SectType, -) + +register_element_cls("w:abstractNumId", CT_DecimalNumber) +register_element_cls("w:ilvl", CT_DecimalNumber) +register_element_cls("w:lvlOverride", CT_NumLvl) +register_element_cls("w:num", CT_Num) +register_element_cls("w:numId", CT_DecimalNumber) +register_element_cls("w:numPr", CT_NumPr) +register_element_cls("w:numbering", CT_Numbering) +register_element_cls("w:startOverride", CT_DecimalNumber) + +from .section import CT_PageSz # noqa +from .section import CT_HdrFtr, CT_HdrFtrRef, CT_PageMar, CT_SectPr, CT_SectType + register_element_cls("w:footerReference", CT_HdrFtrRef) register_element_cls("w:ftr", CT_HdrFtr) register_element_cls("w:hdr", CT_HdrFtr) @@ -115,12 +112,13 @@ def OxmlElement(nsptag_str, attrs=None, nsdecls=None): register_element_cls("w:type", CT_SectType) from .settings import CT_Settings # noqa + register_element_cls("w:settings", CT_Settings) -from .shape import ( # noqa +from .shape import CT_GraphicalObject # noqa +from .shape import ( CT_Blip, CT_BlipFillProperties, - CT_GraphicalObject, CT_GraphicalObjectData, CT_Inline, CT_NonVisualDrawingProps, @@ -131,40 +129,42 @@ def OxmlElement(nsptag_str, attrs=None, nsdecls=None): CT_ShapeProperties, CT_Transform2D, ) -register_element_cls('a:blip', CT_Blip) -register_element_cls('a:ext', CT_PositiveSize2D) -register_element_cls('a:graphic', CT_GraphicalObject) -register_element_cls('a:graphicData', CT_GraphicalObjectData) -register_element_cls('a:off', CT_Point2D) -register_element_cls('a:xfrm', CT_Transform2D) -register_element_cls('pic:blipFill', CT_BlipFillProperties) -register_element_cls('pic:cNvPr', CT_NonVisualDrawingProps) -register_element_cls('pic:nvPicPr', CT_PictureNonVisual) -register_element_cls('pic:pic', CT_Picture) -register_element_cls('pic:spPr', CT_ShapeProperties) -register_element_cls('wp:docPr', CT_NonVisualDrawingProps) -register_element_cls('wp:extent', CT_PositiveSize2D) -register_element_cls('wp:inline', CT_Inline) + +register_element_cls("a:blip", CT_Blip) +register_element_cls("a:ext", CT_PositiveSize2D) +register_element_cls("a:graphic", CT_GraphicalObject) +register_element_cls("a:graphicData", CT_GraphicalObjectData) +register_element_cls("a:off", CT_Point2D) +register_element_cls("a:xfrm", CT_Transform2D) +register_element_cls("pic:blipFill", CT_BlipFillProperties) +register_element_cls("pic:cNvPr", CT_NonVisualDrawingProps) +register_element_cls("pic:nvPicPr", CT_PictureNonVisual) +register_element_cls("pic:pic", CT_Picture) +register_element_cls("pic:spPr", CT_ShapeProperties) +register_element_cls("wp:docPr", CT_NonVisualDrawingProps) +register_element_cls("wp:extent", CT_PositiveSize2D) +register_element_cls("wp:inline", CT_Inline) from .styles import CT_LatentStyles, CT_LsdException, CT_Style, CT_Styles # noqa -register_element_cls('w:basedOn', CT_String) -register_element_cls('w:latentStyles', CT_LatentStyles) -register_element_cls('w:locked', CT_OnOff) -register_element_cls('w:lsdException', CT_LsdException) -register_element_cls('w:name', CT_String) -register_element_cls('w:next', CT_String) -register_element_cls('w:qFormat', CT_OnOff) -register_element_cls('w:semiHidden', CT_OnOff) -register_element_cls('w:style', CT_Style) -register_element_cls('w:styles', CT_Styles) -register_element_cls('w:uiPriority', CT_DecimalNumber) -register_element_cls('w:unhideWhenUsed', CT_OnOff) - -from .table import ( # noqa + +register_element_cls("w:basedOn", CT_String) +register_element_cls("w:latentStyles", CT_LatentStyles) +register_element_cls("w:locked", CT_OnOff) +register_element_cls("w:lsdException", CT_LsdException) +register_element_cls("w:name", CT_String) +register_element_cls("w:next", CT_String) +register_element_cls("w:qFormat", CT_OnOff) +register_element_cls("w:semiHidden", CT_OnOff) +register_element_cls("w:style", CT_Style) +register_element_cls("w:styles", CT_Styles) +register_element_cls("w:uiPriority", CT_DecimalNumber) +register_element_cls("w:unhideWhenUsed", CT_OnOff) + +from .table import CT_TblGrid # noqa +from .table import ( CT_Height, CT_Row, CT_Tbl, - CT_TblGrid, CT_TblGridCol, CT_TblLayoutType, CT_TblPr, @@ -172,88 +172,87 @@ def OxmlElement(nsptag_str, attrs=None, nsdecls=None): CT_Tc, CT_TcPr, CT_TrPr, - CT_VMerge, CT_VerticalJc, + CT_VMerge, ) -register_element_cls('w:bidiVisual', CT_OnOff) -register_element_cls('w:gridCol', CT_TblGridCol) -register_element_cls('w:gridSpan', CT_DecimalNumber) -register_element_cls('w:tbl', CT_Tbl) -register_element_cls('w:tblGrid', CT_TblGrid) -register_element_cls('w:tblLayout', CT_TblLayoutType) -register_element_cls('w:tblPr', CT_TblPr) -register_element_cls('w:tblStyle', CT_String) -register_element_cls('w:tc', CT_Tc) -register_element_cls('w:tcPr', CT_TcPr) -register_element_cls('w:tcW', CT_TblWidth) -register_element_cls('w:tr', CT_Row) -register_element_cls('w:trHeight', CT_Height) -register_element_cls('w:trPr', CT_TrPr) -register_element_cls('w:vAlign', CT_VerticalJc) -register_element_cls('w:vMerge', CT_VMerge) - -from .text.font import ( # noqa + +register_element_cls("w:bidiVisual", CT_OnOff) +register_element_cls("w:gridCol", CT_TblGridCol) +register_element_cls("w:gridSpan", CT_DecimalNumber) +register_element_cls("w:tbl", CT_Tbl) +register_element_cls("w:tblGrid", CT_TblGrid) +register_element_cls("w:tblLayout", CT_TblLayoutType) +register_element_cls("w:tblPr", CT_TblPr) +register_element_cls("w:tblStyle", CT_String) +register_element_cls("w:tc", CT_Tc) +register_element_cls("w:tcPr", CT_TcPr) +register_element_cls("w:tcW", CT_TblWidth) +register_element_cls("w:tr", CT_Row) +register_element_cls("w:trHeight", CT_Height) +register_element_cls("w:trPr", CT_TrPr) +register_element_cls("w:vAlign", CT_VerticalJc) +register_element_cls("w:vMerge", CT_VMerge) + +from .text.font import CT_Highlight # noqa +from .text.font import ( CT_Color, CT_Fonts, - CT_Highlight, CT_HpsMeasure, CT_RPr, CT_Underline, CT_VerticalAlignRun, ) -register_element_cls('w:b', CT_OnOff) -register_element_cls('w:bCs', CT_OnOff) -register_element_cls('w:caps', CT_OnOff) -register_element_cls('w:color', CT_Color) -register_element_cls('w:cs', CT_OnOff) -register_element_cls('w:dstrike', CT_OnOff) -register_element_cls('w:emboss', CT_OnOff) -register_element_cls('w:highlight', CT_Highlight) -register_element_cls('w:i', CT_OnOff) -register_element_cls('w:iCs', CT_OnOff) -register_element_cls('w:imprint', CT_OnOff) -register_element_cls('w:noProof', CT_OnOff) -register_element_cls('w:oMath', CT_OnOff) -register_element_cls('w:outline', CT_OnOff) -register_element_cls('w:rFonts', CT_Fonts) -register_element_cls('w:rPr', CT_RPr) -register_element_cls('w:rStyle', CT_String) -register_element_cls('w:rtl', CT_OnOff) -register_element_cls('w:shadow', CT_OnOff) -register_element_cls('w:smallCaps', CT_OnOff) -register_element_cls('w:snapToGrid', CT_OnOff) -register_element_cls('w:specVanish', CT_OnOff) -register_element_cls('w:strike', CT_OnOff) -register_element_cls('w:sz', CT_HpsMeasure) -register_element_cls('w:u', CT_Underline) -register_element_cls('w:vanish', CT_OnOff) -register_element_cls('w:vertAlign', CT_VerticalAlignRun) -register_element_cls('w:webHidden', CT_OnOff) + +register_element_cls("w:b", CT_OnOff) +register_element_cls("w:bCs", CT_OnOff) +register_element_cls("w:caps", CT_OnOff) +register_element_cls("w:color", CT_Color) +register_element_cls("w:cs", CT_OnOff) +register_element_cls("w:dstrike", CT_OnOff) +register_element_cls("w:emboss", CT_OnOff) +register_element_cls("w:highlight", CT_Highlight) +register_element_cls("w:i", CT_OnOff) +register_element_cls("w:iCs", CT_OnOff) +register_element_cls("w:imprint", CT_OnOff) +register_element_cls("w:noProof", CT_OnOff) +register_element_cls("w:oMath", CT_OnOff) +register_element_cls("w:outline", CT_OnOff) +register_element_cls("w:rFonts", CT_Fonts) +register_element_cls("w:rPr", CT_RPr) +register_element_cls("w:rStyle", CT_String) +register_element_cls("w:rtl", CT_OnOff) +register_element_cls("w:shadow", CT_OnOff) +register_element_cls("w:smallCaps", CT_OnOff) +register_element_cls("w:snapToGrid", CT_OnOff) +register_element_cls("w:specVanish", CT_OnOff) +register_element_cls("w:strike", CT_OnOff) +register_element_cls("w:sz", CT_HpsMeasure) +register_element_cls("w:u", CT_Underline) +register_element_cls("w:vanish", CT_OnOff) +register_element_cls("w:vertAlign", CT_VerticalAlignRun) +register_element_cls("w:webHidden", CT_OnOff) from .text.paragraph import CT_P # noqa -register_element_cls('w:p', CT_P) - -from .text.parfmt import ( # noqa - CT_Ind, - CT_Jc, - CT_PPr, - CT_Spacing, - CT_TabStop, - CT_TabStops, -) -register_element_cls('w:ind', CT_Ind) -register_element_cls('w:jc', CT_Jc) -register_element_cls('w:keepLines', CT_OnOff) -register_element_cls('w:keepNext', CT_OnOff) -register_element_cls('w:pageBreakBefore', CT_OnOff) -register_element_cls('w:pPr', CT_PPr) -register_element_cls('w:pStyle', CT_String) -register_element_cls('w:spacing', CT_Spacing) -register_element_cls('w:tab', CT_TabStop) -register_element_cls('w:tabs', CT_TabStops) -register_element_cls('w:widowControl', CT_OnOff) - -from .text.run import CT_Br, CT_R, CT_Text # noqa -register_element_cls('w:br', CT_Br) -register_element_cls('w:r', CT_R) -register_element_cls('w:t', CT_Text) + +register_element_cls("w:p", CT_P) + +from .text.parfmt import CT_Spacing # noqa +from .text.parfmt import CT_Ind, CT_Jc, CT_PPr, CT_TabStop, CT_TabStops + +register_element_cls("w:ind", CT_Ind) +register_element_cls("w:jc", CT_Jc) +register_element_cls("w:keepLines", CT_OnOff) +register_element_cls("w:keepNext", CT_OnOff) +register_element_cls("w:pageBreakBefore", CT_OnOff) +register_element_cls("w:pPr", CT_PPr) +register_element_cls("w:pStyle", CT_String) +register_element_cls("w:spacing", CT_Spacing) +register_element_cls("w:tab", CT_TabStop) +register_element_cls("w:tabs", CT_TabStops) +register_element_cls("w:widowControl", CT_OnOff) + +from .text.run import CT_R, CT_Br, CT_Text # noqa + +register_element_cls("w:br", CT_Br) +register_element_cls("w:r", CT_R) +register_element_cls("w:t", CT_Text) diff --git a/docx/oxml/coreprops.py b/docx/oxml/coreprops.py index ed3dd100..679be513 100644 --- a/docx/oxml/coreprops.py +++ b/docx/oxml/coreprops.py @@ -213,10 +213,9 @@ def _get_or_add(self, prop_name): """ Return element returned by 'get_or_add_' method for *prop_name*. """ - get_or_add_method_name = 'get_or_add_%s' % prop_name + get_or_add_method_name = f'get_or_add_{prop_name}' get_or_add_method = getattr(self, get_or_add_method_name) - element = get_or_add_method() - return element + return get_or_add_method() @classmethod def _offset_dt(cls, dt, offset_str): diff --git a/docx/parts/customxml.py b/docx/parts/customxml.py new file mode 100644 index 00000000..944e8ca9 --- /dev/null +++ b/docx/parts/customxml.py @@ -0,0 +1,61 @@ +""" +|CustomXmlPart| and closely related objects +""" +from lxml import etree +from lxml.etree import fromstring + +from docx.opc.package import OpcPackage +from docx.opc.packuri import PackURI +from docx.opc.part import XmlPart + + +class CustomXmlPart(XmlPart): + """ + Proxy for the /customXml/*.xml part containing custom items definitions + """ + + @classmethod + def default( + cls, + file_name: str, + content_type: str, + xml: str, + package: OpcPackage, + ) -> "CustomXmlPart": + """ + Create a default xml file in /customXml/*file_name*.xml + with default content *xml* and type *content_type* + """ + return cls( + PackURI(f"/customXml/{file_name}.xml"), + content_type, + fromstring(xml), + package, + ) + + @property + def tag(self) -> str: + """ + Return the root element tag name. + """ + return self.element.tag + + @property + def attrib(self) -> dict: + """ + Return the root element attributes. + """ + return self.element.attrib + + @property + def items(self) -> list[etree._Element]: + """ + Return all children belong to root element. + """ + return self.element.getchildren() + + def add_item(self, tag: str, text: str = "", **attrib): + """ + Add a child element to root. + """ + etree.SubElement(self.element, tag, **attrib).text = text diff --git a/docx/parts/document.py b/docx/parts/document.py index c75ec0dd..f5a65428 100644 --- a/docx/parts/document.py +++ b/docx/parts/document.py @@ -1,11 +1,10 @@ -# encoding: utf-8 - -"""|DocumentPart| and closely related objects""" - -from __future__ import absolute_import, division, print_function, unicode_literals - +""" + |DocumentPart| and closely related objects +""" from docx.document import Document +from docx.opc.constants import CONTENT_TYPE as CT from docx.opc.constants import RELATIONSHIP_TYPE as RT +from docx.parts.customxml import CustomXmlPart from docx.parts.hdrftr import FooterPart, HeaderPart from docx.parts.numbering import NumberingPart from docx.parts.settings import SettingsPart @@ -52,6 +51,26 @@ def custom_properties(self): """ return self.package.custom_properties + @property + def custom_xml_parts(self) -> list[CustomXmlPart]: + """ + A |CustomXmlPart| object providing access to the customXml/*.xml + for this document. + """ + try: + return self.rels.parts_with_reltype(RT.CUSTOM_XML) + except KeyError: + return [] + + def add_custom_xml_part( + self, xml: str, file_name: str = "item", content_type: str = CT.XML + ) -> CustomXmlPart: + """ + Add a file in /customXml/*file_name*.xml with default content *xml* + """ + part = CustomXmlPart.default(file_name, content_type, xml, self.package) + return self.rels.get_or_add(RT.CUSTOM_XML, part).target_part + @property def document(self): """ diff --git a/setup.py b/setup.py index 6eb95466..b26f40c2 100644 --- a/setup.py +++ b/setup.py @@ -35,7 +35,7 @@ def text_of(relpath): PACKAGES = find_packages(exclude=["tests", "tests.*"]) PACKAGE_DATA = {"docx": ["templates/*.xml", "templates/*.docx"]} -INSTALL_REQUIRES = ["lxml>=4.9.0"] +INSTALL_REQUIRES = ["lxml>=4.6.5"] TEST_SUITE = "tests" TESTS_REQUIRE = ["behave", "mock", "pyparsing", "pytest"] From e195507a9fc06fa3c791a781cf9c272eba79e30a Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 24 Jun 2022 18:34:22 +0800 Subject: [PATCH 019/115] black *.py (#11) blacken all .py --- docs/conf.py | 61 ++- docx/api.py | 2 +- docx/blkcntnr.py | 4 +- docx/dml/color.py | 4 +- docx/document.py | 9 +- docx/enum/__init__.py | 1 - docx/enum/base.py | 74 ++-- docx/enum/dml.py | 87 ++-- docx/enum/section.py | 40 +- docx/enum/shape.py | 1 + docx/enum/style.py | 560 ++++++----------------- docx/enum/table.py | 91 ++-- docx/enum/text.py | 343 ++++++--------- docx/image/__init__.py | 20 +- docx/image/bmp.py | 3 +- docx/image/constants.py | 227 +++++----- docx/image/gif.py | 5 +- docx/image/helpers.py | 21 +- docx/image/image.py | 14 +- docx/image/jpeg.py | 75 ++-- docx/image/png.py | 22 +- docx/image/tiff.py | 38 +- docx/opc/constants.py | 612 +++++++++++--------------- docx/opc/oxml.py | 84 ++-- docx/opc/parts/coreprops.py | 15 +- docx/opc/phys_pkg.py | 15 +- docx/opc/pkgreader.py | 23 +- docx/opc/shared.py | 7 +- docx/opc/spec.py | 36 +- docx/oxml/coreprops.py | 137 +++--- docx/oxml/customprops.py | 54 +-- docx/oxml/document.py | 12 +- docx/oxml/ns.py | 19 +- docx/oxml/numbering.py | 40 +- docx/oxml/section.py | 57 ++- docx/oxml/settings.py | 131 ++++-- docx/oxml/shape.py | 134 +++--- docx/oxml/shared.py | 11 +- docx/oxml/simpletypes.py | 122 ++--- docx/oxml/styles.py | 125 +++--- docx/oxml/table.py | 244 ++++++---- docx/oxml/text/font.py | 139 +++--- docx/oxml/text/paragraph.py | 9 +- docx/oxml/text/parfmt.py | 113 +++-- docx/oxml/text/run.py | 45 +- docx/package.py | 8 +- docx/parts/hdrftr.py | 8 +- docx/parts/image.py | 7 +- docx/parts/settings.py | 12 +- docx/parts/story.py | 2 +- docx/parts/styles.py | 12 +- docx/shape.py | 14 +- docx/shared.py | 19 +- docx/styles/__init__.py | 32 +- docx/styles/latent.py | 36 +- docx/styles/style.py | 12 +- docx/styles/styles.py | 11 +- docx/table.py | 13 +- docx/text/font.py | 84 ++-- docx/text/paragraph.py | 11 +- docx/text/parfmt.py | 10 +- docx/text/run.py | 18 +- docx/text/tabstops.py | 17 +- features/environment.py | 4 +- features/steps/api.py | 21 +- features/steps/block.py | 17 +- features/steps/cell.py | 17 +- features/steps/coreprops.py | 99 +++-- features/steps/customprops.py | 47 +- features/steps/document.py | 106 ++--- features/steps/font.py | 167 ++++--- features/steps/hdrftr.py | 11 +- features/steps/helpers.py | 21 +- features/steps/image.py | 42 +- features/steps/numbering.py | 11 +- features/steps/paragraph.py | 107 ++--- features/steps/parfmt.py | 161 ++++--- features/steps/section.py | 133 +++--- features/steps/settings.py | 19 +- features/steps/shape.py | 95 ++-- features/steps/shared.py | 6 +- features/steps/styles.py | 305 ++++++------- features/steps/table.py | 311 +++++++------ features/steps/tabstops.py | 57 +-- features/steps/text.py | 160 +++---- tests/dml/test_color.py | 142 +++--- tests/image/test_bmp.py | 7 +- tests/image/test_gif.py | 5 +- tests/image/test_helpers.py | 20 +- tests/image/test_image.py | 126 +++--- tests/image/test_jpeg.py | 245 ++++++----- tests/image/test_png.py | 96 ++-- tests/image/test_tiff.py | 151 ++++--- tests/opc/parts/test_coreprops.py | 11 +- tests/opc/parts/test_customprops.py | 7 +- tests/opc/test_coreprops.py | 168 +++---- tests/opc/test_customprops.py | 44 +- tests/opc/test_oxml.py | 61 +-- tests/opc/test_package.py | 219 ++++----- tests/opc/test_packuri.py | 49 ++- tests/opc/test_part.py | 16 +- tests/opc/test_pkgreader.py | 305 +++++++------ tests/opc/test_pkgwriter.py | 100 ++--- tests/opc/test_rel.py | 153 +++---- tests/opc/unitdata/rels.py | 122 ++--- tests/opc/unitdata/types.py | 18 +- tests/oxml/parts/test_document.py | 27 +- tests/oxml/parts/unitdata/document.py | 8 +- tests/oxml/test__init__.py | 62 ++- tests/oxml/test_ns.py | 20 +- tests/oxml/test_styles.py | 33 +- tests/oxml/test_table.py | 287 +++++++----- tests/oxml/test_xmlchemy.py | 426 +++++++++--------- tests/oxml/text/test_run.py | 22 +- tests/oxml/unitdata/dml.py | 102 ++--- tests/oxml/unitdata/numbering.py | 10 +- tests/oxml/unitdata/section.py | 29 +- tests/oxml/unitdata/shared.py | 10 +- tests/oxml/unitdata/styles.py | 10 +- tests/oxml/unitdata/table.py | 44 +- tests/oxml/unitdata/text.py | 96 ++-- tests/parts/test_document.py | 38 +- tests/parts/test_hdrftr.py | 2 - tests/parts/test_numbering.py | 31 +- tests/parts/test_settings.py | 11 +- tests/parts/test_story.py | 1 - tests/parts/test_styles.py | 7 +- tests/styles/test_latent.py | 297 +++++++------ tests/styles/test_style.py | 391 ++++++++-------- tests/styles/test_styles.py | 219 +++++---- tests/test_api.py | 17 +- tests/test_blkcntnr.py | 58 +-- tests/test_document.py | 94 ++-- tests/test_enum.py | 55 +-- tests/test_section.py | 230 +++++----- tests/test_settings.py | 3 +- tests/test_shape.py | 109 +++-- tests/test_shared.py | 63 ++- tests/test_table.py | 528 ++++++++++++---------- tests/text/test_font.py | 475 +++++++++++--------- tests/text/test_paragraph.py | 179 ++++---- tests/text/test_parfmt.py | 473 +++++++++++--------- tests/text/test_run.py | 285 ++++++------ tests/text/test_tabstops.py | 261 ++++++----- tests/unitdata.py | 42 +- tests/unitutil/cxml.py | 67 +-- tests/unitutil/mock.py | 6 +- 147 files changed, 6856 insertions(+), 6466 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 1a988453..ceea9809 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -18,7 +18,7 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath('..')) +sys.path.insert(0, os.path.abspath("..")) from docx import __version__ # noqa @@ -31,28 +31,28 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.intersphinx', - 'sphinx.ext.todo', - 'sphinx.ext.coverage', - 'sphinx.ext.viewcode' + "sphinx.ext.autodoc", + "sphinx.ext.intersphinx", + "sphinx.ext.todo", + "sphinx.ext.coverage", + "sphinx.ext.viewcode", ] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix of source filenames. -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. # source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = u'python-docx' -copyright = u'2013, Steve Canny' +project = "python-docx" +copyright = "2013, Steve Canny" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -193,7 +193,7 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['.build'] +exclude_patterns = [".build"] # The reST default role (used for this markup: `text`) to use for all # documents. @@ -211,7 +211,7 @@ # show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. # modindex_common_prefix = [] @@ -221,7 +221,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'armstrong' +html_theme = "armstrong" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -229,7 +229,7 @@ # html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -html_theme_path = ['_themes'] +html_theme_path = ["_themes"] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". @@ -250,7 +250,7 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = ["_static"] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. @@ -263,8 +263,7 @@ # Custom sidebar templates, maps document names to template names. # html_sidebars = {} html_sidebars = { - '**': ['localtoc.html', 'relations.html', 'sidebarlinks.html', - 'searchbox.html'] + "**": ["localtoc.html", "relations.html", "sidebarlinks.html", "searchbox.html"] } # Additional templates that should be rendered to pages, maps page names to @@ -298,7 +297,7 @@ # html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'python-docxdoc' +htmlhelp_basename = "python-docxdoc" # -- Options for LaTeX output ----------------------------------------------- @@ -306,10 +305,8 @@ latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # 'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). # 'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. # 'preamble': '', } @@ -321,8 +318,7 @@ # author, # documentclass [howto/manual]). latex_documents = [ - ('index', 'python-docx.tex', u'python-docx Documentation', - u'Steve Canny', 'manual'), + ("index", "python-docx.tex", "python-docx Documentation", "Steve Canny", "manual"), ] # The name of an image file (relative to this directory) to place at the top of @@ -350,10 +346,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'python-docx', u'python-docx Documentation', - [u'Steve Canny'], 1) -] +man_pages = [("index", "python-docx", "python-docx Documentation", ["Steve Canny"], 1)] # If true, show URL addresses after external links. # man_show_urls = False @@ -365,9 +358,15 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'python-docx', u'python-docx Documentation', - u'Steve Canny', 'python-docx', 'One line description of project.', - 'Miscellaneous'), + ( + "index", + "python-docx", + "python-docx Documentation", + "Steve Canny", + "python-docx", + "One line description of project.", + "Miscellaneous", + ), ] # Documents to append as an appendix to all manuals. @@ -381,4 +380,4 @@ # Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'http://docs.python.org/3/': None} +intersphinx_mapping = {"http://docs.python.org/3/": None} diff --git a/docx/api.py b/docx/api.py index 63e18c40..4cf6acd1 100644 --- a/docx/api.py +++ b/docx/api.py @@ -34,4 +34,4 @@ def _default_docx_path(): Return the path to the built-in default .docx package. """ _thisdir = os.path.split(__file__)[0] - return os.path.join(_thisdir, 'templates', 'default.docx') + return os.path.join(_thisdir, "templates", "default.docx") diff --git a/docx/blkcntnr.py b/docx/blkcntnr.py index a80903e5..b4d4d8b0 100644 --- a/docx/blkcntnr.py +++ b/docx/blkcntnr.py @@ -25,7 +25,7 @@ def __init__(self, element, parent): super(BlockItemContainer, self).__init__(parent) self._element = element - def add_paragraph(self, text='', style=None): + def add_paragraph(self, text="", style=None): """ Return a paragraph newly added to the end of the content in this container, having *text* in a single run if present, and having @@ -46,6 +46,7 @@ def add_table(self, rows, cols, width): distributed between the table columns. """ from .table import Table + tbl = CT_Tbl.new_tbl(rows, cols, width) self._element._insert_tbl(tbl) return Table(tbl, self) @@ -65,6 +66,7 @@ def tables(self): Read-only. """ from .table import Table + return [Table(tbl, self) for tbl in self._element.tbl_lst] def _add_paragraph(self): diff --git a/docx/dml/color.py b/docx/dml/color.py index 2f2f25cb..cfdf097a 100644 --- a/docx/dml/color.py +++ b/docx/dml/color.py @@ -4,9 +4,7 @@ DrawingML objects related to color, ColorFormat being the most prominent. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals from ..enum.dml import MSO_COLOR_TYPE from ..oxml.simpletypes import ST_HexColorAuto diff --git a/docx/document.py b/docx/document.py index bb42cb84..8bdd5da1 100644 --- a/docx/document.py +++ b/docx/document.py @@ -18,7 +18,7 @@ class Document(ElementProxy): a document. """ - __slots__ = ('_part', '__body') + __slots__ = ("_part", "__body") def __init__(self, element, part): super(Document, self).__init__(element) @@ -44,7 +44,7 @@ def add_page_break(self): paragraph.add_run().add_break(WD_BREAK.PAGE) return paragraph - def add_paragraph(self, text='', style=None): + def add_paragraph(self, text="", style=None): """ Return a paragraph newly added to the end of the document, populated with *text* and having paragraph style *style*. *text* can contain @@ -180,9 +180,7 @@ def _block_width(self): space between the margins of the last section of this document. """ section = self.sections[-1] - return Emu( - section.page_width - section.left_margin - section.right_margin - ) + return Emu(section.page_width - section.left_margin - section.right_margin) @property def _body(self): @@ -199,6 +197,7 @@ class _Body(BlockItemContainer): Proxy for ```` element in this document, having primarily a container role. """ + def __init__(self, body_elm, parent): super(_Body, self).__init__(body_elm, parent) self._body = body_elm diff --git a/docx/enum/__init__.py b/docx/enum/__init__.py index dd49faaf..e1bbd47f 100644 --- a/docx/enum/__init__.py +++ b/docx/enum/__init__.py @@ -8,7 +8,6 @@ class Enumeration(object): - @classmethod def from_xml(cls, xml_val): return cls._xml_to_idx[xml_val] diff --git a/docx/enum/base.py b/docx/enum/base.py index 36764b1a..0bcdbd6d 100644 --- a/docx/enum/base.py +++ b/docx/enum/base.py @@ -17,6 +17,7 @@ def alias(*aliases): Decorating a class with @alias('FOO', 'BAR', ..) allows the class to be referenced by each of the names provided as arguments. """ + def decorator(cls): # alias must be set in globals from caller's frame caller = sys._getframe(1) @@ -24,6 +25,7 @@ def decorator(cls): for alias in aliases: globals_dict[alias] = cls return cls + return decorator @@ -45,10 +47,12 @@ def page_str(self): The RestructuredText documentation page for the enumeration. This is the only API member for the class. """ - tmpl = '.. _%s:\n\n%s\n\n%s\n\n----\n\n%s' + tmpl = ".. _%s:\n\n%s\n\n%s\n\n----\n\n%s" components = ( - self._ms_name, self._page_title, self._intro_text, - self._member_defs + self._ms_name, + self._page_title, + self._intro_text, + self._member_defs, ) return tmpl % components @@ -56,12 +60,12 @@ def page_str(self): def _intro_text(self): """Docstring of the enumeration, formatted for documentation page.""" try: - cls_docstring = self._clsdict['__doc__'] + cls_docstring = self._clsdict["__doc__"] except KeyError: - cls_docstring = '' + cls_docstring = "" if cls_docstring is None: - return '' + return "" return textwrap.dedent(cls_docstring).strip() @@ -72,10 +76,12 @@ def _member_def(self, member): """ member_docstring = textwrap.dedent(member.docstring).strip() member_docstring = textwrap.fill( - member_docstring, width=78, initial_indent=' '*4, - subsequent_indent=' '*4 + member_docstring, + width=78, + initial_indent=" " * 4, + subsequent_indent=" " * 4, ) - return '%s\n%s\n' % (member.name, member_docstring) + return "%s\n%s\n" % (member.name, member_docstring) @property def _member_defs(self): @@ -83,19 +89,18 @@ def _member_defs(self): A single string containing the aggregated member definitions section of the documentation page """ - members = self._clsdict['__members__'] + members = self._clsdict["__members__"] member_defs = [ - self._member_def(member) for member in members - if member.name is not None + self._member_def(member) for member in members if member.name is not None ] - return '\n'.join(member_defs) + return "\n".join(member_defs) @property def _ms_name(self): """ The Microsoft API name for this enumeration """ - return self._clsdict['__ms_name__'] + return self._clsdict["__ms_name__"] @property def _page_title(self): @@ -103,8 +108,8 @@ def _page_title(self): The title for the documentation page, formatted as code (surrounded in double-backtics) and underlined with '=' characters """ - title_underscore = '=' * (len(self._clsname)+4) - return '``%s``\n%s' % (self._clsname, title_underscore) + title_underscore = "=" * (len(self._clsname) + 4) + return "``%s``\n%s" % (self._clsname, title_underscore) class MetaEnumeration(type): @@ -113,6 +118,7 @@ class MetaEnumeration(type): named member and compiles state needed by the enumeration class to respond to other attribute gets """ + def __new__(meta, clsname, bases, clsdict): meta._add_enum_members(clsdict) meta._collect_valid_settings(clsdict) @@ -126,7 +132,7 @@ def _add_enum_members(meta, clsdict): thing to properly add itself to the enumeration class. This delegation allows member sub-classes to add specialized behaviors. """ - enum_members = clsdict['__members__'] + enum_members = clsdict["__members__"] for member in enum_members: member.add_to_enum(clsdict) @@ -136,20 +142,18 @@ def _collect_valid_settings(meta, clsdict): Return a sequence containing the enumeration values that are valid assignment values. Return-only values are excluded. """ - enum_members = clsdict['__members__'] + enum_members = clsdict["__members__"] valid_settings = [] for member in enum_members: valid_settings.extend(member.valid_settings) - clsdict['_valid_settings'] = valid_settings + clsdict["_valid_settings"] = valid_settings @classmethod def _generate_docs_page(meta, clsname, clsdict): """ Return the RST documentation page for the enumeration. """ - clsdict['__docs_rst__'] = ( - _DocsPageFormatter(clsname, clsdict).page_str - ) + clsdict["__docs_rst__"] = _DocsPageFormatter(clsname, clsdict).page_str class EnumerationBase(object): @@ -158,8 +162,9 @@ class EnumerationBase(object): only basic behavior. It's __dict__ is used below in the Python 2+3 compatible metaclass definition. """ + __members__ = () - __ms_name__ = '' + __ms_name__ = "" @classmethod def validate(cls, value): @@ -172,9 +177,7 @@ def validate(cls, value): ) -Enumeration = MetaEnumeration( - 'Enumeration', (object,), dict(EnumerationBase.__dict__) -) +Enumeration = MetaEnumeration("Enumeration", (object,), dict(EnumerationBase.__dict__)) class XmlEnumeration(Enumeration): @@ -182,8 +185,9 @@ class XmlEnumeration(Enumeration): Provides ``to_xml()`` and ``from_xml()`` methods in addition to base enumeration features """ + __members__ = () - __ms_name__ = '' + __ms_name__ = "" @classmethod def from_xml(cls, xml_val): @@ -214,6 +218,7 @@ class EnumMember(object): Used in the enumeration class definition to define a member value and its mappings """ + def __init__(self, name, value, docstring): self._name = name if isinstance(value, int): @@ -278,6 +283,7 @@ class EnumValue(int): for its symbolic name and description, respectively. Subclasses int, so behaves as a regular int unless the strings are asked for. """ + def __new__(cls, member_name, int_value, docstring): return super(EnumValue, cls).__new__(cls, int_value) @@ -305,6 +311,7 @@ class ReturnValueOnlyEnumMember(EnumMember): Used to define a member of an enumeration that is only valid as a query result and is not valid as a setting, e.g. MSO_VERTICAL_ANCHOR.MIXED (-2) """ + @property def valid_settings(self): """ @@ -317,6 +324,7 @@ class XmlMappedEnumMember(EnumMember): """ Used to define a member whose value maps to an XML attribute value. """ + def __init__(self, name, value, xml_value, docstring): super(XmlMappedEnumMember, self).__init__(name, value, docstring) self._xml_value = xml_value @@ -349,15 +357,15 @@ def _get_or_add_member_to_xml(clsdict): """ Add the enum -> xml value mapping to the enumeration class state """ - if '_member_to_xml' not in clsdict: - clsdict['_member_to_xml'] = dict() - return clsdict['_member_to_xml'] + if "_member_to_xml" not in clsdict: + clsdict["_member_to_xml"] = dict() + return clsdict["_member_to_xml"] @staticmethod def _get_or_add_xml_to_member(clsdict): """ Add the xml -> enum value mapping to the enumeration class state """ - if '_xml_to_member' not in clsdict: - clsdict['_xml_to_member'] = dict() - return clsdict['_xml_to_member'] + if "_xml_to_member" not in clsdict: + clsdict["_xml_to_member"] = dict() + return clsdict["_xml_to_member"] diff --git a/docx/enum/dml.py b/docx/enum/dml.py index 1ad0eaa8..133d824d 100644 --- a/docx/enum/dml.py +++ b/docx/enum/dml.py @@ -6,9 +6,7 @@ from __future__ import absolute_import -from .base import ( - alias, Enumeration, EnumMember, XmlEnumeration, XmlMappedEnumMember -) +from .base import alias, Enumeration, EnumMember, XmlEnumeration, XmlMappedEnumMember class MSO_COLOR_TYPE(Enumeration): @@ -22,28 +20,22 @@ class MSO_COLOR_TYPE(Enumeration): assert font.color.type == MSO_COLOR_TYPE.SCHEME """ - __ms_name__ = 'MsoColorType' + __ms_name__ = "MsoColorType" __url__ = ( - 'http://msdn.microsoft.com/en-us/library/office/ff864912(v=office.15' - ').aspx' + "http://msdn.microsoft.com/en-us/library/office/ff864912(v=office.15" ").aspx" ) __members__ = ( + EnumMember("RGB", 1, "Color is specified by an |RGBColor| value."), + EnumMember("THEME", 2, "Color is one of the preset theme colors."), EnumMember( - 'RGB', 1, 'Color is specified by an |RGBColor| value.' - ), - EnumMember( - 'THEME', 2, 'Color is one of the preset theme colors.' - ), - EnumMember( - 'AUTO', 101, 'Color is determined automatically by the ' - 'application.' + "AUTO", 101, "Color is determined automatically by the " "application." ), ) -@alias('MSO_THEME_COLOR') +@alias("MSO_THEME_COLOR") class MSO_THEME_COLOR_INDEX(XmlEnumeration): """ Indicates the Office theme color, one of those shown in the color gallery @@ -58,67 +50,64 @@ class MSO_THEME_COLOR_INDEX(XmlEnumeration): font.color.theme_color = MSO_THEME_COLOR.ACCENT_1 """ - __ms_name__ = 'MsoThemeColorIndex' + __ms_name__ = "MsoThemeColorIndex" __url__ = ( - 'http://msdn.microsoft.com/en-us/library/office/ff860782(v=office.15' - ').aspx' + "http://msdn.microsoft.com/en-us/library/office/ff860782(v=office.15" ").aspx" ) __members__ = ( - EnumMember( - 'NOT_THEME_COLOR', 0, 'Indicates the color is not a theme color.' - ), - XmlMappedEnumMember( - 'ACCENT_1', 5, 'accent1', 'Specifies the Accent 1 theme color.' - ), - XmlMappedEnumMember( - 'ACCENT_2', 6, 'accent2', 'Specifies the Accent 2 theme color.' - ), - XmlMappedEnumMember( - 'ACCENT_3', 7, 'accent3', 'Specifies the Accent 3 theme color.' - ), - XmlMappedEnumMember( - 'ACCENT_4', 8, 'accent4', 'Specifies the Accent 4 theme color.' - ), + EnumMember("NOT_THEME_COLOR", 0, "Indicates the color is not a theme color."), XmlMappedEnumMember( - 'ACCENT_5', 9, 'accent5', 'Specifies the Accent 5 theme color.' + "ACCENT_1", 5, "accent1", "Specifies the Accent 1 theme color." ), XmlMappedEnumMember( - 'ACCENT_6', 10, 'accent6', 'Specifies the Accent 6 theme color.' + "ACCENT_2", 6, "accent2", "Specifies the Accent 2 theme color." ), XmlMappedEnumMember( - 'BACKGROUND_1', 14, 'background1', 'Specifies the Background 1 ' - 'theme color.' + "ACCENT_3", 7, "accent3", "Specifies the Accent 3 theme color." ), XmlMappedEnumMember( - 'BACKGROUND_2', 16, 'background2', 'Specifies the Background 2 ' - 'theme color.' + "ACCENT_4", 8, "accent4", "Specifies the Accent 4 theme color." ), XmlMappedEnumMember( - 'DARK_1', 1, 'dark1', 'Specifies the Dark 1 theme color.' + "ACCENT_5", 9, "accent5", "Specifies the Accent 5 theme color." ), XmlMappedEnumMember( - 'DARK_2', 3, 'dark2', 'Specifies the Dark 2 theme color.' + "ACCENT_6", 10, "accent6", "Specifies the Accent 6 theme color." ), XmlMappedEnumMember( - 'FOLLOWED_HYPERLINK', 12, 'followedHyperlink', 'Specifies the ' - 'theme color for a clicked hyperlink.' + "BACKGROUND_1", + 14, + "background1", + "Specifies the Background 1 " "theme color.", ), XmlMappedEnumMember( - 'HYPERLINK', 11, 'hyperlink', 'Specifies the theme color for a ' - 'hyperlink.' + "BACKGROUND_2", + 16, + "background2", + "Specifies the Background 2 " "theme color.", ), + XmlMappedEnumMember("DARK_1", 1, "dark1", "Specifies the Dark 1 theme color."), + XmlMappedEnumMember("DARK_2", 3, "dark2", "Specifies the Dark 2 theme color."), XmlMappedEnumMember( - 'LIGHT_1', 2, 'light1', 'Specifies the Light 1 theme color.' + "FOLLOWED_HYPERLINK", + 12, + "followedHyperlink", + "Specifies the " "theme color for a clicked hyperlink.", ), XmlMappedEnumMember( - 'LIGHT_2', 4, 'light2', 'Specifies the Light 2 theme color.' + "HYPERLINK", + 11, + "hyperlink", + "Specifies the theme color for a " "hyperlink.", ), XmlMappedEnumMember( - 'TEXT_1', 13, 'text1', 'Specifies the Text 1 theme color.' + "LIGHT_1", 2, "light1", "Specifies the Light 1 theme color." ), XmlMappedEnumMember( - 'TEXT_2', 15, 'text2', 'Specifies the Text 2 theme color.' + "LIGHT_2", 4, "light2", "Specifies the Light 2 theme color." ), + XmlMappedEnumMember("TEXT_1", 13, "text1", "Specifies the Text 1 theme color."), + XmlMappedEnumMember("TEXT_2", 15, "text2", "Specifies the Text 2 theme color."), ) diff --git a/docx/enum/section.py b/docx/enum/section.py index 381e8187..814e4cfb 100644 --- a/docx/enum/section.py +++ b/docx/enum/section.py @@ -9,7 +9,7 @@ from .base import alias, XmlEnumeration, XmlMappedEnumMember -@alias('WD_HEADER_FOOTER') +@alias("WD_HEADER_FOOTER") class WD_HEADER_FOOTER_INDEX(XmlEnumeration): """ alias: **WD_HEADER_FOOTER** @@ -36,7 +36,7 @@ class WD_HEADER_FOOTER_INDEX(XmlEnumeration): ) -@alias('WD_ORIENT') +@alias("WD_ORIENT") class WD_ORIENTATION(XmlEnumeration): """ alias: **WD_ORIENT** @@ -51,21 +51,17 @@ class WD_ORIENTATION(XmlEnumeration): section.orientation = WD_ORIENT.LANDSCAPE """ - __ms_name__ = 'WdOrientation' + __ms_name__ = "WdOrientation" - __url__ = 'http://msdn.microsoft.com/en-us/library/office/ff837902.aspx' + __url__ = "http://msdn.microsoft.com/en-us/library/office/ff837902.aspx" __members__ = ( - XmlMappedEnumMember( - 'PORTRAIT', 0, 'portrait', 'Portrait orientation.' - ), - XmlMappedEnumMember( - 'LANDSCAPE', 1, 'landscape', 'Landscape orientation.' - ), + XmlMappedEnumMember("PORTRAIT", 0, "portrait", "Portrait orientation."), + XmlMappedEnumMember("LANDSCAPE", 1, "landscape", "Landscape orientation."), ) -@alias('WD_SECTION') +@alias("WD_SECTION") class WD_SECTION_START(XmlEnumeration): """ alias: **WD_SECTION** @@ -80,24 +76,16 @@ class WD_SECTION_START(XmlEnumeration): section.start_type = WD_SECTION.NEW_PAGE """ - __ms_name__ = 'WdSectionStart' + __ms_name__ = "WdSectionStart" - __url__ = 'http://msdn.microsoft.com/en-us/library/office/ff840975.aspx' + __url__ = "http://msdn.microsoft.com/en-us/library/office/ff840975.aspx" __members__ = ( + XmlMappedEnumMember("CONTINUOUS", 0, "continuous", "Continuous section break."), + XmlMappedEnumMember("NEW_COLUMN", 1, "nextColumn", "New column section break."), + XmlMappedEnumMember("NEW_PAGE", 2, "nextPage", "New page section break."), + XmlMappedEnumMember("EVEN_PAGE", 3, "evenPage", "Even pages section break."), XmlMappedEnumMember( - 'CONTINUOUS', 0, 'continuous', 'Continuous section break.' - ), - XmlMappedEnumMember( - 'NEW_COLUMN', 1, 'nextColumn', 'New column section break.' - ), - XmlMappedEnumMember( - 'NEW_PAGE', 2, 'nextPage', 'New page section break.' - ), - XmlMappedEnumMember( - 'EVEN_PAGE', 3, 'evenPage', 'Even pages section break.' - ), - XmlMappedEnumMember( - 'ODD_PAGE', 4, 'oddPage', 'Section begins on next odd page.' + "ODD_PAGE", 4, "oddPage", "Section begins on next odd page." ), ) diff --git a/docx/enum/shape.py b/docx/enum/shape.py index 937f30a9..b785ab9c 100644 --- a/docx/enum/shape.py +++ b/docx/enum/shape.py @@ -12,6 +12,7 @@ class WD_INLINE_SHAPE_TYPE(object): Corresponds to WdInlineShapeType enumeration http://msdn.microsoft.com/en-us/library/office/ff192587.aspx """ + CHART = 12 LINKED_PICTURE = 4 PICTURE = 3 diff --git a/docx/enum/style.py b/docx/enum/style.py index 515c594c..1915429c 100644 --- a/docx/enum/style.py +++ b/docx/enum/style.py @@ -9,7 +9,7 @@ from .base import alias, EnumMember, XmlEnumeration, XmlMappedEnumMember -@alias('WD_STYLE') +@alias("WD_STYLE") class WD_BUILTIN_STYLE(XmlEnumeration): """ alias: **WD_STYLE** @@ -26,409 +26,147 @@ class WD_BUILTIN_STYLE(XmlEnumeration): style = styles[WD_STYLE.BODY_TEXT] """ - __ms_name__ = 'WdBuiltinStyle' + __ms_name__ = "WdBuiltinStyle" - __url__ = 'http://msdn.microsoft.com/en-us/library/office/ff835210.aspx' + __url__ = "http://msdn.microsoft.com/en-us/library/office/ff835210.aspx" __members__ = ( - EnumMember( - 'BLOCK_QUOTATION', -85, 'Block Text.' - ), - EnumMember( - 'BODY_TEXT', -67, 'Body Text.' - ), - EnumMember( - 'BODY_TEXT_2', -81, 'Body Text 2.' - ), - EnumMember( - 'BODY_TEXT_3', -82, 'Body Text 3.' - ), - EnumMember( - 'BODY_TEXT_FIRST_INDENT', -78, 'Body Text First Indent.' - ), - EnumMember( - 'BODY_TEXT_FIRST_INDENT_2', -79, 'Body Text First Indent 2.' - ), - EnumMember( - 'BODY_TEXT_INDENT', -68, 'Body Text Indent.' - ), - EnumMember( - 'BODY_TEXT_INDENT_2', -83, 'Body Text Indent 2.' - ), - EnumMember( - 'BODY_TEXT_INDENT_3', -84, 'Body Text Indent 3.' - ), - EnumMember( - 'BOOK_TITLE', -265, 'Book Title.' - ), - EnumMember( - 'CAPTION', -35, 'Caption.' - ), - EnumMember( - 'CLOSING', -64, 'Closing.' - ), - EnumMember( - 'COMMENT_REFERENCE', -40, 'Comment Reference.' - ), - EnumMember( - 'COMMENT_TEXT', -31, 'Comment Text.' - ), - EnumMember( - 'DATE', -77, 'Date.' - ), - EnumMember( - 'DEFAULT_PARAGRAPH_FONT', -66, 'Default Paragraph Font.' - ), - EnumMember( - 'EMPHASIS', -89, 'Emphasis.' - ), - EnumMember( - 'ENDNOTE_REFERENCE', -43, 'Endnote Reference.' - ), - EnumMember( - 'ENDNOTE_TEXT', -44, 'Endnote Text.' - ), - EnumMember( - 'ENVELOPE_ADDRESS', -37, 'Envelope Address.' - ), - EnumMember( - 'ENVELOPE_RETURN', -38, 'Envelope Return.' - ), - EnumMember( - 'FOOTER', -33, 'Footer.' - ), - EnumMember( - 'FOOTNOTE_REFERENCE', -39, 'Footnote Reference.' - ), - EnumMember( - 'FOOTNOTE_TEXT', -30, 'Footnote Text.' - ), - EnumMember( - 'HEADER', -32, 'Header.' - ), - EnumMember( - 'HEADING_1', -2, 'Heading 1.' - ), - EnumMember( - 'HEADING_2', -3, 'Heading 2.' - ), - EnumMember( - 'HEADING_3', -4, 'Heading 3.' - ), - EnumMember( - 'HEADING_4', -5, 'Heading 4.' - ), - EnumMember( - 'HEADING_5', -6, 'Heading 5.' - ), - EnumMember( - 'HEADING_6', -7, 'Heading 6.' - ), - EnumMember( - 'HEADING_7', -8, 'Heading 7.' - ), - EnumMember( - 'HEADING_8', -9, 'Heading 8.' - ), - EnumMember( - 'HEADING_9', -10, 'Heading 9.' - ), - EnumMember( - 'HTML_ACRONYM', -96, 'HTML Acronym.' - ), - EnumMember( - 'HTML_ADDRESS', -97, 'HTML Address.' - ), - EnumMember( - 'HTML_CITE', -98, 'HTML Cite.' - ), - EnumMember( - 'HTML_CODE', -99, 'HTML Code.' - ), - EnumMember( - 'HTML_DFN', -100, 'HTML Definition.' - ), - EnumMember( - 'HTML_KBD', -101, 'HTML Keyboard.' - ), - EnumMember( - 'HTML_NORMAL', -95, 'Normal (Web).' - ), - EnumMember( - 'HTML_PRE', -102, 'HTML Preformatted.' - ), - EnumMember( - 'HTML_SAMP', -103, 'HTML Sample.' - ), - EnumMember( - 'HTML_TT', -104, 'HTML Typewriter.' - ), - EnumMember( - 'HTML_VAR', -105, 'HTML Variable.' - ), - EnumMember( - 'HYPERLINK', -86, 'Hyperlink.' - ), - EnumMember( - 'HYPERLINK_FOLLOWED', -87, 'Followed Hyperlink.' - ), - EnumMember( - 'INDEX_1', -11, 'Index 1.' - ), - EnumMember( - 'INDEX_2', -12, 'Index 2.' - ), - EnumMember( - 'INDEX_3', -13, 'Index 3.' - ), - EnumMember( - 'INDEX_4', -14, 'Index 4.' - ), - EnumMember( - 'INDEX_5', -15, 'Index 5.' - ), - EnumMember( - 'INDEX_6', -16, 'Index 6.' - ), - EnumMember( - 'INDEX_7', -17, 'Index 7.' - ), - EnumMember( - 'INDEX_8', -18, 'Index 8.' - ), - EnumMember( - 'INDEX_9', -19, 'Index 9.' - ), - EnumMember( - 'INDEX_HEADING', -34, 'Index Heading' - ), - EnumMember( - 'INTENSE_EMPHASIS', -262, 'Intense Emphasis.' - ), - EnumMember( - 'INTENSE_QUOTE', -182, 'Intense Quote.' - ), - EnumMember( - 'INTENSE_REFERENCE', -264, 'Intense Reference.' - ), - EnumMember( - 'LINE_NUMBER', -41, 'Line Number.' - ), - EnumMember( - 'LIST', -48, 'List.' - ), - EnumMember( - 'LIST_2', -51, 'List 2.' - ), - EnumMember( - 'LIST_3', -52, 'List 3.' - ), - EnumMember( - 'LIST_4', -53, 'List 4.' - ), - EnumMember( - 'LIST_5', -54, 'List 5.' - ), - EnumMember( - 'LIST_BULLET', -49, 'List Bullet.' - ), - EnumMember( - 'LIST_BULLET_2', -55, 'List Bullet 2.' - ), - EnumMember( - 'LIST_BULLET_3', -56, 'List Bullet 3.' - ), - EnumMember( - 'LIST_BULLET_4', -57, 'List Bullet 4.' - ), - EnumMember( - 'LIST_BULLET_5', -58, 'List Bullet 5.' - ), - EnumMember( - 'LIST_CONTINUE', -69, 'List Continue.' - ), - EnumMember( - 'LIST_CONTINUE_2', -70, 'List Continue 2.' - ), - EnumMember( - 'LIST_CONTINUE_3', -71, 'List Continue 3.' - ), - EnumMember( - 'LIST_CONTINUE_4', -72, 'List Continue 4.' - ), - EnumMember( - 'LIST_CONTINUE_5', -73, 'List Continue 5.' - ), - EnumMember( - 'LIST_NUMBER', -50, 'List Number.' - ), - EnumMember( - 'LIST_NUMBER_2', -59, 'List Number 2.' - ), - EnumMember( - 'LIST_NUMBER_3', -60, 'List Number 3.' - ), - EnumMember( - 'LIST_NUMBER_4', -61, 'List Number 4.' - ), - EnumMember( - 'LIST_NUMBER_5', -62, 'List Number 5.' - ), - EnumMember( - 'LIST_PARAGRAPH', -180, 'List Paragraph.' - ), - EnumMember( - 'MACRO_TEXT', -46, 'Macro Text.' - ), - EnumMember( - 'MESSAGE_HEADER', -74, 'Message Header.' - ), - EnumMember( - 'NAV_PANE', -90, 'Document Map.' - ), - EnumMember( - 'NORMAL', -1, 'Normal.' - ), - EnumMember( - 'NORMAL_INDENT', -29, 'Normal Indent.' - ), - EnumMember( - 'NORMAL_OBJECT', -158, 'Normal (applied to an object).' - ), - EnumMember( - 'NORMAL_TABLE', -106, 'Normal (applied within a table).' - ), - EnumMember( - 'NOTE_HEADING', -80, 'Note Heading.' - ), - EnumMember( - 'PAGE_NUMBER', -42, 'Page Number.' - ), - EnumMember( - 'PLAIN_TEXT', -91, 'Plain Text.' - ), - EnumMember( - 'QUOTE', -181, 'Quote.' - ), - EnumMember( - 'SALUTATION', -76, 'Salutation.' - ), - EnumMember( - 'SIGNATURE', -65, 'Signature.' - ), - EnumMember( - 'STRONG', -88, 'Strong.' - ), - EnumMember( - 'SUBTITLE', -75, 'Subtitle.' - ), - EnumMember( - 'SUBTLE_EMPHASIS', -261, 'Subtle Emphasis.' - ), - EnumMember( - 'SUBTLE_REFERENCE', -263, 'Subtle Reference.' - ), - EnumMember( - 'TABLE_COLORFUL_GRID', -172, 'Colorful Grid.' - ), - EnumMember( - 'TABLE_COLORFUL_LIST', -171, 'Colorful List.' - ), - EnumMember( - 'TABLE_COLORFUL_SHADING', -170, 'Colorful Shading.' - ), - EnumMember( - 'TABLE_DARK_LIST', -169, 'Dark List.' - ), - EnumMember( - 'TABLE_LIGHT_GRID', -161, 'Light Grid.' - ), - EnumMember( - 'TABLE_LIGHT_GRID_ACCENT_1', -175, 'Light Grid Accent 1.' - ), - EnumMember( - 'TABLE_LIGHT_LIST', -160, 'Light List.' - ), - EnumMember( - 'TABLE_LIGHT_LIST_ACCENT_1', -174, 'Light List Accent 1.' - ), - EnumMember( - 'TABLE_LIGHT_SHADING', -159, 'Light Shading.' - ), - EnumMember( - 'TABLE_LIGHT_SHADING_ACCENT_1', -173, 'Light Shading Accent 1.' - ), - EnumMember( - 'TABLE_MEDIUM_GRID_1', -166, 'Medium Grid 1.' - ), - EnumMember( - 'TABLE_MEDIUM_GRID_2', -167, 'Medium Grid 2.' - ), - EnumMember( - 'TABLE_MEDIUM_GRID_3', -168, 'Medium Grid 3.' - ), - EnumMember( - 'TABLE_MEDIUM_LIST_1', -164, 'Medium List 1.' - ), - EnumMember( - 'TABLE_MEDIUM_LIST_1_ACCENT_1', -178, 'Medium List 1 Accent 1.' - ), - EnumMember( - 'TABLE_MEDIUM_LIST_2', -165, 'Medium List 2.' - ), - EnumMember( - 'TABLE_MEDIUM_SHADING_1', -162, 'Medium Shading 1.' - ), - EnumMember( - 'TABLE_MEDIUM_SHADING_1_ACCENT_1', -176, - 'Medium Shading 1 Accent 1.' - ), - EnumMember( - 'TABLE_MEDIUM_SHADING_2', -163, 'Medium Shading 2.' - ), - EnumMember( - 'TABLE_MEDIUM_SHADING_2_ACCENT_1', -177, - 'Medium Shading 2 Accent 1.' - ), - EnumMember( - 'TABLE_OF_AUTHORITIES', -45, 'Table of Authorities.' - ), - EnumMember( - 'TABLE_OF_FIGURES', -36, 'Table of Figures.' - ), - EnumMember( - 'TITLE', -63, 'Title.' - ), - EnumMember( - 'TOAHEADING', -47, 'TOA Heading.' - ), - EnumMember( - 'TOC_1', -20, 'TOC 1.' - ), - EnumMember( - 'TOC_2', -21, 'TOC 2.' - ), - EnumMember( - 'TOC_3', -22, 'TOC 3.' - ), - EnumMember( - 'TOC_4', -23, 'TOC 4.' - ), - EnumMember( - 'TOC_5', -24, 'TOC 5.' - ), - EnumMember( - 'TOC_6', -25, 'TOC 6.' - ), - EnumMember( - 'TOC_7', -26, 'TOC 7.' - ), - EnumMember( - 'TOC_8', -27, 'TOC 8.' - ), - EnumMember( - 'TOC_9', -28, 'TOC 9.' - ), + EnumMember("BLOCK_QUOTATION", -85, "Block Text."), + EnumMember("BODY_TEXT", -67, "Body Text."), + EnumMember("BODY_TEXT_2", -81, "Body Text 2."), + EnumMember("BODY_TEXT_3", -82, "Body Text 3."), + EnumMember("BODY_TEXT_FIRST_INDENT", -78, "Body Text First Indent."), + EnumMember("BODY_TEXT_FIRST_INDENT_2", -79, "Body Text First Indent 2."), + EnumMember("BODY_TEXT_INDENT", -68, "Body Text Indent."), + EnumMember("BODY_TEXT_INDENT_2", -83, "Body Text Indent 2."), + EnumMember("BODY_TEXT_INDENT_3", -84, "Body Text Indent 3."), + EnumMember("BOOK_TITLE", -265, "Book Title."), + EnumMember("CAPTION", -35, "Caption."), + EnumMember("CLOSING", -64, "Closing."), + EnumMember("COMMENT_REFERENCE", -40, "Comment Reference."), + EnumMember("COMMENT_TEXT", -31, "Comment Text."), + EnumMember("DATE", -77, "Date."), + EnumMember("DEFAULT_PARAGRAPH_FONT", -66, "Default Paragraph Font."), + EnumMember("EMPHASIS", -89, "Emphasis."), + EnumMember("ENDNOTE_REFERENCE", -43, "Endnote Reference."), + EnumMember("ENDNOTE_TEXT", -44, "Endnote Text."), + EnumMember("ENVELOPE_ADDRESS", -37, "Envelope Address."), + EnumMember("ENVELOPE_RETURN", -38, "Envelope Return."), + EnumMember("FOOTER", -33, "Footer."), + EnumMember("FOOTNOTE_REFERENCE", -39, "Footnote Reference."), + EnumMember("FOOTNOTE_TEXT", -30, "Footnote Text."), + EnumMember("HEADER", -32, "Header."), + EnumMember("HEADING_1", -2, "Heading 1."), + EnumMember("HEADING_2", -3, "Heading 2."), + EnumMember("HEADING_3", -4, "Heading 3."), + EnumMember("HEADING_4", -5, "Heading 4."), + EnumMember("HEADING_5", -6, "Heading 5."), + EnumMember("HEADING_6", -7, "Heading 6."), + EnumMember("HEADING_7", -8, "Heading 7."), + EnumMember("HEADING_8", -9, "Heading 8."), + EnumMember("HEADING_9", -10, "Heading 9."), + EnumMember("HTML_ACRONYM", -96, "HTML Acronym."), + EnumMember("HTML_ADDRESS", -97, "HTML Address."), + EnumMember("HTML_CITE", -98, "HTML Cite."), + EnumMember("HTML_CODE", -99, "HTML Code."), + EnumMember("HTML_DFN", -100, "HTML Definition."), + EnumMember("HTML_KBD", -101, "HTML Keyboard."), + EnumMember("HTML_NORMAL", -95, "Normal (Web)."), + EnumMember("HTML_PRE", -102, "HTML Preformatted."), + EnumMember("HTML_SAMP", -103, "HTML Sample."), + EnumMember("HTML_TT", -104, "HTML Typewriter."), + EnumMember("HTML_VAR", -105, "HTML Variable."), + EnumMember("HYPERLINK", -86, "Hyperlink."), + EnumMember("HYPERLINK_FOLLOWED", -87, "Followed Hyperlink."), + EnumMember("INDEX_1", -11, "Index 1."), + EnumMember("INDEX_2", -12, "Index 2."), + EnumMember("INDEX_3", -13, "Index 3."), + EnumMember("INDEX_4", -14, "Index 4."), + EnumMember("INDEX_5", -15, "Index 5."), + EnumMember("INDEX_6", -16, "Index 6."), + EnumMember("INDEX_7", -17, "Index 7."), + EnumMember("INDEX_8", -18, "Index 8."), + EnumMember("INDEX_9", -19, "Index 9."), + EnumMember("INDEX_HEADING", -34, "Index Heading"), + EnumMember("INTENSE_EMPHASIS", -262, "Intense Emphasis."), + EnumMember("INTENSE_QUOTE", -182, "Intense Quote."), + EnumMember("INTENSE_REFERENCE", -264, "Intense Reference."), + EnumMember("LINE_NUMBER", -41, "Line Number."), + EnumMember("LIST", -48, "List."), + EnumMember("LIST_2", -51, "List 2."), + EnumMember("LIST_3", -52, "List 3."), + EnumMember("LIST_4", -53, "List 4."), + EnumMember("LIST_5", -54, "List 5."), + EnumMember("LIST_BULLET", -49, "List Bullet."), + EnumMember("LIST_BULLET_2", -55, "List Bullet 2."), + EnumMember("LIST_BULLET_3", -56, "List Bullet 3."), + EnumMember("LIST_BULLET_4", -57, "List Bullet 4."), + EnumMember("LIST_BULLET_5", -58, "List Bullet 5."), + EnumMember("LIST_CONTINUE", -69, "List Continue."), + EnumMember("LIST_CONTINUE_2", -70, "List Continue 2."), + EnumMember("LIST_CONTINUE_3", -71, "List Continue 3."), + EnumMember("LIST_CONTINUE_4", -72, "List Continue 4."), + EnumMember("LIST_CONTINUE_5", -73, "List Continue 5."), + EnumMember("LIST_NUMBER", -50, "List Number."), + EnumMember("LIST_NUMBER_2", -59, "List Number 2."), + EnumMember("LIST_NUMBER_3", -60, "List Number 3."), + EnumMember("LIST_NUMBER_4", -61, "List Number 4."), + EnumMember("LIST_NUMBER_5", -62, "List Number 5."), + EnumMember("LIST_PARAGRAPH", -180, "List Paragraph."), + EnumMember("MACRO_TEXT", -46, "Macro Text."), + EnumMember("MESSAGE_HEADER", -74, "Message Header."), + EnumMember("NAV_PANE", -90, "Document Map."), + EnumMember("NORMAL", -1, "Normal."), + EnumMember("NORMAL_INDENT", -29, "Normal Indent."), + EnumMember("NORMAL_OBJECT", -158, "Normal (applied to an object)."), + EnumMember("NORMAL_TABLE", -106, "Normal (applied within a table)."), + EnumMember("NOTE_HEADING", -80, "Note Heading."), + EnumMember("PAGE_NUMBER", -42, "Page Number."), + EnumMember("PLAIN_TEXT", -91, "Plain Text."), + EnumMember("QUOTE", -181, "Quote."), + EnumMember("SALUTATION", -76, "Salutation."), + EnumMember("SIGNATURE", -65, "Signature."), + EnumMember("STRONG", -88, "Strong."), + EnumMember("SUBTITLE", -75, "Subtitle."), + EnumMember("SUBTLE_EMPHASIS", -261, "Subtle Emphasis."), + EnumMember("SUBTLE_REFERENCE", -263, "Subtle Reference."), + EnumMember("TABLE_COLORFUL_GRID", -172, "Colorful Grid."), + EnumMember("TABLE_COLORFUL_LIST", -171, "Colorful List."), + EnumMember("TABLE_COLORFUL_SHADING", -170, "Colorful Shading."), + EnumMember("TABLE_DARK_LIST", -169, "Dark List."), + EnumMember("TABLE_LIGHT_GRID", -161, "Light Grid."), + EnumMember("TABLE_LIGHT_GRID_ACCENT_1", -175, "Light Grid Accent 1."), + EnumMember("TABLE_LIGHT_LIST", -160, "Light List."), + EnumMember("TABLE_LIGHT_LIST_ACCENT_1", -174, "Light List Accent 1."), + EnumMember("TABLE_LIGHT_SHADING", -159, "Light Shading."), + EnumMember("TABLE_LIGHT_SHADING_ACCENT_1", -173, "Light Shading Accent 1."), + EnumMember("TABLE_MEDIUM_GRID_1", -166, "Medium Grid 1."), + EnumMember("TABLE_MEDIUM_GRID_2", -167, "Medium Grid 2."), + EnumMember("TABLE_MEDIUM_GRID_3", -168, "Medium Grid 3."), + EnumMember("TABLE_MEDIUM_LIST_1", -164, "Medium List 1."), + EnumMember("TABLE_MEDIUM_LIST_1_ACCENT_1", -178, "Medium List 1 Accent 1."), + EnumMember("TABLE_MEDIUM_LIST_2", -165, "Medium List 2."), + EnumMember("TABLE_MEDIUM_SHADING_1", -162, "Medium Shading 1."), + EnumMember( + "TABLE_MEDIUM_SHADING_1_ACCENT_1", -176, "Medium Shading 1 Accent 1." + ), + EnumMember("TABLE_MEDIUM_SHADING_2", -163, "Medium Shading 2."), + EnumMember( + "TABLE_MEDIUM_SHADING_2_ACCENT_1", -177, "Medium Shading 2 Accent 1." + ), + EnumMember("TABLE_OF_AUTHORITIES", -45, "Table of Authorities."), + EnumMember("TABLE_OF_FIGURES", -36, "Table of Figures."), + EnumMember("TITLE", -63, "Title."), + EnumMember("TOAHEADING", -47, "TOA Heading."), + EnumMember("TOC_1", -20, "TOC 1."), + EnumMember("TOC_2", -21, "TOC 2."), + EnumMember("TOC_3", -22, "TOC 3."), + EnumMember("TOC_4", -23, "TOC 4."), + EnumMember("TOC_5", -24, "TOC 5."), + EnumMember("TOC_6", -25, "TOC 6."), + EnumMember("TOC_7", -26, "TOC 7."), + EnumMember("TOC_8", -27, "TOC 8."), + EnumMember("TOC_9", -28, "TOC 9."), ) @@ -446,21 +184,13 @@ class WD_STYLE_TYPE(XmlEnumeration): assert styles[0].type == WD_STYLE_TYPE.PARAGRAPH """ - __ms_name__ = 'WdStyleType' + __ms_name__ = "WdStyleType" - __url__ = 'http://msdn.microsoft.com/en-us/library/office/ff196870.aspx' + __url__ = "http://msdn.microsoft.com/en-us/library/office/ff196870.aspx" __members__ = ( - XmlMappedEnumMember( - 'CHARACTER', 2, 'character', 'Character style.' - ), - XmlMappedEnumMember( - 'LIST', 4, 'numbering', 'List style.' - ), - XmlMappedEnumMember( - 'PARAGRAPH', 1, 'paragraph', 'Paragraph style.' - ), - XmlMappedEnumMember( - 'TABLE', 3, 'table', 'Table style.' - ), + XmlMappedEnumMember("CHARACTER", 2, "character", "Character style."), + XmlMappedEnumMember("LIST", 4, "numbering", "List style."), + XmlMappedEnumMember("PARAGRAPH", 1, "paragraph", "Paragraph style."), + XmlMappedEnumMember("TABLE", 3, "table", "Table style."), ) diff --git a/docx/enum/table.py b/docx/enum/table.py index eedab082..f66fdccd 100644 --- a/docx/enum/table.py +++ b/docx/enum/table.py @@ -4,16 +4,12 @@ Enumerations related to tables in WordprocessingML files """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals -from .base import ( - alias, Enumeration, EnumMember, XmlEnumeration, XmlMappedEnumMember -) +from .base import alias, Enumeration, EnumMember, XmlEnumeration, XmlMappedEnumMember -@alias('WD_ALIGN_VERTICAL') +@alias("WD_ALIGN_VERTICAL") class WD_CELL_VERTICAL_ALIGNMENT(XmlEnumeration): """ alias: **WD_ALIGN_VERTICAL** @@ -28,33 +24,37 @@ class WD_CELL_VERTICAL_ALIGNMENT(XmlEnumeration): table.cell(0, 0).vertical_alignment = WD_ALIGN_VERTICAL.BOTTOM """ - __ms_name__ = 'WdCellVerticalAlignment' + __ms_name__ = "WdCellVerticalAlignment" - __url__ = 'https://msdn.microsoft.com/en-us/library/office/ff193345.aspx' + __url__ = "https://msdn.microsoft.com/en-us/library/office/ff193345.aspx" __members__ = ( XmlMappedEnumMember( - 'TOP', 0, 'top', 'Text is aligned to the top border of the cell.' + "TOP", 0, "top", "Text is aligned to the top border of the cell." ), XmlMappedEnumMember( - 'CENTER', 1, 'center', 'Text is aligned to the center of the cel' - 'l.' + "CENTER", 1, "center", "Text is aligned to the center of the cel" "l." ), XmlMappedEnumMember( - 'BOTTOM', 3, 'bottom', 'Text is aligned to the bottom border of ' - 'the cell.' + "BOTTOM", + 3, + "bottom", + "Text is aligned to the bottom border of " "the cell.", ), XmlMappedEnumMember( - 'BOTH', 101, 'both', 'This is an option in the OpenXml spec, but' - ' not in Word itself. It\'s not clear what Word behavior this se' - 'tting produces. If you find out please let us know and we\'ll u' - 'pdate this documentation. Otherwise, probably best to avoid thi' - 's option.' + "BOTH", + 101, + "both", + "This is an option in the OpenXml spec, but" + " not in Word itself. It's not clear what Word behavior this se" + "tting produces. If you find out please let us know and we'll u" + "pdate this documentation. Otherwise, probably best to avoid thi" + "s option.", ), ) -@alias('WD_ROW_HEIGHT') +@alias("WD_ROW_HEIGHT") class WD_ROW_HEIGHT_RULE(XmlEnumeration): """ alias: **WD_ROW_HEIGHT** @@ -71,20 +71,23 @@ class WD_ROW_HEIGHT_RULE(XmlEnumeration): __ms_name__ = "WdRowHeightRule" - __url__ = 'https://msdn.microsoft.com/en-us/library/office/ff193620.aspx' + __url__ = "https://msdn.microsoft.com/en-us/library/office/ff193620.aspx" __members__ = ( XmlMappedEnumMember( - 'AUTO', 0, 'auto', 'The row height is adjusted to accommodate th' - 'e tallest value in the row.' + "AUTO", + 0, + "auto", + "The row height is adjusted to accommodate th" + "e tallest value in the row.", ), XmlMappedEnumMember( - 'AT_LEAST', 1, 'atLeast', 'The row height is at least a minimum ' - 'specified value.' - ), - XmlMappedEnumMember( - 'EXACTLY', 2, 'exact', 'The row height is an exact value.' + "AT_LEAST", + 1, + "atLeast", + "The row height is at least a minimum " "specified value.", ), + XmlMappedEnumMember("EXACTLY", 2, "exact", "The row height is an exact value."), ) @@ -100,20 +103,14 @@ class WD_TABLE_ALIGNMENT(XmlEnumeration): table.alignment = WD_TABLE_ALIGNMENT.CENTER """ - __ms_name__ = 'WdRowAlignment' + __ms_name__ = "WdRowAlignment" - __url__ = ' http://office.microsoft.com/en-us/word-help/HV080607259.aspx' + __url__ = " http://office.microsoft.com/en-us/word-help/HV080607259.aspx" __members__ = ( - XmlMappedEnumMember( - 'LEFT', 0, 'left', 'Left-aligned' - ), - XmlMappedEnumMember( - 'CENTER', 1, 'center', 'Center-aligned.' - ), - XmlMappedEnumMember( - 'RIGHT', 2, 'right', 'Right-aligned.' - ), + XmlMappedEnumMember("LEFT", 0, "left", "Left-aligned"), + XmlMappedEnumMember("CENTER", 1, "center", "Center-aligned."), + XmlMappedEnumMember("RIGHT", 2, "right", "Right-aligned."), ) @@ -130,17 +127,21 @@ class WD_TABLE_DIRECTION(Enumeration): table.direction = WD_TABLE_DIRECTION.RTL """ - __ms_name__ = 'WdTableDirection' + __ms_name__ = "WdTableDirection" - __url__ = ' http://msdn.microsoft.com/en-us/library/ff835141.aspx' + __url__ = " http://msdn.microsoft.com/en-us/library/ff835141.aspx" __members__ = ( EnumMember( - 'LTR', 0, 'The table or row is arranged with the first column ' - 'in the leftmost position.' + "LTR", + 0, + "The table or row is arranged with the first column " + "in the leftmost position.", ), EnumMember( - 'RTL', 1, 'The table or row is arranged with the first column ' - 'in the rightmost position.' + "RTL", + 1, + "The table or row is arranged with the first column " + "in the rightmost position.", ), ) diff --git a/docx/enum/text.py b/docx/enum/text.py index 67f6a66a..1de05326 100644 --- a/docx/enum/text.py +++ b/docx/enum/text.py @@ -9,7 +9,7 @@ from .base import alias, EnumMember, XmlEnumeration, XmlMappedEnumMember -@alias('WD_ALIGN_PARAGRAPH') +@alias("WD_ALIGN_PARAGRAPH") class WD_PARAGRAPH_ALIGNMENT(XmlEnumeration): """ alias: **WD_ALIGN_PARAGRAPH** @@ -24,42 +24,45 @@ class WD_PARAGRAPH_ALIGNMENT(XmlEnumeration): paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER """ - __ms_name__ = 'WdParagraphAlignment' + __ms_name__ = "WdParagraphAlignment" - __url__ = 'http://msdn.microsoft.com/en-us/library/office/ff835817.aspx' + __url__ = "http://msdn.microsoft.com/en-us/library/office/ff835817.aspx" __members__ = ( + XmlMappedEnumMember("LEFT", 0, "left", "Left-aligned"), + XmlMappedEnumMember("CENTER", 1, "center", "Center-aligned."), + XmlMappedEnumMember("RIGHT", 2, "right", "Right-aligned."), + XmlMappedEnumMember("JUSTIFY", 3, "both", "Fully justified."), XmlMappedEnumMember( - 'LEFT', 0, 'left', 'Left-aligned' + "DISTRIBUTE", + 4, + "distribute", + "Paragraph characters are distrib" + "uted to fill the entire width of the paragraph.", ), XmlMappedEnumMember( - 'CENTER', 1, 'center', 'Center-aligned.' + "JUSTIFY_MED", + 5, + "mediumKashida", + "Justified with a medium char" "acter compression ratio.", ), XmlMappedEnumMember( - 'RIGHT', 2, 'right', 'Right-aligned.' + "JUSTIFY_HI", + 7, + "highKashida", + "Justified with a high character" " compression ratio.", ), XmlMappedEnumMember( - 'JUSTIFY', 3, 'both', 'Fully justified.' + "JUSTIFY_LOW", + 8, + "lowKashida", + "Justified with a low character " "compression ratio.", ), XmlMappedEnumMember( - 'DISTRIBUTE', 4, 'distribute', 'Paragraph characters are distrib' - 'uted to fill the entire width of the paragraph.' - ), - XmlMappedEnumMember( - 'JUSTIFY_MED', 5, 'mediumKashida', 'Justified with a medium char' - 'acter compression ratio.' - ), - XmlMappedEnumMember( - 'JUSTIFY_HI', 7, 'highKashida', 'Justified with a high character' - ' compression ratio.' - ), - XmlMappedEnumMember( - 'JUSTIFY_LOW', 8, 'lowKashida', 'Justified with a low character ' - 'compression ratio.' - ), - XmlMappedEnumMember( - 'THAI_JUSTIFY', 9, 'thaiDistribute', 'Justified according to Tha' - 'i formatting layout.' + "THAI_JUSTIFY", + 9, + "thaiDistribute", + "Justified according to Tha" "i formatting layout.", ), ) @@ -69,6 +72,7 @@ class WD_BREAK_TYPE(object): Corresponds to WdBreakType enumeration http://msdn.microsoft.com/en-us/library/office/ff195905.aspx """ + COLUMN = 8 LINE = 6 LINE_CLEAR_LEFT = 9 @@ -85,72 +89,40 @@ class WD_BREAK_TYPE(object): WD_BREAK = WD_BREAK_TYPE -@alias('WD_COLOR') +@alias("WD_COLOR") class WD_COLOR_INDEX(XmlEnumeration): """ Specifies a standard preset color to apply. Used for font highlighting and perhaps other applications. """ - __ms_name__ = 'WdColorIndex' + __ms_name__ = "WdColorIndex" - __url__ = 'https://msdn.microsoft.com/EN-US/library/office/ff195343.aspx' + __url__ = "https://msdn.microsoft.com/EN-US/library/office/ff195343.aspx" __members__ = ( XmlMappedEnumMember( - None, None, None, 'Color is inherited from the style hierarchy.' - ), - XmlMappedEnumMember( - 'AUTO', 0, 'default', 'Automatic color. Default; usually black.' - ), - XmlMappedEnumMember( - 'BLACK', 1, 'black', 'Black color.' - ), - XmlMappedEnumMember( - 'BLUE', 2, 'blue', 'Blue color' - ), - XmlMappedEnumMember( - 'BRIGHT_GREEN', 4, 'green', 'Bright green color.' - ), - XmlMappedEnumMember( - 'DARK_BLUE', 9, 'darkBlue', 'Dark blue color.' - ), - XmlMappedEnumMember( - 'DARK_RED', 13, 'darkRed', 'Dark red color.' - ), - XmlMappedEnumMember( - 'DARK_YELLOW', 14, 'darkYellow', 'Dark yellow color.' - ), - XmlMappedEnumMember( - 'GRAY_25', 16, 'lightGray', '25% shade of gray color.' - ), - XmlMappedEnumMember( - 'GRAY_50', 15, 'darkGray', '50% shade of gray color.' - ), - XmlMappedEnumMember( - 'GREEN', 11, 'darkGreen', 'Green color.' - ), - XmlMappedEnumMember( - 'PINK', 5, 'magenta', 'Pink color.' - ), - XmlMappedEnumMember( - 'RED', 6, 'red', 'Red color.' - ), - XmlMappedEnumMember( - 'TEAL', 10, 'darkCyan', 'Teal color.' - ), - XmlMappedEnumMember( - 'TURQUOISE', 3, 'cyan', 'Turquoise color.' - ), - XmlMappedEnumMember( - 'VIOLET', 12, 'darkMagenta', 'Violet color.' - ), - XmlMappedEnumMember( - 'WHITE', 8, 'white', 'White color.' - ), - XmlMappedEnumMember( - 'YELLOW', 7, 'yellow', 'Yellow color.' - ), + None, None, None, "Color is inherited from the style hierarchy." + ), + XmlMappedEnumMember( + "AUTO", 0, "default", "Automatic color. Default; usually black." + ), + XmlMappedEnumMember("BLACK", 1, "black", "Black color."), + XmlMappedEnumMember("BLUE", 2, "blue", "Blue color"), + XmlMappedEnumMember("BRIGHT_GREEN", 4, "green", "Bright green color."), + XmlMappedEnumMember("DARK_BLUE", 9, "darkBlue", "Dark blue color."), + XmlMappedEnumMember("DARK_RED", 13, "darkRed", "Dark red color."), + XmlMappedEnumMember("DARK_YELLOW", 14, "darkYellow", "Dark yellow color."), + XmlMappedEnumMember("GRAY_25", 16, "lightGray", "25% shade of gray color."), + XmlMappedEnumMember("GRAY_50", 15, "darkGray", "50% shade of gray color."), + XmlMappedEnumMember("GREEN", 11, "darkGreen", "Green color."), + XmlMappedEnumMember("PINK", 5, "magenta", "Pink color."), + XmlMappedEnumMember("RED", 6, "red", "Red color."), + XmlMappedEnumMember("TEAL", 10, "darkCyan", "Teal color."), + XmlMappedEnumMember("TURQUOISE", 3, "cyan", "Turquoise color."), + XmlMappedEnumMember("VIOLET", 12, "darkMagenta", "Violet color."), + XmlMappedEnumMember("WHITE", 8, "white", "White color."), + XmlMappedEnumMember("YELLOW", 7, "yellow", "Yellow color."), ) @@ -166,33 +138,36 @@ class WD_LINE_SPACING(XmlEnumeration): paragraph.line_spacing_rule = WD_LINE_SPACING.EXACTLY """ - __ms_name__ = 'WdLineSpacing' + __ms_name__ = "WdLineSpacing" - __url__ = 'http://msdn.microsoft.com/en-us/library/office/ff844910.aspx' + __url__ = "http://msdn.microsoft.com/en-us/library/office/ff844910.aspx" __members__ = ( - EnumMember( - 'ONE_POINT_FIVE', 1, 'Space-and-a-half line spacing.' - ), + EnumMember("ONE_POINT_FIVE", 1, "Space-and-a-half line spacing."), XmlMappedEnumMember( - 'AT_LEAST', 3, 'atLeast', 'Line spacing is always at least the s' - 'pecified amount. The amount is specified separately.' - ), - EnumMember( - 'DOUBLE', 2, 'Double spaced.' + "AT_LEAST", + 3, + "atLeast", + "Line spacing is always at least the s" + "pecified amount. The amount is specified separately.", ), + EnumMember("DOUBLE", 2, "Double spaced."), XmlMappedEnumMember( - 'EXACTLY', 4, 'exact', 'Line spacing is exactly the specified am' - 'ount. The amount is specified separately.' + "EXACTLY", + 4, + "exact", + "Line spacing is exactly the specified am" + "ount. The amount is specified separately.", ), XmlMappedEnumMember( - 'MULTIPLE', 5, 'auto', 'Line spacing is specified as a multiple ' - 'of line heights. Changing the font size will change the line sp' - 'acing proportionately.' - ), - EnumMember( - 'SINGLE', 0, 'Single spaced (default).' + "MULTIPLE", + 5, + "auto", + "Line spacing is specified as a multiple " + "of line heights. Changing the font size will change the line sp" + "acing proportionately.", ), + EnumMember("SINGLE", 0, "Single spaced (default)."), ) @@ -201,41 +176,21 @@ class WD_TAB_ALIGNMENT(XmlEnumeration): Specifies the tab stop alignment to apply. """ - __ms_name__ = 'WdTabAlignment' + __ms_name__ = "WdTabAlignment" - __url__ = 'https://msdn.microsoft.com/EN-US/library/office/ff195609.aspx' + __url__ = "https://msdn.microsoft.com/EN-US/library/office/ff195609.aspx" __members__ = ( - XmlMappedEnumMember( - 'LEFT', 0, 'left', 'Left-aligned.' - ), - XmlMappedEnumMember( - 'CENTER', 1, 'center', 'Center-aligned.' - ), - XmlMappedEnumMember( - 'RIGHT', 2, 'right', 'Right-aligned.' - ), - XmlMappedEnumMember( - 'DECIMAL', 3, 'decimal', 'Decimal-aligned.' - ), - XmlMappedEnumMember( - 'BAR', 4, 'bar', 'Bar-aligned.' - ), - XmlMappedEnumMember( - 'LIST', 6, 'list', 'List-aligned. (deprecated)' - ), - XmlMappedEnumMember( - 'CLEAR', 101, 'clear', 'Clear an inherited tab stop.' - ), - XmlMappedEnumMember( - 'END', 102, 'end', 'Right-aligned. (deprecated)' - ), - XmlMappedEnumMember( - 'NUM', 103, 'num', 'Left-aligned. (deprecated)' - ), - XmlMappedEnumMember( - 'START', 104, 'start', 'Left-aligned. (deprecated)' - ), + XmlMappedEnumMember("LEFT", 0, "left", "Left-aligned."), + XmlMappedEnumMember("CENTER", 1, "center", "Center-aligned."), + XmlMappedEnumMember("RIGHT", 2, "right", "Right-aligned."), + XmlMappedEnumMember("DECIMAL", 3, "decimal", "Decimal-aligned."), + XmlMappedEnumMember("BAR", 4, "bar", "Bar-aligned."), + XmlMappedEnumMember("LIST", 6, "list", "List-aligned. (deprecated)"), + XmlMappedEnumMember("CLEAR", 101, "clear", "Clear an inherited tab stop."), + XmlMappedEnumMember("END", 102, "end", "Right-aligned. (deprecated)"), + XmlMappedEnumMember("NUM", 103, "num", "Left-aligned. (deprecated)"), + XmlMappedEnumMember("START", 104, "start", "Left-aligned. (deprecated)"), ) @@ -244,29 +199,17 @@ class WD_TAB_LEADER(XmlEnumeration): Specifies the character to use as the leader with formatted tabs. """ - __ms_name__ = 'WdTabLeader' + __ms_name__ = "WdTabLeader" - __url__ = 'https://msdn.microsoft.com/en-us/library/office/ff845050.aspx' + __url__ = "https://msdn.microsoft.com/en-us/library/office/ff845050.aspx" __members__ = ( - XmlMappedEnumMember( - 'SPACES', 0, 'none', 'Spaces. Default.' - ), - XmlMappedEnumMember( - 'DOTS', 1, 'dot', 'Dots.' - ), - XmlMappedEnumMember( - 'DASHES', 2, 'hyphen', 'Dashes.' - ), - XmlMappedEnumMember( - 'LINES', 3, 'underscore', 'Double lines.' - ), - XmlMappedEnumMember( - 'HEAVY', 4, 'heavy', 'A heavy line.' - ), - XmlMappedEnumMember( - 'MIDDLE_DOT', 5, 'middleDot', 'A vertically-centered dot.' - ), + XmlMappedEnumMember("SPACES", 0, "none", "Spaces. Default."), + XmlMappedEnumMember("DOTS", 1, "dot", "Dots."), + XmlMappedEnumMember("DASHES", 2, "hyphen", "Dashes."), + XmlMappedEnumMember("LINES", 3, "underscore", "Double lines."), + XmlMappedEnumMember("HEAVY", 4, "heavy", "A heavy line."), + XmlMappedEnumMember("MIDDLE_DOT", 5, "middleDot", "A vertically-centered dot."), ) @@ -275,78 +218,62 @@ class WD_UNDERLINE(XmlEnumeration): Specifies the style of underline applied to a run of characters. """ - __ms_name__ = 'WdUnderline' + __ms_name__ = "WdUnderline" - __url__ = 'http://msdn.microsoft.com/en-us/library/office/ff822388.aspx' + __url__ = "http://msdn.microsoft.com/en-us/library/office/ff822388.aspx" __members__ = ( XmlMappedEnumMember( - None, None, None, 'Inherit underline setting from containing par' - 'agraph.' - ), - XmlMappedEnumMember( - 'NONE', 0, 'none', 'No underline. This setting overrides any inh' - 'erited underline value, so can be used to remove underline from' - ' a run that inherits underlining from its containing paragraph.' - ' Note this is not the same as assigning |None| to Run.underline' - '. |None| is a valid assignment value, but causes the run to inh' - 'erit its underline value. Assigning ``WD_UNDERLINE.NONE`` cause' - 's underlining to be unconditionally turned off.' - ), - XmlMappedEnumMember( - 'SINGLE', 1, 'single', 'A single line. Note that this setting is' - 'write-only in the sense that |True| (rather than ``WD_UNDERLINE' - '.SINGLE``) is returned for a run having this setting.' - ), - XmlMappedEnumMember( - 'WORDS', 2, 'words', 'Underline individual words only.' - ), - XmlMappedEnumMember( - 'DOUBLE', 3, 'double', 'A double line.' - ), - XmlMappedEnumMember( - 'DOTTED', 4, 'dotted', 'Dots.' - ), - XmlMappedEnumMember( - 'THICK', 6, 'thick', 'A single thick line.' - ), - XmlMappedEnumMember( - 'DASH', 7, 'dash', 'Dashes.' - ), - XmlMappedEnumMember( - 'DOT_DASH', 9, 'dotDash', 'Alternating dots and dashes.' - ), - XmlMappedEnumMember( - 'DOT_DOT_DASH', 10, 'dotDotDash', 'An alternating dot-dot-dash p' - 'attern.' - ), - XmlMappedEnumMember( - 'WAVY', 11, 'wave', 'A single wavy line.' - ), - XmlMappedEnumMember( - 'DOTTED_HEAVY', 20, 'dottedHeavy', 'Heavy dots.' - ), - XmlMappedEnumMember( - 'DASH_HEAVY', 23, 'dashedHeavy', 'Heavy dashes.' + None, None, None, "Inherit underline setting from containing par" "agraph." ), XmlMappedEnumMember( - 'DOT_DASH_HEAVY', 25, 'dashDotHeavy', 'Alternating heavy dots an' - 'd heavy dashes.' + "NONE", + 0, + "none", + "No underline. This setting overrides any inh" + "erited underline value, so can be used to remove underline from" + " a run that inherits underlining from its containing paragraph." + " Note this is not the same as assigning |None| to Run.underline" + ". |None| is a valid assignment value, but causes the run to inh" + "erit its underline value. Assigning ``WD_UNDERLINE.NONE`` cause" + "s underlining to be unconditionally turned off.", ), XmlMappedEnumMember( - 'DOT_DOT_DASH_HEAVY', 26, 'dashDotDotHeavy', 'An alternating hea' - 'vy dot-dot-dash pattern.' + "SINGLE", + 1, + "single", + "A single line. Note that this setting is" + "write-only in the sense that |True| (rather than ``WD_UNDERLINE" + ".SINGLE``) is returned for a run having this setting.", ), + XmlMappedEnumMember("WORDS", 2, "words", "Underline individual words only."), + XmlMappedEnumMember("DOUBLE", 3, "double", "A double line."), + XmlMappedEnumMember("DOTTED", 4, "dotted", "Dots."), + XmlMappedEnumMember("THICK", 6, "thick", "A single thick line."), + XmlMappedEnumMember("DASH", 7, "dash", "Dashes."), + XmlMappedEnumMember("DOT_DASH", 9, "dotDash", "Alternating dots and dashes."), XmlMappedEnumMember( - 'WAVY_HEAVY', 27, 'wavyHeavy', 'A heavy wavy line.' + "DOT_DOT_DASH", 10, "dotDotDash", "An alternating dot-dot-dash p" "attern." ), + XmlMappedEnumMember("WAVY", 11, "wave", "A single wavy line."), + XmlMappedEnumMember("DOTTED_HEAVY", 20, "dottedHeavy", "Heavy dots."), + XmlMappedEnumMember("DASH_HEAVY", 23, "dashedHeavy", "Heavy dashes."), XmlMappedEnumMember( - 'DASH_LONG', 39, 'dashLong', 'Long dashes.' + "DOT_DASH_HEAVY", + 25, + "dashDotHeavy", + "Alternating heavy dots an" "d heavy dashes.", ), XmlMappedEnumMember( - 'WAVY_DOUBLE', 43, 'wavyDouble', 'A double wavy line.' + "DOT_DOT_DASH_HEAVY", + 26, + "dashDotDotHeavy", + "An alternating hea" "vy dot-dot-dash pattern.", ), + XmlMappedEnumMember("WAVY_HEAVY", 27, "wavyHeavy", "A heavy wavy line."), + XmlMappedEnumMember("DASH_LONG", 39, "dashLong", "Long dashes."), + XmlMappedEnumMember("WAVY_DOUBLE", 43, "wavyDouble", "A double wavy line."), XmlMappedEnumMember( - 'DASH_LONG_HEAVY', 55, 'dashLongHeavy', 'Long heavy dashes.' + "DASH_LONG_HEAVY", 55, "dashLongHeavy", "Long heavy dashes." ), ) diff --git a/docx/image/__init__.py b/docx/image/__init__.py index 8ab3ada6..e8523454 100644 --- a/docx/image/__init__.py +++ b/docx/image/__init__.py @@ -5,9 +5,7 @@ size, as a required step in including them in a document. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals from docx.image.bmp import Bmp from docx.image.gif import Gif @@ -18,12 +16,12 @@ SIGNATURES = ( # class, offset, signature_bytes - (Png, 0, b'\x89PNG\x0D\x0A\x1A\x0A'), - (Jfif, 6, b'JFIF'), - (Exif, 6, b'Exif'), - (Gif, 0, b'GIF87a'), - (Gif, 0, b'GIF89a'), - (Tiff, 0, b'MM\x00*'), # big-endian (Motorola) TIFF - (Tiff, 0, b'II*\x00'), # little-endian (Intel) TIFF - (Bmp, 0, b'BM'), + (Png, 0, b"\x89PNG\x0D\x0A\x1A\x0A"), + (Jfif, 6, b"JFIF"), + (Exif, 6, b"Exif"), + (Gif, 0, b"GIF87a"), + (Gif, 0, b"GIF89a"), + (Tiff, 0, b"MM\x00*"), # big-endian (Motorola) TIFF + (Tiff, 0, b"II*\x00"), # little-endian (Intel) TIFF + (Bmp, 0, b"BM"), ) diff --git a/docx/image/bmp.py b/docx/image/bmp.py index d22f2587..aebc6b9c 100644 --- a/docx/image/bmp.py +++ b/docx/image/bmp.py @@ -11,6 +11,7 @@ class Bmp(BaseImageHeader): """ Image header parser for BMP images """ + @classmethod def from_stream(cls, stream): """ @@ -43,7 +44,7 @@ def default_ext(self): """ Default filename extension, always 'bmp' for BMP images. """ - return 'bmp' + return "bmp" @staticmethod def _dpi(px_per_meter): diff --git a/docx/image/constants.py b/docx/image/constants.py index 90b46970..e4fa17fb 100644 --- a/docx/image/constants.py +++ b/docx/image/constants.py @@ -9,83 +9,93 @@ class JPEG_MARKER_CODE(object): """ JPEG marker codes """ - TEM = b'\x01' - DHT = b'\xC4' - DAC = b'\xCC' - JPG = b'\xC8' - - SOF0 = b'\xC0' - SOF1 = b'\xC1' - SOF2 = b'\xC2' - SOF3 = b'\xC3' - SOF5 = b'\xC5' - SOF6 = b'\xC6' - SOF7 = b'\xC7' - SOF9 = b'\xC9' - SOFA = b'\xCA' - SOFB = b'\xCB' - SOFD = b'\xCD' - SOFE = b'\xCE' - SOFF = b'\xCF' - - RST0 = b'\xD0' - RST1 = b'\xD1' - RST2 = b'\xD2' - RST3 = b'\xD3' - RST4 = b'\xD4' - RST5 = b'\xD5' - RST6 = b'\xD6' - RST7 = b'\xD7' - - SOI = b'\xD8' - EOI = b'\xD9' - SOS = b'\xDA' - DQT = b'\xDB' # Define Quantization Table(s) - DNL = b'\xDC' - DRI = b'\xDD' - DHP = b'\xDE' - EXP = b'\xDF' - - APP0 = b'\xE0' - APP1 = b'\xE1' - APP2 = b'\xE2' - APP3 = b'\xE3' - APP4 = b'\xE4' - APP5 = b'\xE5' - APP6 = b'\xE6' - APP7 = b'\xE7' - APP8 = b'\xE8' - APP9 = b'\xE9' - APPA = b'\xEA' - APPB = b'\xEB' - APPC = b'\xEC' - APPD = b'\xED' - APPE = b'\xEE' - APPF = b'\xEF' - - STANDALONE_MARKERS = ( - TEM, SOI, EOI, RST0, RST1, RST2, RST3, RST4, RST5, RST6, RST7 - ) + + TEM = b"\x01" + DHT = b"\xC4" + DAC = b"\xCC" + JPG = b"\xC8" + + SOF0 = b"\xC0" + SOF1 = b"\xC1" + SOF2 = b"\xC2" + SOF3 = b"\xC3" + SOF5 = b"\xC5" + SOF6 = b"\xC6" + SOF7 = b"\xC7" + SOF9 = b"\xC9" + SOFA = b"\xCA" + SOFB = b"\xCB" + SOFD = b"\xCD" + SOFE = b"\xCE" + SOFF = b"\xCF" + + RST0 = b"\xD0" + RST1 = b"\xD1" + RST2 = b"\xD2" + RST3 = b"\xD3" + RST4 = b"\xD4" + RST5 = b"\xD5" + RST6 = b"\xD6" + RST7 = b"\xD7" + + SOI = b"\xD8" + EOI = b"\xD9" + SOS = b"\xDA" + DQT = b"\xDB" # Define Quantization Table(s) + DNL = b"\xDC" + DRI = b"\xDD" + DHP = b"\xDE" + EXP = b"\xDF" + + APP0 = b"\xE0" + APP1 = b"\xE1" + APP2 = b"\xE2" + APP3 = b"\xE3" + APP4 = b"\xE4" + APP5 = b"\xE5" + APP6 = b"\xE6" + APP7 = b"\xE7" + APP8 = b"\xE8" + APP9 = b"\xE9" + APPA = b"\xEA" + APPB = b"\xEB" + APPC = b"\xEC" + APPD = b"\xED" + APPE = b"\xEE" + APPF = b"\xEF" + + STANDALONE_MARKERS = (TEM, SOI, EOI, RST0, RST1, RST2, RST3, RST4, RST5, RST6, RST7) SOF_MARKER_CODES = ( - SOF0, SOF1, SOF2, SOF3, SOF5, SOF6, SOF7, SOF9, SOFA, SOFB, SOFD, - SOFE, SOFF + SOF0, + SOF1, + SOF2, + SOF3, + SOF5, + SOF6, + SOF7, + SOF9, + SOFA, + SOFB, + SOFD, + SOFE, + SOFF, ) marker_names = { - b'\x00': 'UNKNOWN', - b'\xC0': 'SOF0', - b'\xC2': 'SOF2', - b'\xC4': 'DHT', - b'\xDA': 'SOS', # start of scan - b'\xD8': 'SOI', # start of image - b'\xD9': 'EOI', # end of image - b'\xDB': 'DQT', - b'\xE0': 'APP0', - b'\xE1': 'APP1', - b'\xE2': 'APP2', - b'\xED': 'APP13', - b'\xEE': 'APP14', + b"\x00": "UNKNOWN", + b"\xC0": "SOF0", + b"\xC2": "SOF2", + b"\xC4": "DHT", + b"\xDA": "SOS", # start of scan + b"\xD8": "SOI", # start of image + b"\xD9": "EOI", # end of image + b"\xDB": "DQT", + b"\xE0": "APP0", + b"\xE1": "APP1", + b"\xE2": "APP2", + b"\xED": "APP13", + b"\xEE": "APP14", } @classmethod @@ -97,26 +107,29 @@ class MIME_TYPE(object): """ Image content types """ - BMP = 'image/bmp' - GIF = 'image/gif' - JPEG = 'image/jpeg' - PNG = 'image/png' - TIFF = 'image/tiff' + + BMP = "image/bmp" + GIF = "image/gif" + JPEG = "image/jpeg" + PNG = "image/png" + TIFF = "image/tiff" class PNG_CHUNK_TYPE(object): """ PNG chunk type names """ - IHDR = 'IHDR' - pHYs = 'pHYs' - IEND = 'IEND' + + IHDR = "IHDR" + pHYs = "pHYs" + IEND = "IEND" class TIFF_FLD_TYPE(object): """ Tag codes for TIFF Image File Directory (IFD) entries. """ + BYTE = 1 ASCII = 2 SHORT = 3 @@ -124,8 +137,11 @@ class TIFF_FLD_TYPE(object): RATIONAL = 5 field_type_names = { - 1: 'BYTE', 2: 'ASCII char', 3: 'SHORT', 4: 'LONG', - 5: 'RATIONAL' + 1: "BYTE", + 2: "ASCII char", + 3: "SHORT", + 4: "LONG", + 5: "RATIONAL", } @@ -136,6 +152,7 @@ class TIFF_TAG(object): """ Tag codes for TIFF Image File Directory (IFD) entries. """ + IMAGE_WIDTH = 0x0100 IMAGE_LENGTH = 0x0101 X_RESOLUTION = 0x011A @@ -143,27 +160,27 @@ class TIFF_TAG(object): RESOLUTION_UNIT = 0x0128 tag_names = { - 0x00FE: 'NewSubfileType', - 0x0100: 'ImageWidth', - 0x0101: 'ImageLength', - 0x0102: 'BitsPerSample', - 0x0103: 'Compression', - 0x0106: 'PhotometricInterpretation', - 0x010E: 'ImageDescription', - 0x010F: 'Make', - 0x0110: 'Model', - 0x0111: 'StripOffsets', - 0x0112: 'Orientation', - 0x0115: 'SamplesPerPixel', - 0x0117: 'StripByteCounts', - 0x011A: 'XResolution', - 0x011B: 'YResolution', - 0x011C: 'PlanarConfiguration', - 0x0128: 'ResolutionUnit', - 0x0131: 'Software', - 0x0132: 'DateTime', - 0x0213: 'YCbCrPositioning', - 0x8769: 'ExifTag', - 0x8825: 'GPS IFD', - 0xC4A5: 'PrintImageMatching', + 0x00FE: "NewSubfileType", + 0x0100: "ImageWidth", + 0x0101: "ImageLength", + 0x0102: "BitsPerSample", + 0x0103: "Compression", + 0x0106: "PhotometricInterpretation", + 0x010E: "ImageDescription", + 0x010F: "Make", + 0x0110: "Model", + 0x0111: "StripOffsets", + 0x0112: "Orientation", + 0x0115: "SamplesPerPixel", + 0x0117: "StripByteCounts", + 0x011A: "XResolution", + 0x011B: "YResolution", + 0x011C: "PlanarConfiguration", + 0x0128: "ResolutionUnit", + 0x0131: "Software", + 0x0132: "DateTime", + 0x0213: "YCbCrPositioning", + 0x8769: "ExifTag", + 0x8825: "GPS IFD", + 0xC4A5: "PrintImageMatching", } diff --git a/docx/image/gif.py b/docx/image/gif.py index 57f037d8..07f2b1c7 100644 --- a/docx/image/gif.py +++ b/docx/image/gif.py @@ -14,6 +14,7 @@ class Gif(BaseImageHeader): support resolution (DPI) information. Both horizontal and vertical DPI default to 72. """ + @classmethod def from_stream(cls, stream): """ @@ -36,12 +37,12 @@ def default_ext(self): """ Default filename extension, always 'gif' for GIF images. """ - return 'gif' + return "gif" @classmethod def _dimensions_from_stream(cls, stream): stream.seek(6) bytes_ = stream.read(4) - struct = Struct('L' + fmt = "L" return self._read_int(fmt, base, offset) def read_short(self, base, offset=0): @@ -55,7 +54,7 @@ def read_short(self, base, offset=0): Return the int value of the two bytes at the file position determined by *base* and *offset*, similarly to ``read_long()`` above. """ - fmt = b'H' + fmt = b"H" return self._read_int(fmt, base, offset) def read_str(self, char_count, base, offset=0): @@ -63,12 +62,14 @@ def read_str(self, char_count, base, offset=0): Return a string containing the *char_count* bytes at the file position determined by self._base_offset + *base* + *offset*. """ + def str_struct(char_count): - format_ = '%ds' % char_count + format_ = "%ds" % char_count return Struct(format_) + struct = str_struct(char_count) chars = self._unpack_item(struct, base, offset) - unicode_str = chars.decode('UTF-8') + unicode_str = chars.decode("UTF-8") return unicode_str def seek(self, base, offset=0): diff --git a/docx/image/image.py b/docx/image/image.py index ba2158e7..8fddaabc 100644 --- a/docx/image/image.py +++ b/docx/image/image.py @@ -20,6 +20,7 @@ class Image(object): Graphical image stream such as JPEG, PNG, or GIF with properties and methods required by ImagePart. """ + def __init__(self, blob, filename, image_header): super(Image, self).__init__() self._blob = blob @@ -43,7 +44,7 @@ def from_file(cls, image_descriptor): """ if is_string(image_descriptor): path = image_descriptor - with open(path, 'rb') as f: + with open(path, "rb") as f: blob = f.read() stream = BytesIO(blob) filename = os.path.basename(path) @@ -175,7 +176,7 @@ def _from_stream(cls, stream, blob, filename=None): """ image_header = _ImageHeaderFactory(stream) if filename is None: - filename = 'image.%s' % image_header.default_ext + filename = "image.%s" % image_header.default_ext return cls(blob, filename, image_header) @@ -203,6 +204,7 @@ class BaseImageHeader(object): """ Base class for image header subclasses like |Jpeg| and |Tiff|. """ + def __init__(self, px_width, px_height, horz_dpi, vert_dpi): self._px_width = px_width self._px_height = px_height @@ -215,8 +217,8 @@ def content_type(self): Abstract property definition, must be implemented by all subclasses. """ msg = ( - 'content_type property must be implemented by all subclasses of ' - 'BaseImageHeader' + "content_type property must be implemented by all subclasses of " + "BaseImageHeader" ) raise NotImplementedError(msg) @@ -227,8 +229,8 @@ def default_ext(self): property definition, must be implemented by all subclasses. """ msg = ( - 'default_ext property must be implemented by all subclasses of ' - 'BaseImageHeader' + "default_ext property must be implemented by all subclasses of " + "BaseImageHeader" ) raise NotImplementedError(msg) diff --git a/docx/image/jpeg.py b/docx/image/jpeg.py index 4ce39b98..40354e97 100644 --- a/docx/image/jpeg.py +++ b/docx/image/jpeg.py @@ -13,6 +13,7 @@ class Jpeg(BaseImageHeader): """ Base class for JFIF and EXIF subclasses. """ + @property def content_type(self): """ @@ -26,13 +27,14 @@ def default_ext(self): """ Default filename extension, always 'jpg' for JPG images. """ - return 'jpg' + return "jpg" class Exif(Jpeg): """ Image header parser for Exif image format """ + @classmethod def from_stream(cls, stream): """ @@ -53,6 +55,7 @@ class Jfif(Jpeg): """ Image header parser for JFIF image format """ + @classmethod def from_stream(cls, stream): """ @@ -74,6 +77,7 @@ class _JfifMarkers(object): Sequence of markers in a JPEG file, perhaps truncated at first SOS marker for performance reasons. """ + def __init__(self, markers): super(_JfifMarkers, self).__init__() self._markers = list(markers) @@ -83,16 +87,21 @@ def __str__(self): # pragma: no cover Returns a tabular listing of the markers in this instance, which can be handy for debugging and perhaps other uses. """ - header = ' offset seglen mc name\n======= ====== == =====' - tmpl = '%7d %6d %02X %s' + header = " offset seglen mc name\n======= ====== == =====" + tmpl = "%7d %6d %02X %s" rows = [] for marker in self._markers: - rows.append(tmpl % ( - marker.offset, marker.segment_length, - ord(marker.marker_code), marker.name - )) + rows.append( + tmpl + % ( + marker.offset, + marker.segment_length, + ord(marker.marker_code), + marker.name, + ) + ) lines = [header] + rows - return '\n'.join(lines) + return "\n".join(lines) @classmethod def from_stream(cls, stream): @@ -116,7 +125,7 @@ def app0(self): for m in self._markers: if m.marker_code == JPEG_MARKER_CODE.APP0: return m - raise KeyError('no APP0 marker in image') + raise KeyError("no APP0 marker in image") @property def app1(self): @@ -126,7 +135,7 @@ def app1(self): for m in self._markers: if m.marker_code == JPEG_MARKER_CODE.APP1: return m - raise KeyError('no APP1 marker in image') + raise KeyError("no APP1 marker in image") @property def sof(self): @@ -136,7 +145,7 @@ def sof(self): for m in self._markers: if m.marker_code in JPEG_MARKER_CODE.SOF_MARKER_CODES: return m - raise KeyError('no start of frame (SOFn) marker in image') + raise KeyError("no start of frame (SOFn) marker in image") class _MarkerParser(object): @@ -144,6 +153,7 @@ class _MarkerParser(object): Service class that knows how to parse a JFIF stream and iterate over its markers. """ + def __init__(self, stream_reader): super(_MarkerParser, self).__init__() self._stream = stream_reader @@ -167,9 +177,7 @@ def iter_markers(self): marker_code = None while marker_code != JPEG_MARKER_CODE.EOI: marker_code, segment_offset = marker_finder.next(start) - marker = _MarkerFactory( - marker_code, self._stream, segment_offset - ) + marker = _MarkerFactory(marker_code, self._stream, segment_offset) yield marker start = segment_offset + marker.segment_length @@ -178,6 +186,7 @@ class _MarkerFinder(object): """ Service class that knows how to find the next JFIF marker in a stream. """ + def __init__(self, stream): super(_MarkerFinder, self).__init__() self._stream = stream @@ -202,12 +211,12 @@ def next(self, start): # skip over any non-\xFF bytes position = self._offset_of_next_ff_byte(start=position) # skip over any \xFF padding bytes - position, byte_ = self._next_non_ff_byte(start=position+1) + position, byte_ = self._next_non_ff_byte(start=position + 1) # 'FF 00' sequence is not a marker, start over if found - if byte_ == b'\x00': + if byte_ == b"\x00": continue # this is a marker, gather return values and break out of scan - marker_code, segment_offset = byte_, position+1 + marker_code, segment_offset = byte_, position + 1 break return marker_code, segment_offset @@ -220,7 +229,7 @@ def _next_non_ff_byte(self, start): """ self._stream.seek(start) byte_ = self._read_byte() - while byte_ == b'\xFF': + while byte_ == b"\xFF": byte_ = self._read_byte() offset_of_non_ff_byte = self._stream.tell() - 1 return offset_of_non_ff_byte, byte_ @@ -233,7 +242,7 @@ def _offset_of_next_ff_byte(self, start): """ self._stream.seek(start) byte_ = self._read_byte() - while byte_ != b'\xFF': + while byte_ != b"\xFF": byte_ = self._read_byte() offset_of_ff_byte = self._stream.tell() - 1 return offset_of_ff_byte @@ -245,7 +254,7 @@ def _read_byte(self): """ byte_ = self._stream.read(1) if not byte_: # pragma: no cover - raise Exception('unexpected end of file') + raise Exception("unexpected end of file") return byte_ @@ -270,6 +279,7 @@ class _Marker(object): Base class for JFIF marker classes. Represents a marker and its segment occuring in a JPEG byte stream. """ + def __init__(self, marker_code, offset, segment_length): super(_Marker, self).__init__() self._marker_code = marker_code @@ -316,9 +326,10 @@ class _App0Marker(_Marker): """ Represents a JFIF APP0 marker segment. """ + def __init__( - self, marker_code, offset, length, density_units, x_density, - y_density): + self, marker_code, offset, length, density_units, x_density, y_density + ): super(_App0Marker, self).__init__(marker_code, offset, length) self._density_units = density_units self._x_density = x_density @@ -373,8 +384,7 @@ def from_stream(cls, stream, marker_code, offset): x_density = stream.read_short(offset, 10) y_density = stream.read_short(offset, 12) return cls( - marker_code, offset, segment_length, density_units, x_density, - y_density + marker_code, offset, segment_length, density_units, x_density, y_density ) @@ -382,6 +392,7 @@ class _App1Marker(_Marker): """ Represents a JFIF APP1 (Exif) marker segment. """ + def __init__(self, marker_code, offset, length, horz_dpi, vert_dpi): super(_App1Marker, self).__init__(marker_code, offset, length) self._horz_dpi = horz_dpi @@ -405,9 +416,7 @@ def from_stream(cls, stream, marker_code, offset): if cls._is_non_Exif_APP1_segment(stream, offset): return cls(marker_code, offset, segment_length, 72, 72) tiff = cls._tiff_from_exif_segment(stream, offset, segment_length) - return cls( - marker_code, offset, segment_length, tiff.horz_dpi, tiff.vert_dpi - ) + return cls(marker_code, offset, segment_length, tiff.horz_dpi, tiff.vert_dpi) @property def horz_dpi(self): @@ -432,9 +441,9 @@ def _is_non_Exif_APP1_segment(cls, stream, offset): Exif segment, as determined by the ``'Exif\x00\x00'`` signature at offset 2 in the segment. """ - stream.seek(offset+2) + stream.seek(offset + 2) exif_signature = stream.read(6) - return exif_signature != b'Exif\x00\x00' + return exif_signature != b"Exif\x00\x00" @classmethod def _tiff_from_exif_segment(cls, stream, offset, segment_length): @@ -443,8 +452,8 @@ def _tiff_from_exif_segment(cls, stream, offset, segment_length): *segment_length* at *offset* in *stream*. """ # wrap full segment in its own stream and feed to Tiff() - stream.seek(offset+8) - segment_bytes = stream.read(segment_length-8) + stream.seek(offset + 8) + segment_bytes = stream.read(segment_length - 8) substream = BytesIO(segment_bytes) return Tiff.from_stream(substream) @@ -453,8 +462,8 @@ class _SofMarker(_Marker): """ Represents a JFIF start of frame (SOFx) marker segment. """ - def __init__( - self, marker_code, offset, segment_length, px_width, px_height): + + def __init__(self, marker_code, offset, segment_length, px_width, px_height): super(_SofMarker, self).__init__(marker_code, offset, segment_length) self._px_width = px_width self._px_height = px_height diff --git a/docx/image/png.py b/docx/image/png.py index 4e899fa5..c2e4ae82 100644 --- a/docx/image/png.py +++ b/docx/image/png.py @@ -12,6 +12,7 @@ class Png(BaseImageHeader): """ Image header parser for PNG images """ + @property def content_type(self): """ @@ -25,7 +26,7 @@ def default_ext(self): """ Default filename extension, always 'png' for PNG images. """ - return 'png' + return "png" @classmethod def from_stream(cls, stream): @@ -48,6 +49,7 @@ class _PngParser(object): Parses a PNG image stream to extract the image properties found in its chunks. """ + def __init__(self, chunks): super(_PngParser, self).__init__() self._chunks = chunks @@ -114,6 +116,7 @@ class _Chunks(object): """ Collection of the chunks parsed from a PNG image stream """ + def __init__(self, chunk_iterable): super(_Chunks, self).__init__() self._chunks = list(chunk_iterable) @@ -135,7 +138,7 @@ def IHDR(self): match = lambda chunk: chunk.type_name == PNG_CHUNK_TYPE.IHDR # noqa IHDR = self._find_first(match) if IHDR is None: - raise InvalidImageStreamError('no IHDR chunk in PNG image') + raise InvalidImageStreamError("no IHDR chunk in PNG image") return IHDR @property @@ -161,6 +164,7 @@ class _ChunkParser(object): """ Extracts chunks from a PNG image stream """ + def __init__(self, stream_rdr): super(_ChunkParser, self).__init__() self._stream_rdr = stream_rdr @@ -195,10 +199,10 @@ def _iter_chunk_offsets(self): chunk_type = self._stream_rdr.read_str(4, chunk_offset, 4) data_offset = chunk_offset + 8 yield chunk_type, data_offset - if chunk_type == 'IEND': + if chunk_type == "IEND": break # incr offset for chunk len long, chunk type, chunk data, and CRC - chunk_offset += (4 + 4 + chunk_data_len + 4) + chunk_offset += 4 + 4 + chunk_data_len + 4 def _ChunkFactory(chunk_type, stream_rdr, offset): @@ -219,6 +223,7 @@ class _Chunk(object): Base class for specific chunk types. Also serves as the default chunk type. """ + def __init__(self, chunk_type): super(_Chunk, self).__init__() self._chunk_type = chunk_type @@ -242,6 +247,7 @@ class _IHDRChunk(_Chunk): """ IHDR chunk, contains the image dimensions """ + def __init__(self, chunk_type, px_width, px_height): super(_IHDRChunk, self).__init__(chunk_type) self._px_width = px_width @@ -270,8 +276,8 @@ class _pHYsChunk(_Chunk): """ pYHs chunk, contains the image dpi information """ - def __init__(self, chunk_type, horz_px_per_unit, vert_px_per_unit, - units_specifier): + + def __init__(self, chunk_type, horz_px_per_unit, vert_px_per_unit, units_specifier): super(_pHYsChunk, self).__init__(chunk_type) self._horz_px_per_unit = horz_px_per_unit self._vert_px_per_unit = vert_px_per_unit @@ -286,9 +292,7 @@ def from_offset(cls, chunk_type, stream_rdr, offset): horz_px_per_unit = stream_rdr.read_long(offset) vert_px_per_unit = stream_rdr.read_long(offset, 4) units_specifier = stream_rdr.read_byte(offset, 8) - return cls( - chunk_type, horz_px_per_unit, vert_px_per_unit, units_specifier - ) + return cls(chunk_type, horz_px_per_unit, vert_px_per_unit, units_specifier) @property def horz_px_per_unit(self): diff --git a/docx/image/tiff.py b/docx/image/tiff.py index c3824236..5b5e8b74 100644 --- a/docx/image/tiff.py +++ b/docx/image/tiff.py @@ -12,6 +12,7 @@ class Tiff(BaseImageHeader): Image header parser for TIFF images. Handles both big and little endian byte ordering. """ + @property def content_type(self): """ @@ -25,7 +26,7 @@ def default_ext(self): """ Default filename extension, always 'tiff' for TIFF images. """ - return 'tiff' + return "tiff" @classmethod def from_stream(cls, stream): @@ -48,6 +49,7 @@ class _TiffParser(object): Parses a TIFF image stream to extract the image properties found in its main image file directory (IFD) """ + def __init__(self, ifd_entries): super(_TiffParser, self).__init__() self._ifd_entries = ifd_entries @@ -107,7 +109,7 @@ def _detect_endian(cls, stream): """ stream.seek(0) endian_str = stream.read(2) - return BIG_ENDIAN if endian_str == b'MM' else LITTLE_ENDIAN + return BIG_ENDIAN if endian_str == b"MM" else LITTLE_ENDIAN def _dpi(self, resolution_tag): """ @@ -124,7 +126,8 @@ def _dpi(self, resolution_tag): # resolution unit defaults to inches (2) resolution_unit = ( ifd_entries[TIFF_TAG.RESOLUTION_UNIT] - if TIFF_TAG.RESOLUTION_UNIT in ifd_entries else 2 + if TIFF_TAG.RESOLUTION_UNIT in ifd_entries + else 2 ) if resolution_unit == 1: # aspect ratio only @@ -150,6 +153,7 @@ class _IfdEntries(object): Image File Directory for a TIFF image, having mapping (dict) semantics allowing "tag" values to be retrieved by tag code. """ + def __init__(self, entries): super(_IfdEntries, self).__init__() self._entries = entries @@ -189,6 +193,7 @@ class _IfdParser(object): Service object that knows how to extract directory entries from an Image File Directory (IFD) """ + def __init__(self, stream_rdr, offset): super(_IfdParser, self).__init__() self._stream_rdr = stream_rdr @@ -200,7 +205,7 @@ def iter_entries(self): directory. """ for idx in range(self._entry_count): - dir_entry_offset = self._offset + 2 + (idx*12) + dir_entry_offset = self._offset + 2 + (idx * 12) ifd_entry = _IfdEntryFactory(self._stream_rdr, dir_entry_offset) yield ifd_entry @@ -218,9 +223,9 @@ def _IfdEntryFactory(stream_rdr, offset): directory entry at *offset* in *stream_rdr*. """ ifd_entry_classes = { - TIFF_FLD.ASCII: _AsciiIfdEntry, - TIFF_FLD.SHORT: _ShortIfdEntry, - TIFF_FLD.LONG: _LongIfdEntry, + TIFF_FLD.ASCII: _AsciiIfdEntry, + TIFF_FLD.SHORT: _ShortIfdEntry, + TIFF_FLD.LONG: _LongIfdEntry, TIFF_FLD.RATIONAL: _RationalIfdEntry, } field_type = stream_rdr.read_short(offset, 2) @@ -236,6 +241,7 @@ class _IfdEntry(object): Base class for IFD entry classes. Subclasses are differentiated by value type, e.g. ASCII, long int, etc. """ + def __init__(self, tag_code, value): super(_IfdEntry, self).__init__() self._tag_code = tag_code @@ -252,9 +258,7 @@ def from_stream(cls, stream_rdr, offset): tag_code = stream_rdr.read_short(offset, 0) value_count = stream_rdr.read_long(offset, 4) value_offset = stream_rdr.read_long(offset, 8) - value = cls._parse_value( - stream_rdr, offset, value_count, value_offset - ) + value = cls._parse_value(stream_rdr, offset, value_count, value_offset) return cls(tag_code, value) @classmethod @@ -263,7 +267,7 @@ def _parse_value(cls, stream_rdr, offset, value_count, value_offset): Return the value of this field parsed from *stream_rdr* at *offset*. Intended to be overridden by subclasses. """ - return 'UNIMPLEMENTED FIELD TYPE' # pragma: no cover + return "UNIMPLEMENTED FIELD TYPE" # pragma: no cover @property def tag(self): @@ -284,6 +288,7 @@ class _AsciiIfdEntry(_IfdEntry): """ IFD entry having the form of a NULL-terminated ASCII string """ + @classmethod def _parse_value(cls, stream_rdr, offset, value_count, value_offset): """ @@ -291,13 +296,14 @@ def _parse_value(cls, stream_rdr, offset, value_count, value_offset): The length of the string, including a terminating '\x00' (NUL) character, is in *value_count*. """ - return stream_rdr.read_str(value_count-1, value_offset) + return stream_rdr.read_str(value_count - 1, value_offset) class _ShortIfdEntry(_IfdEntry): """ IFD entry expressed as a short (2-byte) integer """ + @classmethod def _parse_value(cls, stream_rdr, offset, value_count, value_offset): """ @@ -307,13 +313,14 @@ def _parse_value(cls, stream_rdr, offset, value_count, value_offset): if value_count == 1: return stream_rdr.read_short(offset, 8) else: # pragma: no cover - return 'Multi-value short integer NOT IMPLEMENTED' + return "Multi-value short integer NOT IMPLEMENTED" class _LongIfdEntry(_IfdEntry): """ IFD entry expressed as a long (4-byte) integer """ + @classmethod def _parse_value(cls, stream_rdr, offset, value_count, value_offset): """ @@ -323,13 +330,14 @@ def _parse_value(cls, stream_rdr, offset, value_count, value_offset): if value_count == 1: return stream_rdr.read_long(offset, 8) else: # pragma: no cover - return 'Multi-value long integer NOT IMPLEMENTED' + return "Multi-value long integer NOT IMPLEMENTED" class _RationalIfdEntry(_IfdEntry): """ IFD entry expressed as a numerator, denominator pair """ + @classmethod def _parse_value(cls, stream_rdr, offset, value_count, value_offset): """ @@ -342,4 +350,4 @@ def _parse_value(cls, stream_rdr, offset, value_count, value_offset): denominator = stream_rdr.read_long(value_offset, 4) return numerator / denominator else: # pragma: no cover - return 'Multi-value Rational NOT IMPLEMENTED' + return "Multi-value Rational NOT IMPLEMENTED" diff --git a/docx/opc/constants.py b/docx/opc/constants.py index 1bcf16f6..87a64998 100644 --- a/docx/opc/constants.py +++ b/docx/opc/constants.py @@ -10,652 +10,550 @@ class CONTENT_TYPE(object): """ Content type URIs (like MIME-types) that specify a part's format """ - BMP = ( - 'image/bmp' - ) - DML_CHART = ( - 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml' - ) + + BMP = "image/bmp" + DML_CHART = "application/vnd.openxmlformats-officedocument.drawingml.chart+xml" DML_CHARTSHAPES = ( - 'application/vnd.openxmlformats-officedocument.drawingml.chartshapes' - '+xml' + "application/vnd.openxmlformats-officedocument.drawingml.chartshapes" "+xml" ) DML_DIAGRAM_COLORS = ( - 'application/vnd.openxmlformats-officedocument.drawingml.diagramColo' - 'rs+xml' + "application/vnd.openxmlformats-officedocument.drawingml.diagramColo" "rs+xml" ) DML_DIAGRAM_DATA = ( - 'application/vnd.openxmlformats-officedocument.drawingml.diagramData' - '+xml' + "application/vnd.openxmlformats-officedocument.drawingml.diagramData" "+xml" ) DML_DIAGRAM_LAYOUT = ( - 'application/vnd.openxmlformats-officedocument.drawingml.diagramLayo' - 'ut+xml' + "application/vnd.openxmlformats-officedocument.drawingml.diagramLayo" "ut+xml" ) DML_DIAGRAM_STYLE = ( - 'application/vnd.openxmlformats-officedocument.drawingml.diagramStyl' - 'e+xml' - ) - GIF = ( - 'image/gif' - ) - JPEG = ( - 'image/jpeg' - ) - MS_PHOTO = ( - 'image/vnd.ms-photo' + "application/vnd.openxmlformats-officedocument.drawingml.diagramStyl" "e+xml" ) + GIF = "image/gif" + JPEG = "image/jpeg" + MS_PHOTO = "image/vnd.ms-photo" OFC_CUSTOM_PROPERTIES = ( - 'application/vnd.openxmlformats-officedocument.custom-properties+xml' + "application/vnd.openxmlformats-officedocument.custom-properties+xml" ) OFC_CUSTOM_XML_PROPERTIES = ( - 'application/vnd.openxmlformats-officedocument.customXmlProperties+x' - 'ml' - ) - OFC_DRAWING = ( - 'application/vnd.openxmlformats-officedocument.drawing+xml' + "application/vnd.openxmlformats-officedocument.customXmlProperties+x" "ml" ) + OFC_DRAWING = "application/vnd.openxmlformats-officedocument.drawing+xml" OFC_EXTENDED_PROPERTIES = ( - 'application/vnd.openxmlformats-officedocument.extended-properties+x' - 'ml' - ) - OFC_OLE_OBJECT = ( - 'application/vnd.openxmlformats-officedocument.oleObject' - ) - OFC_PACKAGE = ( - 'application/vnd.openxmlformats-officedocument.package' - ) - OFC_THEME = ( - 'application/vnd.openxmlformats-officedocument.theme+xml' + "application/vnd.openxmlformats-officedocument.extended-properties+x" "ml" ) + OFC_OLE_OBJECT = "application/vnd.openxmlformats-officedocument.oleObject" + OFC_PACKAGE = "application/vnd.openxmlformats-officedocument.package" + OFC_THEME = "application/vnd.openxmlformats-officedocument.theme+xml" OFC_THEME_OVERRIDE = ( - 'application/vnd.openxmlformats-officedocument.themeOverride+xml' - ) - OFC_VML_DRAWING = ( - 'application/vnd.openxmlformats-officedocument.vmlDrawing' - ) - OPC_CORE_PROPERTIES = ( - 'application/vnd.openxmlformats-package.core-properties+xml' + "application/vnd.openxmlformats-officedocument.themeOverride+xml" ) + OFC_VML_DRAWING = "application/vnd.openxmlformats-officedocument.vmlDrawing" + OPC_CORE_PROPERTIES = "application/vnd.openxmlformats-package.core-properties+xml" OPC_CUSTOM_PROPERTIES = ( - 'application/vnd.openxmlformats-officedocument.custom-properties+xml' + "application/vnd.openxmlformats-officedocument.custom-properties+xml" ) OPC_DIGITAL_SIGNATURE_CERTIFICATE = ( - 'application/vnd.openxmlformats-package.digital-signature-certificat' - 'e' + "application/vnd.openxmlformats-package.digital-signature-certificat" "e" ) OPC_DIGITAL_SIGNATURE_ORIGIN = ( - 'application/vnd.openxmlformats-package.digital-signature-origin' + "application/vnd.openxmlformats-package.digital-signature-origin" ) OPC_DIGITAL_SIGNATURE_XMLSIGNATURE = ( - 'application/vnd.openxmlformats-package.digital-signature-xmlsignatu' - 're+xml' - ) - OPC_RELATIONSHIPS = ( - 'application/vnd.openxmlformats-package.relationships+xml' + "application/vnd.openxmlformats-package.digital-signature-xmlsignatu" "re+xml" ) + OPC_RELATIONSHIPS = "application/vnd.openxmlformats-package.relationships+xml" PML_COMMENTS = ( - 'application/vnd.openxmlformats-officedocument.presentationml.commen' - 'ts+xml' + "application/vnd.openxmlformats-officedocument.presentationml.commen" "ts+xml" ) PML_COMMENT_AUTHORS = ( - 'application/vnd.openxmlformats-officedocument.presentationml.commen' - 'tAuthors+xml' + "application/vnd.openxmlformats-officedocument.presentationml.commen" + "tAuthors+xml" ) PML_HANDOUT_MASTER = ( - 'application/vnd.openxmlformats-officedocument.presentationml.handou' - 'tMaster+xml' + "application/vnd.openxmlformats-officedocument.presentationml.handou" + "tMaster+xml" ) PML_NOTES_MASTER = ( - 'application/vnd.openxmlformats-officedocument.presentationml.notesM' - 'aster+xml' + "application/vnd.openxmlformats-officedocument.presentationml.notesM" + "aster+xml" ) PML_NOTES_SLIDE = ( - 'application/vnd.openxmlformats-officedocument.presentationml.notesS' - 'lide+xml' + "application/vnd.openxmlformats-officedocument.presentationml.notesS" "lide+xml" ) PML_PRESENTATION_MAIN = ( - 'application/vnd.openxmlformats-officedocument.presentationml.presen' - 'tation.main+xml' + "application/vnd.openxmlformats-officedocument.presentationml.presen" + "tation.main+xml" ) PML_PRES_PROPS = ( - 'application/vnd.openxmlformats-officedocument.presentationml.presPr' - 'ops+xml' + "application/vnd.openxmlformats-officedocument.presentationml.presPr" "ops+xml" ) PML_PRINTER_SETTINGS = ( - 'application/vnd.openxmlformats-officedocument.presentationml.printe' - 'rSettings' + "application/vnd.openxmlformats-officedocument.presentationml.printe" + "rSettings" ) PML_SLIDE = ( - 'application/vnd.openxmlformats-officedocument.presentationml.slide+' - 'xml' + "application/vnd.openxmlformats-officedocument.presentationml.slide+" "xml" ) PML_SLIDESHOW_MAIN = ( - 'application/vnd.openxmlformats-officedocument.presentationml.slides' - 'how.main+xml' + "application/vnd.openxmlformats-officedocument.presentationml.slides" + "how.main+xml" ) PML_SLIDE_LAYOUT = ( - 'application/vnd.openxmlformats-officedocument.presentationml.slideL' - 'ayout+xml' + "application/vnd.openxmlformats-officedocument.presentationml.slideL" + "ayout+xml" ) PML_SLIDE_MASTER = ( - 'application/vnd.openxmlformats-officedocument.presentationml.slideM' - 'aster+xml' + "application/vnd.openxmlformats-officedocument.presentationml.slideM" + "aster+xml" ) PML_SLIDE_UPDATE_INFO = ( - 'application/vnd.openxmlformats-officedocument.presentationml.slideU' - 'pdateInfo+xml' + "application/vnd.openxmlformats-officedocument.presentationml.slideU" + "pdateInfo+xml" ) PML_TABLE_STYLES = ( - 'application/vnd.openxmlformats-officedocument.presentationml.tableS' - 'tyles+xml' + "application/vnd.openxmlformats-officedocument.presentationml.tableS" + "tyles+xml" ) PML_TAGS = ( - 'application/vnd.openxmlformats-officedocument.presentationml.tags+x' - 'ml' + "application/vnd.openxmlformats-officedocument.presentationml.tags+x" "ml" ) PML_TEMPLATE_MAIN = ( - 'application/vnd.openxmlformats-officedocument.presentationml.templa' - 'te.main+xml' + "application/vnd.openxmlformats-officedocument.presentationml.templa" + "te.main+xml" ) PML_VIEW_PROPS = ( - 'application/vnd.openxmlformats-officedocument.presentationml.viewPr' - 'ops+xml' - ) - PNG = ( - 'image/png' + "application/vnd.openxmlformats-officedocument.presentationml.viewPr" "ops+xml" ) + PNG = "image/png" SML_CALC_CHAIN = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.calcCha' - 'in+xml' + "application/vnd.openxmlformats-officedocument.spreadsheetml.calcCha" "in+xml" ) SML_CHARTSHEET = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.chartsh' - 'eet+xml' + "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsh" "eet+xml" ) SML_COMMENTS = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.comment' - 's+xml' + "application/vnd.openxmlformats-officedocument.spreadsheetml.comment" "s+xml" ) SML_CONNECTIONS = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.connect' - 'ions+xml' + "application/vnd.openxmlformats-officedocument.spreadsheetml.connect" "ions+xml" ) SML_CUSTOM_PROPERTY = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.customP' - 'roperty' + "application/vnd.openxmlformats-officedocument.spreadsheetml.customP" "roperty" ) SML_DIALOGSHEET = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.dialogs' - 'heet+xml' + "application/vnd.openxmlformats-officedocument.spreadsheetml.dialogs" "heet+xml" ) SML_EXTERNAL_LINK = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.externa' - 'lLink+xml' + "application/vnd.openxmlformats-officedocument.spreadsheetml.externa" + "lLink+xml" ) SML_PIVOT_CACHE_DEFINITION = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCa' - 'cheDefinition+xml' + "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCa" + "cheDefinition+xml" ) SML_PIVOT_CACHE_RECORDS = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCa' - 'cheRecords+xml' + "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCa" + "cheRecords+xml" ) SML_PIVOT_TABLE = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTa' - 'ble+xml' + "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTa" "ble+xml" ) SML_PRINTER_SETTINGS = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.printer' - 'Settings' + "application/vnd.openxmlformats-officedocument.spreadsheetml.printer" "Settings" ) SML_QUERY_TABLE = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.queryTa' - 'ble+xml' + "application/vnd.openxmlformats-officedocument.spreadsheetml.queryTa" "ble+xml" ) SML_REVISION_HEADERS = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.revisio' - 'nHeaders+xml' + "application/vnd.openxmlformats-officedocument.spreadsheetml.revisio" + "nHeaders+xml" ) SML_REVISION_LOG = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.revisio' - 'nLog+xml' + "application/vnd.openxmlformats-officedocument.spreadsheetml.revisio" "nLog+xml" ) SML_SHARED_STRINGS = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedS' - 'trings+xml' - ) - SML_SHEET = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' + "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedS" + "trings+xml" ) + SML_SHEET = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" SML_SHEET_MAIN = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.m' - 'ain+xml' + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.m" "ain+xml" ) SML_SHEET_METADATA = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMe' - 'tadata+xml' + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMe" + "tadata+xml" ) SML_STYLES = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.styles+' - 'xml' + "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+" "xml" ) SML_TABLE = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.table+x' - 'ml' + "application/vnd.openxmlformats-officedocument.spreadsheetml.table+x" "ml" ) SML_TABLE_SINGLE_CELLS = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.tableSi' - 'ngleCells+xml' + "application/vnd.openxmlformats-officedocument.spreadsheetml.tableSi" + "ngleCells+xml" ) SML_TEMPLATE_MAIN = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.templat' - 'e.main+xml' + "application/vnd.openxmlformats-officedocument.spreadsheetml.templat" + "e.main+xml" ) SML_USER_NAMES = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.userNam' - 'es+xml' + "application/vnd.openxmlformats-officedocument.spreadsheetml.userNam" "es+xml" ) SML_VOLATILE_DEPENDENCIES = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.volatil' - 'eDependencies+xml' + "application/vnd.openxmlformats-officedocument.spreadsheetml.volatil" + "eDependencies+xml" ) SML_WORKSHEET = ( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.workshe' - 'et+xml' - ) - TIFF = ( - 'image/tiff' + "application/vnd.openxmlformats-officedocument.spreadsheetml.workshe" "et+xml" ) + TIFF = "image/tiff" WML_COMMENTS = ( - 'application/vnd.openxmlformats-officedocument.wordprocessingml.comm' - 'ents+xml' + "application/vnd.openxmlformats-officedocument.wordprocessingml.comm" "ents+xml" ) WML_DOCUMENT = ( - 'application/vnd.openxmlformats-officedocument.wordprocessingml.docu' - 'ment' + "application/vnd.openxmlformats-officedocument.wordprocessingml.docu" "ment" ) WML_DOCUMENT_GLOSSARY = ( - 'application/vnd.openxmlformats-officedocument.wordprocessingml.docu' - 'ment.glossary+xml' + "application/vnd.openxmlformats-officedocument.wordprocessingml.docu" + "ment.glossary+xml" ) WML_DOCUMENT_MAIN = ( - 'application/vnd.openxmlformats-officedocument.wordprocessingml.docu' - 'ment.main+xml' + "application/vnd.openxmlformats-officedocument.wordprocessingml.docu" + "ment.main+xml" ) WML_ENDNOTES = ( - 'application/vnd.openxmlformats-officedocument.wordprocessingml.endn' - 'otes+xml' + "application/vnd.openxmlformats-officedocument.wordprocessingml.endn" "otes+xml" ) WML_FONT_TABLE = ( - 'application/vnd.openxmlformats-officedocument.wordprocessingml.font' - 'Table+xml' + "application/vnd.openxmlformats-officedocument.wordprocessingml.font" + "Table+xml" ) WML_FOOTER = ( - 'application/vnd.openxmlformats-officedocument.wordprocessingml.foot' - 'er+xml' + "application/vnd.openxmlformats-officedocument.wordprocessingml.foot" "er+xml" ) WML_FOOTNOTES = ( - 'application/vnd.openxmlformats-officedocument.wordprocessingml.foot' - 'notes+xml' + "application/vnd.openxmlformats-officedocument.wordprocessingml.foot" + "notes+xml" ) WML_HEADER = ( - 'application/vnd.openxmlformats-officedocument.wordprocessingml.head' - 'er+xml' + "application/vnd.openxmlformats-officedocument.wordprocessingml.head" "er+xml" ) WML_NUMBERING = ( - 'application/vnd.openxmlformats-officedocument.wordprocessingml.numb' - 'ering+xml' + "application/vnd.openxmlformats-officedocument.wordprocessingml.numb" + "ering+xml" ) WML_PRINTER_SETTINGS = ( - 'application/vnd.openxmlformats-officedocument.wordprocessingml.prin' - 'terSettings' + "application/vnd.openxmlformats-officedocument.wordprocessingml.prin" + "terSettings" ) WML_SETTINGS = ( - 'application/vnd.openxmlformats-officedocument.wordprocessingml.sett' - 'ings+xml' + "application/vnd.openxmlformats-officedocument.wordprocessingml.sett" "ings+xml" ) WML_STYLES = ( - 'application/vnd.openxmlformats-officedocument.wordprocessingml.styl' - 'es+xml' + "application/vnd.openxmlformats-officedocument.wordprocessingml.styl" "es+xml" ) WML_WEB_SETTINGS = ( - 'application/vnd.openxmlformats-officedocument.wordprocessingml.webS' - 'ettings+xml' - ) - XML = ( - 'application/xml' - ) - X_EMF = ( - 'image/x-emf' - ) - X_FONTDATA = ( - 'application/x-fontdata' - ) - X_FONT_TTF = ( - 'application/x-font-ttf' - ) - X_WMF = ( - 'image/x-wmf' - ) + "application/vnd.openxmlformats-officedocument.wordprocessingml.webS" + "ettings+xml" + ) + XML = "application/xml" + X_EMF = "image/x-emf" + X_FONTDATA = "application/x-fontdata" + X_FONT_TTF = "application/x-font-ttf" + X_WMF = "image/x-wmf" class NAMESPACE(object): """Constant values for OPC XML namespaces""" + DML_WORDPROCESSING_DRAWING = ( - 'http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDraw' - 'ing' + "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDraw" "ing" ) OFC_RELATIONSHIPS = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - ) - OPC_RELATIONSHIPS = ( - 'http://schemas.openxmlformats.org/package/2006/relationships' - ) - OPC_CONTENT_TYPES = ( - 'http://schemas.openxmlformats.org/package/2006/content-types' - ) - WML_MAIN = ( - 'http://schemas.openxmlformats.org/wordprocessingml/2006/main' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" ) + OPC_RELATIONSHIPS = "http://schemas.openxmlformats.org/package/2006/relationships" + OPC_CONTENT_TYPES = "http://schemas.openxmlformats.org/package/2006/content-types" + WML_MAIN = "http://schemas.openxmlformats.org/wordprocessingml/2006/main" class RELATIONSHIP_TARGET_MODE(object): """Open XML relationship target modes""" - EXTERNAL = 'External' - INTERNAL = 'Internal' + + EXTERNAL = "External" + INTERNAL = "Internal" class RELATIONSHIP_TYPE(object): AUDIO = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/audio' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/audio" ) A_F_CHUNK = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/aFChunk' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/aFChunk" ) CALC_CHAIN = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/calcChain' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/calcChain" ) CERTIFICATE = ( - 'http://schemas.openxmlformats.org/package/2006/relationships/digita' - 'l-signature/certificate' + "http://schemas.openxmlformats.org/package/2006/relationships/digita" + "l-signature/certificate" ) CHART = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/chart' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/chart" ) CHARTSHEET = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/chartsheet' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/chartsheet" ) CHART_USER_SHAPES = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/chartUserShapes' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/chartUserShapes" ) COMMENTS = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/comments' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/comments" ) COMMENT_AUTHORS = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/commentAuthors' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/commentAuthors" ) CONNECTIONS = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/connections' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/connections" ) CONTROL = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/control' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/control" ) CORE_PROPERTIES = ( - 'http://schemas.openxmlformats.org/package/2006/relationships/metada' - 'ta/core-properties' + "http://schemas.openxmlformats.org/package/2006/relationships/metada" + "ta/core-properties" ) CUSTOM_PROPERTIES = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/custom-properties' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/custom-properties" ) CUSTOM_PROPERTY = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/customProperty' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/customProperty" ) CUSTOM_XML = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/customXml' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/customXml" ) CUSTOM_XML_PROPS = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/customXmlProps' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/customXmlProps" ) DIAGRAM_COLORS = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/diagramColors' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/diagramColors" ) DIAGRAM_DATA = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/diagramData' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/diagramData" ) DIAGRAM_LAYOUT = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/diagramLayout' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/diagramLayout" ) DIAGRAM_QUICK_STYLE = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/diagramQuickStyle' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/diagramQuickStyle" ) DIALOGSHEET = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/dialogsheet' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/dialogsheet" ) DRAWING = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/drawing' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/drawing" ) ENDNOTES = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/endnotes' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/endnotes" ) EXTENDED_PROPERTIES = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/extended-properties' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/extended-properties" ) EXTERNAL_LINK = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/externalLink' - ) - FONT = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/font' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/externalLink" ) + FONT = "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/font" FONT_TABLE = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/fontTable' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/fontTable" ) FOOTER = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/footer' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/footer" ) FOOTNOTES = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/footnotes' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/footnotes" ) GLOSSARY_DOCUMENT = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/glossaryDocument' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/glossaryDocument" ) HANDOUT_MASTER = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/handoutMaster' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/handoutMaster" ) HEADER = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/header' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/header" ) HYPERLINK = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/hyperlink' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/hyperlink" ) IMAGE = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/image' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/image" ) NOTES_MASTER = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/notesMaster' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/notesMaster" ) NOTES_SLIDE = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/notesSlide' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/notesSlide" ) NUMBERING = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/numbering' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/numbering" ) OFFICE_DOCUMENT = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/officeDocument' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/officeDocument" ) OLE_OBJECT = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/oleObject' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/oleObject" ) ORIGIN = ( - 'http://schemas.openxmlformats.org/package/2006/relationships/digita' - 'l-signature/origin' + "http://schemas.openxmlformats.org/package/2006/relationships/digita" + "l-signature/origin" ) PACKAGE = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/package' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/package" ) PIVOT_CACHE_DEFINITION = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/pivotCacheDefinition' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/pivotCacheDefinition" ) PIVOT_CACHE_RECORDS = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/spreadsheetml/pivotCacheRecords' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/spreadsheetml/pivotCacheRecords" ) PIVOT_TABLE = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/pivotTable' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/pivotTable" ) PRES_PROPS = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/presProps' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/presProps" ) PRINTER_SETTINGS = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/printerSettings' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/printerSettings" ) QUERY_TABLE = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/queryTable' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/queryTable" ) REVISION_HEADERS = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/revisionHeaders' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/revisionHeaders" ) REVISION_LOG = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/revisionLog' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/revisionLog" ) SETTINGS = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/settings' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/settings" ) SHARED_STRINGS = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/sharedStrings' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/sharedStrings" ) SHEET_METADATA = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/sheetMetadata' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/sheetMetadata" ) SIGNATURE = ( - 'http://schemas.openxmlformats.org/package/2006/relationships/digita' - 'l-signature/signature' + "http://schemas.openxmlformats.org/package/2006/relationships/digita" + "l-signature/signature" ) SLIDE = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/slide' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/slide" ) SLIDE_LAYOUT = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/slideLayout' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/slideLayout" ) SLIDE_MASTER = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/slideMaster' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/slideMaster" ) SLIDE_UPDATE_INFO = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/slideUpdateInfo' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/slideUpdateInfo" ) STYLES = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/styles' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/styles" ) TABLE = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/table' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/table" ) TABLE_SINGLE_CELLS = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/tableSingleCells' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/tableSingleCells" ) TABLE_STYLES = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/tableStyles' - ) - TAGS = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/tags' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/tableStyles" ) + TAGS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/tags" THEME = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/theme' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/theme" ) THEME_OVERRIDE = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/themeOverride' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/themeOverride" ) THUMBNAIL = ( - 'http://schemas.openxmlformats.org/package/2006/relationships/metada' - 'ta/thumbnail' + "http://schemas.openxmlformats.org/package/2006/relationships/metada" + "ta/thumbnail" ) USERNAMES = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/usernames' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/usernames" ) VIDEO = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/video' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/video" ) VIEW_PROPS = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/viewProps' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/viewProps" ) VML_DRAWING = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/vmlDrawing' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/vmlDrawing" ) VOLATILE_DEPENDENCIES = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/volatileDependencies' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/volatileDependencies" ) WEB_SETTINGS = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/webSettings' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/webSettings" ) WORKSHEET_SOURCE = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/worksheetSource' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/worksheetSource" ) XML_MAPS = ( - 'http://schemas.openxmlformats.org/officeDocument/2006/relationships' - '/xmlMaps' + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/xmlMaps" ) diff --git a/docx/opc/oxml.py b/docx/opc/oxml.py index 494b31dc..432dcf9f 100644 --- a/docx/opc/oxml.py +++ b/docx/opc/oxml.py @@ -20,9 +20,9 @@ oxml_parser.set_element_class_lookup(element_class_lookup) nsmap = { - 'ct': NS.OPC_CONTENT_TYPES, - 'pr': NS.OPC_RELATIONSHIPS, - 'r': NS.OFC_RELATIONSHIPS, + "ct": NS.OPC_CONTENT_TYPES, + "pr": NS.OPC_RELATIONSHIPS, + "r": NS.OFC_RELATIONSHIPS, } @@ -30,6 +30,7 @@ # functions # =========================================================================== + def parse_xml(text): """ ``etree.fromstring()`` replacement that uses oxml parser @@ -43,9 +44,9 @@ def qn(tag): prefixed tag name into a Clark-notation qualified tag name for lxml. For example, ``qn('p:cSld')`` returns ``'{http://schemas.../main}cSld'``. """ - prefix, tagroot = tag.split(':') + prefix, tagroot = tag.split(":") uri = nsmap[prefix] - return '{%s}%s' % (uri, tagroot) + return "{%s}%s" % (uri, tagroot) def serialize_part_xml(part_elm): @@ -54,7 +55,7 @@ def serialize_part_xml(part_elm): part. That is to say, no insignificant whitespace added for readability, and an appropriate XML declaration added with UTF-8 encoding specified. """ - return etree.tostring(part_elm, encoding='UTF-8', standalone=True) + return etree.tostring(part_elm, encoding="UTF-8", standalone=True) def serialize_for_reading(element): @@ -62,18 +63,20 @@ def serialize_for_reading(element): Serialize *element* to human-readable XML suitable for tests. No XML declaration. """ - return etree.tostring(element, encoding='unicode', pretty_print=True) + return etree.tostring(element, encoding="unicode", pretty_print=True) # =========================================================================== # Custom element classes # =========================================================================== + class BaseOxmlElement(etree.ElementBase): """ Base class for all custom element classes, to add standardized behavior to all classes in one place. """ + @property def xml(self): """ @@ -89,13 +92,14 @@ class CT_Default(BaseOxmlElement): ```` element, specifying the default content type to be applied to a part with the specified extension. """ + @property def content_type(self): """ String held in the ``ContentType`` attribute of this ```` element. """ - return self.get('ContentType') + return self.get("ContentType") @property def extension(self): @@ -103,7 +107,7 @@ def extension(self): String held in the ``Extension`` attribute of this ```` element. """ - return self.get('Extension') + return self.get("Extension") @staticmethod def new(ext, content_type): @@ -111,10 +115,10 @@ def new(ext, content_type): Return a new ```` element with attributes set to parameter values. """ - xml = '' % nsmap['ct'] + xml = '' % nsmap["ct"] default = parse_xml(xml) - default.set('Extension', ext) - default.set('ContentType', content_type) + default.set("Extension", ext) + default.set("ContentType", content_type) return default @@ -123,13 +127,14 @@ class CT_Override(BaseOxmlElement): ```` element, specifying the content type to be applied for a part with the specified partname. """ + @property def content_type(self): """ String held in the ``ContentType`` attribute of this ```` element. """ - return self.get('ContentType') + return self.get("ContentType") @staticmethod def new(partname, content_type): @@ -137,10 +142,10 @@ def new(partname, content_type): Return a new ```` element with attributes set to parameter values. """ - xml = '' % nsmap['ct'] + xml = '' % nsmap["ct"] override = parse_xml(xml) - override.set('PartName', partname) - override.set('ContentType', content_type) + override.set("PartName", partname) + override.set("ContentType", content_type) return override @property @@ -149,7 +154,7 @@ def partname(self): String held in the ``PartName`` attribute of this ```` element. """ - return self.get('PartName') + return self.get("PartName") class CT_Relationship(BaseOxmlElement): @@ -157,18 +162,19 @@ class CT_Relationship(BaseOxmlElement): ```` element, representing a single relationship from a source to a target part. """ + @staticmethod def new(rId, reltype, target, target_mode=RTM.INTERNAL): """ Return a new ```` element. """ - xml = '' % nsmap['pr'] + xml = '' % nsmap["pr"] relationship = parse_xml(xml) - relationship.set('Id', rId) - relationship.set('Type', reltype) - relationship.set('Target', target) + relationship.set("Id", rId) + relationship.set("Type", reltype) + relationship.set("Target", target) if target_mode == RTM.EXTERNAL: - relationship.set('TargetMode', RTM.EXTERNAL) + relationship.set("TargetMode", RTM.EXTERNAL) return relationship @property @@ -177,7 +183,7 @@ def rId(self): String held in the ``Id`` attribute of this ```` element. """ - return self.get('Id') + return self.get("Id") @property def reltype(self): @@ -185,7 +191,7 @@ def reltype(self): String held in the ``Type`` attribute of this ```` element. """ - return self.get('Type') + return self.get("Type") @property def target_ref(self): @@ -193,7 +199,7 @@ def target_ref(self): String held in the ``Target`` attribute of this ```` element. """ - return self.get('Target') + return self.get("Target") @property def target_mode(self): @@ -202,13 +208,14 @@ def target_mode(self): ```` element, either ``Internal`` or ``External``. Defaults to ``Internal``. """ - return self.get('TargetMode', RTM.INTERNAL) + return self.get("TargetMode", RTM.INTERNAL) class CT_Relationships(BaseOxmlElement): """ ```` element, the root element in a .rels file. """ + def add_rel(self, rId, reltype, target, is_external=False): """ Add a child ```` element with attributes set according @@ -223,7 +230,7 @@ def new(): """ Return a new ```` element. """ - xml = '' % nsmap['pr'] + xml = '' % nsmap["pr"] relationships = parse_xml(xml) return relationships @@ -232,7 +239,7 @@ def Relationship_lst(self): """ Return a list containing all the ```` child elements. """ - return self.findall(qn('pr:Relationship')) + return self.findall(qn("pr:Relationship")) @property def xml(self): @@ -248,6 +255,7 @@ class CT_Types(BaseOxmlElement): ```` element, the container element for Default and Override elements in [Content_Types].xml. """ + def add_default(self, ext, content_type): """ Add a child ```` element with attributes set to parameter @@ -266,27 +274,27 @@ def add_override(self, partname, content_type): @property def defaults(self): - return self.findall(qn('ct:Default')) + return self.findall(qn("ct:Default")) @staticmethod def new(): """ Return a new ```` element. """ - xml = '' % nsmap['ct'] + xml = '' % nsmap["ct"] types = parse_xml(xml) return types @property def overrides(self): - return self.findall(qn('ct:Override')) + return self.findall(qn("ct:Override")) -ct_namespace = element_class_lookup.get_namespace(nsmap['ct']) -ct_namespace['Default'] = CT_Default -ct_namespace['Override'] = CT_Override -ct_namespace['Types'] = CT_Types +ct_namespace = element_class_lookup.get_namespace(nsmap["ct"]) +ct_namespace["Default"] = CT_Default +ct_namespace["Override"] = CT_Override +ct_namespace["Types"] = CT_Types -pr_namespace = element_class_lookup.get_namespace(nsmap['pr']) -pr_namespace['Relationship'] = CT_Relationship -pr_namespace['Relationships'] = CT_Relationships +pr_namespace = element_class_lookup.get_namespace(nsmap["pr"]) +pr_namespace["Relationship"] = CT_Relationship +pr_namespace["Relationships"] = CT_Relationships diff --git a/docx/opc/parts/coreprops.py b/docx/opc/parts/coreprops.py index 3c692fb9..7e5b8c17 100644 --- a/docx/opc/parts/coreprops.py +++ b/docx/opc/parts/coreprops.py @@ -4,9 +4,7 @@ Core properties part, corresponds to ``/docProps/core.xml`` part in package. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals from datetime import datetime @@ -22,6 +20,7 @@ class CorePropertiesPart(XmlPart): Corresponds to part named ``/docProps/core.xml``, containing the core document properties for this document package. """ + @classmethod def default(cls, package): """ @@ -30,8 +29,8 @@ def default(cls, package): """ core_properties_part = cls._new(package) core_properties = core_properties_part.core_properties - core_properties.title = 'Word Document' - core_properties.last_modified_by = 'python-docx' + core_properties.title = "Word Document" + core_properties.last_modified_by = "python-docx" core_properties.revision = 1 core_properties.modified = datetime.utcnow() return core_properties_part @@ -46,9 +45,7 @@ def core_properties(self): @classmethod def _new(cls, package): - partname = PackURI('/docProps/core.xml') + partname = PackURI("/docProps/core.xml") content_type = CT.OPC_CORE_PROPERTIES coreProperties = CT_CoreProperties.new() - return CorePropertiesPart( - partname, content_type, coreProperties, package - ) + return CorePropertiesPart(partname, content_type, coreProperties, package) diff --git a/docx/opc/phys_pkg.py b/docx/opc/phys_pkg.py index c86a5199..6d68198d 100644 --- a/docx/opc/phys_pkg.py +++ b/docx/opc/phys_pkg.py @@ -19,6 +19,7 @@ class PhysPkgReader(object): """ Factory for physical package reader objects. """ + def __new__(cls, pkg_file): # if *pkg_file* is a string, treat it as a path if is_string(pkg_file): @@ -27,9 +28,7 @@ def __new__(cls, pkg_file): elif is_zipfile(pkg_file): reader_cls = _ZipPkgReader else: - raise PackageNotFoundError( - "Package not found at '%s'" % pkg_file - ) + raise PackageNotFoundError("Package not found at '%s'" % pkg_file) else: # assume it's a stream and pass it to Zip reader to sort out reader_cls = _ZipPkgReader @@ -40,6 +39,7 @@ class PhysPkgWriter(object): """ Factory for physical package writer objects. """ + def __new__(cls, pkg_file): return super(PhysPkgWriter, cls).__new__(_ZipPkgWriter) @@ -49,6 +49,7 @@ class _DirPkgReader(PhysPkgReader): Implements |PhysPkgReader| interface for an OPC package extracted into a directory. """ + def __init__(self, path): """ *path* is the path to a directory containing an expanded package. @@ -62,7 +63,7 @@ def blob_for(self, pack_uri): directory. """ path = os.path.join(self._path, pack_uri.membername) - with open(path, 'rb') as f: + with open(path, "rb") as f: blob = f.read() return blob @@ -96,9 +97,10 @@ class _ZipPkgReader(PhysPkgReader): """ Implements |PhysPkgReader| interface for a zip file OPC package. """ + def __init__(self, pkg_file): super(_ZipPkgReader, self).__init__() - self._zipf = ZipFile(pkg_file, 'r') + self._zipf = ZipFile(pkg_file, "r") def blob_for(self, pack_uri): """ @@ -136,9 +138,10 @@ class _ZipPkgWriter(PhysPkgWriter): """ Implements |PhysPkgWriter| interface for a zip file OPC package. """ + def __init__(self, pkg_file): super(_ZipPkgWriter, self).__init__() - self._zipf = ZipFile(pkg_file, 'w', compression=ZIP_DEFLATED) + self._zipf = ZipFile(pkg_file, "w", compression=ZIP_DEFLATED) def close(self): """ diff --git a/docx/opc/pkgreader.py b/docx/opc/pkgreader.py index ae80b358..b5180192 100644 --- a/docx/opc/pkgreader.py +++ b/docx/opc/pkgreader.py @@ -19,6 +19,7 @@ class PackageReader(object): Provides access to the contents of a zip-format OPC package via its :attr:`serialized_parts` and :attr:`pkg_srels` attributes. """ + def __init__(self, content_types, pkg_srels, sparts): super(PackageReader, self).__init__() self._pkg_srels = pkg_srels @@ -68,9 +69,7 @@ def _load_serialized_parts(phys_reader, pkg_srels, content_types): part_walker = PackageReader._walk_phys_parts(phys_reader, pkg_srels) for partname, blob, reltype, srels in part_walker: content_type = content_types[partname] - spart = _SerializedPart( - partname, content_type, reltype, blob, srels - ) + spart = _SerializedPart(partname, content_type, reltype, blob, srels) sparts.append(spart) return tuple(sparts) @@ -81,8 +80,7 @@ def _srels_for(phys_reader, source_uri): relationships for source identified by *source_uri*. """ rels_xml = phys_reader.rels_xml_for(source_uri) - return _SerializedRelationships.load_from_xml( - source_uri.baseURI, rels_xml) + return _SerializedRelationships.load_from_xml(source_uri.baseURI, rels_xml) @staticmethod def _walk_phys_parts(phys_reader, srels, visited_partnames=None): @@ -116,6 +114,7 @@ class _ContentTypeMap(object): Value type providing dictionary semantics for looking up content type by part name, e.g. ``content_type = cti['/ppt/presentation.xml']``. """ + def __init__(self): super(_ContentTypeMap, self).__init__() self._overrides = CaseInsensitiveDict() @@ -169,6 +168,7 @@ class _SerializedPart(object): Value object for an OPC package part. Provides access to the partname, content type, blob, and serialized relationships for the part. """ + def __init__(self, partname, content_type, reltype, blob, srels): super(_SerializedPart, self).__init__() self._partname = partname @@ -207,6 +207,7 @@ class _SerializedRelationship(object): Serialized, in this case, means any target part is referred to via its partname rather than a direct link to an in-memory |Part| object. """ + def __init__(self, baseURI, rel_elm): super(_SerializedRelationship, self).__init__() self._baseURI = baseURI @@ -260,13 +261,14 @@ def target_partname(self): Use :attr:`target_mode` to check before referencing. """ if self.is_external: - msg = ('target_partname attribute on Relationship is undefined w' - 'here TargetMode == "External"') + msg = ( + "target_partname attribute on Relationship is undefined w" + 'here TargetMode == "External"' + ) raise ValueError(msg) # lazy-load _target_partname attribute - if not hasattr(self, '_target_partname'): - self._target_partname = PackURI.from_rel_ref(self._baseURI, - self.target_ref) + if not hasattr(self, "_target_partname"): + self._target_partname = PackURI.from_rel_ref(self._baseURI, self.target_ref) return self._target_partname @@ -275,6 +277,7 @@ class _SerializedRelationships(object): Read-only sequence of |_SerializedRelationship| instances corresponding to the relationships item XML passed to constructor. """ + def __init__(self): super(_SerializedRelationships, self).__init__() self._srels = [] diff --git a/docx/opc/shared.py b/docx/opc/shared.py index 55344483..15eed35d 100644 --- a/docx/opc/shared.py +++ b/docx/opc/shared.py @@ -15,6 +15,7 @@ class CaseInsensitiveDict(dict): assumes str keys, and that it is created empty; keys passed in constructor are not accounted for """ + def __contains__(self, key): return super(CaseInsensitiveDict, self).__contains__(key.lower()) @@ -22,9 +23,7 @@ def __getitem__(self, key): return super(CaseInsensitiveDict, self).__getitem__(key.lower()) def __setitem__(self, key, value): - return super(CaseInsensitiveDict, self).__setitem__( - key.lower(), value - ) + return super(CaseInsensitiveDict, self).__setitem__(key.lower(), value) def lazyproperty(f): @@ -33,7 +32,7 @@ def lazyproperty(f): to calculate a cached property value. After that, the cached value is returned. """ - cache_attr_name = '_%s' % f.__name__ # like '_foobar' for prop 'foobar' + cache_attr_name = "_%s" % f.__name__ # like '_foobar' for prop 'foobar' docstring = f.__doc__ def get_prop_value(obj): diff --git a/docx/opc/spec.py b/docx/opc/spec.py index 60fc3856..87489fcf 100644 --- a/docx/opc/spec.py +++ b/docx/opc/spec.py @@ -8,22 +8,22 @@ default_content_types = ( - ('bin', CT.PML_PRINTER_SETTINGS), - ('bin', CT.SML_PRINTER_SETTINGS), - ('bin', CT.WML_PRINTER_SETTINGS), - ('bmp', CT.BMP), - ('emf', CT.X_EMF), - ('fntdata', CT.X_FONTDATA), - ('gif', CT.GIF), - ('jpe', CT.JPEG), - ('jpeg', CT.JPEG), - ('jpg', CT.JPEG), - ('png', CT.PNG), - ('rels', CT.OPC_RELATIONSHIPS), - ('tif', CT.TIFF), - ('tiff', CT.TIFF), - ('wdp', CT.MS_PHOTO), - ('wmf', CT.X_WMF), - ('xlsx', CT.SML_SHEET), - ('xml', CT.XML), + ("bin", CT.PML_PRINTER_SETTINGS), + ("bin", CT.SML_PRINTER_SETTINGS), + ("bin", CT.WML_PRINTER_SETTINGS), + ("bmp", CT.BMP), + ("emf", CT.X_EMF), + ("fntdata", CT.X_FONTDATA), + ("gif", CT.GIF), + ("jpe", CT.JPEG), + ("jpeg", CT.JPEG), + ("jpg", CT.JPEG), + ("png", CT.PNG), + ("rels", CT.OPC_RELATIONSHIPS), + ("tif", CT.TIFF), + ("tiff", CT.TIFF), + ("wdp", CT.MS_PHOTO), + ("wmf", CT.X_WMF), + ("xlsx", CT.SML_SHEET), + ("xml", CT.XML), ) diff --git a/docx/oxml/coreprops.py b/docx/oxml/coreprops.py index 679be513..0520201b 100644 --- a/docx/oxml/coreprops.py +++ b/docx/oxml/coreprops.py @@ -2,9 +2,7 @@ """Custom element classes for core properties-related XML elements""" -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals import re @@ -24,25 +22,24 @@ class CT_CoreProperties(BaseOxmlElement): ('') if the element is not present in the XML. String elements are limited in length to 255 unicode characters. """ - category = ZeroOrOne('cp:category', successors=()) - contentStatus = ZeroOrOne('cp:contentStatus', successors=()) - created = ZeroOrOne('dcterms:created', successors=()) - creator = ZeroOrOne('dc:creator', successors=()) - description = ZeroOrOne('dc:description', successors=()) - identifier = ZeroOrOne('dc:identifier', successors=()) - keywords = ZeroOrOne('cp:keywords', successors=()) - language = ZeroOrOne('dc:language', successors=()) - lastModifiedBy = ZeroOrOne('cp:lastModifiedBy', successors=()) - lastPrinted = ZeroOrOne('cp:lastPrinted', successors=()) - modified = ZeroOrOne('dcterms:modified', successors=()) - revision = ZeroOrOne('cp:revision', successors=()) - subject = ZeroOrOne('dc:subject', successors=()) - title = ZeroOrOne('dc:title', successors=()) - version = ZeroOrOne('cp:version', successors=()) - - _coreProperties_tmpl = ( - '\n' % nsdecls('cp', 'dc', 'dcterms') - ) + + category = ZeroOrOne("cp:category", successors=()) + contentStatus = ZeroOrOne("cp:contentStatus", successors=()) + created = ZeroOrOne("dcterms:created", successors=()) + creator = ZeroOrOne("dc:creator", successors=()) + description = ZeroOrOne("dc:description", successors=()) + identifier = ZeroOrOne("dc:identifier", successors=()) + keywords = ZeroOrOne("cp:keywords", successors=()) + language = ZeroOrOne("dc:language", successors=()) + lastModifiedBy = ZeroOrOne("cp:lastModifiedBy", successors=()) + lastPrinted = ZeroOrOne("cp:lastPrinted", successors=()) + modified = ZeroOrOne("dcterms:modified", successors=()) + revision = ZeroOrOne("cp:revision", successors=()) + subject = ZeroOrOne("dc:subject", successors=()) + title = ZeroOrOne("dc:title", successors=()) + version = ZeroOrOne("cp:version", successors=()) + + _coreProperties_tmpl = "\n" % nsdecls("cp", "dc", "dcterms") @classmethod def new(cls): @@ -58,91 +55,91 @@ def author_text(self): """ The text in the `dc:creator` child element. """ - return self._text_of_element('creator') + return self._text_of_element("creator") @author_text.setter def author_text(self, value): - self._set_element_text('creator', value) + self._set_element_text("creator", value) @property def category_text(self): - return self._text_of_element('category') + return self._text_of_element("category") @category_text.setter def category_text(self, value): - self._set_element_text('category', value) + self._set_element_text("category", value) @property def comments_text(self): - return self._text_of_element('description') + return self._text_of_element("description") @comments_text.setter def comments_text(self, value): - self._set_element_text('description', value) + self._set_element_text("description", value) @property def contentStatus_text(self): - return self._text_of_element('contentStatus') + return self._text_of_element("contentStatus") @contentStatus_text.setter def contentStatus_text(self, value): - self._set_element_text('contentStatus', value) + self._set_element_text("contentStatus", value) @property def created_datetime(self): - return self._datetime_of_element('created') + return self._datetime_of_element("created") @created_datetime.setter def created_datetime(self, value): - self._set_element_datetime('created', value) + self._set_element_datetime("created", value) @property def identifier_text(self): - return self._text_of_element('identifier') + return self._text_of_element("identifier") @identifier_text.setter def identifier_text(self, value): - self._set_element_text('identifier', value) + self._set_element_text("identifier", value) @property def keywords_text(self): - return self._text_of_element('keywords') + return self._text_of_element("keywords") @keywords_text.setter def keywords_text(self, value): - self._set_element_text('keywords', value) + self._set_element_text("keywords", value) @property def language_text(self): - return self._text_of_element('language') + return self._text_of_element("language") @language_text.setter def language_text(self, value): - self._set_element_text('language', value) + self._set_element_text("language", value) @property def lastModifiedBy_text(self): - return self._text_of_element('lastModifiedBy') + return self._text_of_element("lastModifiedBy") @lastModifiedBy_text.setter def lastModifiedBy_text(self, value): - self._set_element_text('lastModifiedBy', value) + self._set_element_text("lastModifiedBy", value) @property def lastPrinted_datetime(self): - return self._datetime_of_element('lastPrinted') + return self._datetime_of_element("lastPrinted") @lastPrinted_datetime.setter def lastPrinted_datetime(self, value): - self._set_element_datetime('lastPrinted', value) + self._set_element_datetime("lastPrinted", value) @property def modified_datetime(self): - return self._datetime_of_element('modified') + return self._datetime_of_element("modified") @modified_datetime.setter def modified_datetime(self, value): - self._set_element_datetime('modified', value) + self._set_element_datetime("modified", value) @property def revision_number(self): @@ -176,27 +173,27 @@ def revision_number(self, value): @property def subject_text(self): - return self._text_of_element('subject') + return self._text_of_element("subject") @subject_text.setter def subject_text(self, value): - self._set_element_text('subject', value) + self._set_element_text("subject", value) @property def title_text(self): - return self._text_of_element('title') + return self._text_of_element("title") @title_text.setter def title_text(self, value): - self._set_element_text('title', value) + self._set_element_text("title", value) @property def version_text(self): - return self._text_of_element('version') + return self._text_of_element("version") @version_text.setter def version_text(self, value): - self._set_element_text('version', value) + self._set_element_text("version", value) def _datetime_of_element(self, property_name): element = getattr(self, property_name) @@ -213,7 +210,7 @@ def _get_or_add(self, prop_name): """ Return element returned by 'get_or_add_' method for *prop_name*. """ - get_or_add_method_name = f'get_or_add_{prop_name}' + get_or_add_method_name = f"get_or_add_{prop_name}" get_or_add_method = getattr(self, get_or_add_method_name) return get_or_add_method() @@ -226,17 +223,15 @@ def _offset_dt(cls, dt, offset_str): """ match = cls._offset_pattern.match(offset_str) if match is None: - raise ValueError( - "'%s' is not a valid offset string" % offset_str - ) + raise ValueError("'%s' is not a valid offset string" % offset_str) sign, hours_str, minutes_str = match.groups() - sign_factor = -1 if sign == '+' else 1 + sign_factor = -1 if sign == "+" else 1 hours = int(hours_str) * sign_factor minutes = int(minutes_str) * sign_factor td = timedelta(hours=hours, minutes=minutes) return dt + td - _offset_pattern = re.compile(r'([+-])(\d\d):(\d\d)') + _offset_pattern = re.compile(r"([+-])(\d\d):(\d\d)") @classmethod def _parse_W3CDTF_to_datetime(cls, w3cdtf_str): @@ -247,10 +242,10 @@ def _parse_W3CDTF_to_datetime(cls, w3cdtf_str): # UTC timezone e.g. '2003-12-31T10:14:55Z' # numeric timezone e.g. '2003-12-31T10:14:55-08:00' templates = ( - '%Y-%m-%dT%H:%M:%S', - '%Y-%m-%d', - '%Y-%m', - '%Y', + "%Y-%m-%dT%H:%M:%S", + "%Y-%m-%d", + "%Y-%m", + "%Y", ) # strptime isn't smart enough to parse literal timezone offsets like # '-07:30', so we have to do it ourselves @@ -274,21 +269,19 @@ def _set_element_datetime(self, prop_name, value): Set date/time value of child element having *prop_name* to *value*. """ if not isinstance(value, datetime): - tmpl = ( - "property requires object, got %s" - ) + tmpl = "property requires object, got %s" raise ValueError(tmpl % type(value)) element = self._get_or_add(prop_name) - dt_str = value.strftime('%Y-%m-%dT%H:%M:%SZ') + dt_str = value.strftime("%Y-%m-%dT%H:%M:%SZ") element.text = dt_str - if prop_name in ('created', 'modified'): + if prop_name in ("created", "modified"): # These two require an explicit 'xsi:type="dcterms:W3CDTF"' # attribute. The first and last line are a hack required to add # the xsi namespace to the root element rather than each child # element in which it is referenced - self.set(qn('xsi:foo'), 'bar') - element.set(qn('xsi:type'), 'dcterms:W3CDTF') - del self.attrib[qn('xsi:foo')] + self.set(qn("xsi:foo"), "bar") + element.set(qn("xsi:type"), "dcterms:W3CDTF") + del self.attrib[qn("xsi:foo")] def _set_element_text(self, prop_name, value): """Set string value of *name* property to *value*.""" @@ -296,9 +289,7 @@ def _set_element_text(self, prop_name, value): value = str(value) if len(value) > 255: - tmpl = ( - "exceeded 255 char limit for property, got:\n\n'%s'" - ) + tmpl = "exceeded 255 char limit for property, got:\n\n'%s'" raise ValueError(tmpl % value) element = self._get_or_add(prop_name) element.text = value @@ -310,7 +301,7 @@ def _text_of_element(self, property_name): """ element = getattr(self, property_name) if element is None: - return '' + return "" if element.text is None: - return '' + return "" return element.text diff --git a/docx/oxml/customprops.py b/docx/oxml/customprops.py index 3be69e4d..34b9f011 100644 --- a/docx/oxml/customprops.py +++ b/docx/oxml/customprops.py @@ -4,17 +4,17 @@ lxml custom element classes for core properties-related XML elements. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals import re - from datetime import datetime, timedelta + from lxml import etree + +from . import parse_xml from .ns import nsdecls, qn from .xmlchemy import BaseOxmlElement, ZeroOrOne -from . import parse_xml + class CT_CustomProperties(BaseOxmlElement): """ @@ -24,7 +24,8 @@ class CT_CustomProperties(BaseOxmlElement): """ _customProperties_tmpl = ( - '\n' % nsdecls('vt') + '\n' + % nsdecls("vt") ) @classmethod @@ -51,7 +52,7 @@ def _get_or_add(self, prop_name): """ Return element returned by 'get_or_add_' method for *prop_name*. """ - get_or_add_method_name = 'get_or_add_%s' % prop_name + get_or_add_method_name = "get_or_add_%s" % prop_name get_or_add_method = getattr(self, get_or_add_method_name) element = get_or_add_method() return element @@ -65,17 +66,15 @@ def _offset_dt(cls, dt, offset_str): """ match = cls._offset_pattern.match(offset_str) if match is None: - raise ValueError( - "'%s' is not a valid offset string" % offset_str - ) + raise ValueError("'%s' is not a valid offset string" % offset_str) sign, hours_str, minutes_str = match.groups() - sign_factor = -1 if sign == '+' else 1 + sign_factor = -1 if sign == "+" else 1 hours = int(hours_str) * sign_factor minutes = int(minutes_str) * sign_factor td = timedelta(hours=hours, minutes=minutes) return dt + td - _offset_pattern = re.compile('([+-])(\d\d):(\d\d)') + _offset_pattern = re.compile(r"([+-])(\d\d):(\d\d)") @classmethod def _parse_W3CDTF_to_datetime(cls, w3cdtf_str): @@ -86,10 +85,10 @@ def _parse_W3CDTF_to_datetime(cls, w3cdtf_str): # UTC timezone e.g. '2003-12-31T10:14:55Z' # numeric timezone e.g. '2003-12-31T10:14:55-08:00' templates = ( - '%Y-%m-%dT%H:%M:%S', - '%Y-%m-%d', - '%Y-%m', - '%Y', + "%Y-%m-%dT%H:%M:%S", + "%Y-%m-%d", + "%Y-%m", + "%Y", ) # strptime isn't smart enough to parse literal timezone offsets like # '-07:30', so we have to do it ourselves @@ -113,21 +112,19 @@ def _set_element_datetime(self, prop_name, value): Set date/time value of child element having *prop_name* to *value*. """ if not isinstance(value, datetime): - tmpl = ( - "property requires object, got %s" - ) + tmpl = "property requires object, got %s" raise ValueError(tmpl % type(value)) element = self._get_or_add(prop_name) - dt_str = value.strftime('%Y-%m-%dT%H:%M:%SZ') + dt_str = value.strftime("%Y-%m-%dT%H:%M:%SZ") element.text = dt_str - if prop_name in ('created', 'modified'): + if prop_name in ("created", "modified"): # These two require an explicit 'xsi:type="dcterms:W3CDTF"' # attribute. The first and last line are a hack required to add # the xsi namespace to the root element rather than each child # element in which it is referenced - self.set(qn('xsi:foo'), 'bar') - element.set(qn('xsi:type'), 'dcterms:W3CDTF') - del self.attrib[qn('xsi:foo')] + self.set(qn("xsi:foo"), "bar") + element.set(qn("xsi:type"), "dcterms:W3CDTF") + del self.attrib[qn("xsi:foo")] def _set_element_text(self, prop_name, value): """ @@ -135,9 +132,7 @@ def _set_element_text(self, prop_name, value): """ value = str(value) if len(value) > 255: - tmpl = ( - "exceeded 255 char limit for property, got:\n\n'%s'" - ) + tmpl = "exceeded 255 char limit for property, got:\n\n'%s'" raise ValueError(tmpl % value) element = self._get_or_add(prop_name) element.text = value @@ -149,8 +144,7 @@ def _text_of_element(self, property_name): """ element = getattr(self, property_name) if element is None: - return '' + return "" if element.text is None: - return '' + return "" return element.text - diff --git a/docx/oxml/document.py b/docx/oxml/document.py index 4211b8ed..5c3e6f2b 100644 --- a/docx/oxml/document.py +++ b/docx/oxml/document.py @@ -12,7 +12,8 @@ class CT_Document(BaseOxmlElement): """ ```` element, the root element of a document.xml file. """ - body = ZeroOrOne('w:body') + + body = ZeroOrOne("w:body") @property def sectPr_lst(self): @@ -20,7 +21,7 @@ def sectPr_lst(self): Return a list containing a reference to each ```` element in the document, in the order encountered. """ - return self.xpath('.//w:sectPr') + return self.xpath(".//w:sectPr") class CT_Body(BaseOxmlElement): @@ -28,9 +29,10 @@ class CT_Body(BaseOxmlElement): ````, the container element for the main document story in ``document.xml``. """ - p = ZeroOrMore('w:p', successors=('w:sectPr',)) - tbl = ZeroOrMore('w:tbl', successors=('w:sectPr',)) - sectPr = ZeroOrOne('w:sectPr', successors=()) + + p = ZeroOrMore("w:p", successors=("w:sectPr",)) + tbl = ZeroOrMore("w:tbl", successors=("w:sectPr",)) + sectPr = ZeroOrOne("w:sectPr", successors=()) def add_section_break(self): """Return `w:sectPr` element for new section added at end of document. diff --git a/docx/oxml/ns.py b/docx/oxml/ns.py index 42d5e2a8..77cc77ea 100644 --- a/docx/oxml/ns.py +++ b/docx/oxml/ns.py @@ -19,9 +19,9 @@ "pic": "http://schemas.openxmlformats.org/drawingml/2006/picture", "r": "http://schemas.openxmlformats.org/officeDocument/2006/relationships", "sl": "http://schemas.openxmlformats.org/schemaLibrary/2006/main", - 'vt' : "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes", + "vt": "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes", "w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main", - 'w14': "http://schemas.microsoft.com/office/word/2010/wordml", + "w14": "http://schemas.microsoft.com/office/word/2010/wordml", "wp": "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing", "xml": "http://www.w3.org/XML/1998/namespace", "xsi": "http://www.w3.org/2001/XMLSchema-instance", @@ -35,21 +35,22 @@ class NamespacePrefixedTag(str): Value object that knows the semantics of an XML tag having a namespace prefix. """ + def __new__(cls, nstag, *args): return super(NamespacePrefixedTag, cls).__new__(cls, nstag) def __init__(self, nstag): - self._pfx, self._local_part = nstag.split(':') + self._pfx, self._local_part = nstag.split(":") self._ns_uri = nsmap[self._pfx] @property def clark_name(self): - return '{%s}%s' % (self._ns_uri, self._local_part) + return "{%s}%s" % (self._ns_uri, self._local_part) @classmethod def from_clark_name(cls, clark_name): - nsuri, local_name = clark_name[1:].split('}') - nstag = '%s:%s' % (pfxmap[nsuri], local_name) + nsuri, local_name = clark_name[1:].split("}") + nstag = "%s:%s" % (pfxmap[nsuri], local_name) return cls(nstag) @property @@ -92,7 +93,7 @@ def nsdecls(*prefixes): Return a string containing a namespace declaration for each of the namespace prefix strings, e.g. 'p', 'ct', passed as *prefixes*. """ - return ' '.join(['xmlns:%s="%s"' % (pfx, nsmap[pfx]) for pfx in prefixes]) + return " ".join(['xmlns:%s="%s"' % (pfx, nsmap[pfx]) for pfx in prefixes]) def nspfxmap(*nspfxs): @@ -110,6 +111,6 @@ def qn(tag): prefixed tag name into a Clark-notation qualified tag name for lxml. For example, ``qn('p:cSld')`` returns ``'{http://schemas.../main}cSld'``. """ - prefix, tagroot = tag.split(':') + prefix, tagroot = tag.split(":") uri = nsmap[prefix] - return '{%s}%s' % (uri, tagroot) + return "{%s}%s" % (uri, tagroot) diff --git a/docx/oxml/numbering.py b/docx/oxml/numbering.py index aeedfa9a..d5297b2a 100644 --- a/docx/oxml/numbering.py +++ b/docx/oxml/numbering.py @@ -8,7 +8,11 @@ from .shared import CT_DecimalNumber from .simpletypes import ST_DecimalNumber from .xmlchemy import ( - BaseOxmlElement, OneAndOnlyOne, RequiredAttribute, ZeroOrMore, ZeroOrOne + BaseOxmlElement, + OneAndOnlyOne, + RequiredAttribute, + ZeroOrMore, + ZeroOrOne, ) @@ -18,9 +22,10 @@ class CT_Num(BaseOxmlElement): instance, having a required child that references an abstract numbering definition that defines most of the formatting details. """ - abstractNumId = OneAndOnlyOne('w:abstractNumId') - lvlOverride = ZeroOrMore('w:lvlOverride') - numId = RequiredAttribute('w:numId', ST_DecimalNumber) + + abstractNumId = OneAndOnlyOne("w:abstractNumId") + lvlOverride = ZeroOrMore("w:lvlOverride") + numId = RequiredAttribute("w:numId", ST_DecimalNumber) def add_lvlOverride(self, ilvl): """ @@ -36,11 +41,9 @@ def new(cls, num_id, abstractNum_id): a ```` child with val attribute set to *abstractNum_id*. """ - num = OxmlElement('w:num') + num = OxmlElement("w:num") num.numId = num_id - abstractNumId = CT_DecimalNumber.new( - 'w:abstractNumId', abstractNum_id - ) + abstractNumId = CT_DecimalNumber.new("w:abstractNumId", abstractNum_id) num.append(abstractNumId) return num @@ -50,8 +53,9 @@ class CT_NumLvl(BaseOxmlElement): ```` element, which identifies a level in a list definition to override with settings it contains. """ - startOverride = ZeroOrOne('w:startOverride', successors=('w:lvl',)) - ilvl = RequiredAttribute('w:ilvl', ST_DecimalNumber) + + startOverride = ZeroOrOne("w:startOverride", successors=("w:lvl",)) + ilvl = RequiredAttribute("w:ilvl", ST_DecimalNumber) def add_startOverride(self, val): """ @@ -66,10 +70,9 @@ class CT_NumPr(BaseOxmlElement): A ```` element, a container for numbering properties applied to a paragraph. """ - ilvl = ZeroOrOne('w:ilvl', successors=( - 'w:numId', 'w:numberingChange', 'w:ins' - )) - numId = ZeroOrOne('w:numId', successors=('w:numberingChange', 'w:ins')) + + ilvl = ZeroOrOne("w:ilvl", successors=("w:numId", "w:numberingChange", "w:ins")) + numId = ZeroOrOne("w:numId", successors=("w:numberingChange", "w:ins")) # @ilvl.setter # def _set_ilvl(self, val): @@ -94,7 +97,8 @@ class CT_Numbering(BaseOxmlElement): ```` element, the root element of a numbering part, i.e. numbering.xml """ - num = ZeroOrMore('w:num', successors=('w:numIdMacAtCleanup',)) + + num = ZeroOrMore("w:num", successors=("w:numIdMacAtCleanup",)) def add_num(self, abstractNum_id): """ @@ -114,7 +118,7 @@ def num_having_numId(self, numId): try: return self.xpath(xpath)[0] except IndexError: - raise KeyError('no element with numId %d' % numId) + raise KeyError("no element with numId %d" % numId) @property def _next_numId(self): @@ -123,9 +127,9 @@ def _next_numId(self): 1 and filling any gaps in numbering between existing ```` elements. """ - numId_strs = self.xpath('./w:num/@w:numId') + numId_strs = self.xpath("./w:num/@w:numId") num_ids = [int(numId_str) for numId_str in numId_strs] - for num in range(1, len(num_ids)+2): + for num in range(1, len(num_ids) + 2): if num not in num_ids: break return num diff --git a/docx/oxml/section.py b/docx/oxml/section.py index fc953e74..e7193677 100644 --- a/docx/oxml/section.py +++ b/docx/oxml/section.py @@ -20,38 +20,40 @@ class CT_HdrFtr(BaseOxmlElement): """`w:hdr` and `w:ftr`, the root element for header and footer part respectively""" - p = ZeroOrMore('w:p', successors=()) - tbl = ZeroOrMore('w:tbl', successors=()) + p = ZeroOrMore("w:p", successors=()) + tbl = ZeroOrMore("w:tbl", successors=()) class CT_HdrFtrRef(BaseOxmlElement): """`w:headerReference` and `w:footerReference` elements""" - type_ = RequiredAttribute('w:type', WD_HEADER_FOOTER) - rId = RequiredAttribute('r:id', XsdString) + type_ = RequiredAttribute("w:type", WD_HEADER_FOOTER) + rId = RequiredAttribute("r:id", XsdString) class CT_PageMar(BaseOxmlElement): """ ```` element, defining page margins. """ - top = OptionalAttribute('w:top', ST_SignedTwipsMeasure) - right = OptionalAttribute('w:right', ST_TwipsMeasure) - bottom = OptionalAttribute('w:bottom', ST_SignedTwipsMeasure) - left = OptionalAttribute('w:left', ST_TwipsMeasure) - header = OptionalAttribute('w:header', ST_TwipsMeasure) - footer = OptionalAttribute('w:footer', ST_TwipsMeasure) - gutter = OptionalAttribute('w:gutter', ST_TwipsMeasure) + + top = OptionalAttribute("w:top", ST_SignedTwipsMeasure) + right = OptionalAttribute("w:right", ST_TwipsMeasure) + bottom = OptionalAttribute("w:bottom", ST_SignedTwipsMeasure) + left = OptionalAttribute("w:left", ST_TwipsMeasure) + header = OptionalAttribute("w:header", ST_TwipsMeasure) + footer = OptionalAttribute("w:footer", ST_TwipsMeasure) + gutter = OptionalAttribute("w:gutter", ST_TwipsMeasure) class CT_PageSz(BaseOxmlElement): """ ```` element, defining page dimensions and orientation. """ - w = OptionalAttribute('w:w', ST_TwipsMeasure) - h = OptionalAttribute('w:h', ST_TwipsMeasure) + + w = OptionalAttribute("w:w", ST_TwipsMeasure) + h = OptionalAttribute("w:h", ST_TwipsMeasure) orient = OptionalAttribute( - 'w:orient', WD_ORIENTATION, default=WD_ORIENTATION.PORTRAIT + "w:orient", WD_ORIENTATION, default=WD_ORIENTATION.PORTRAIT ) @@ -59,10 +61,26 @@ class CT_SectPr(BaseOxmlElement): """`w:sectPr` element, the container element for section properties""" _tag_seq = ( - 'w:footnotePr', 'w:endnotePr', 'w:type', 'w:pgSz', 'w:pgMar', 'w:paperSrc', - 'w:pgBorders', 'w:lnNumType', 'w:pgNumType', 'w:cols', 'w:formProt', 'w:vAlign', - 'w:noEndnote', 'w:titlePg', 'w:textDirection', 'w:bidi', 'w:rtlGutter', - 'w:docGrid', 'w:printerSettings', 'w:sectPrChange', + "w:footnotePr", + "w:endnotePr", + "w:type", + "w:pgSz", + "w:pgMar", + "w:paperSrc", + "w:pgBorders", + "w:lnNumType", + "w:pgNumType", + "w:cols", + "w:formProt", + "w:vAlign", + "w:noEndnote", + "w:titlePg", + "w:textDirection", + "w:bidi", + "w:rtlGutter", + "w:docGrid", + "w:printerSettings", + "w:sectPrChange", ) headerReference = ZeroOrMore("w:headerReference", successors=_tag_seq) footerReference = ZeroOrMore("w:footerReference", successors=_tag_seq) @@ -348,4 +366,5 @@ class CT_SectType(BaseOxmlElement): """ ```` element, defining the section start type. """ - val = OptionalAttribute('w:val', WD_SECTION_START) + + val = OptionalAttribute("w:val", WD_SECTION_START) diff --git a/docx/oxml/settings.py b/docx/oxml/settings.py index fd319ad7..3fc72e27 100644 --- a/docx/oxml/settings.py +++ b/docx/oxml/settings.py @@ -11,39 +11,104 @@ class CT_Settings(BaseOxmlElement): """`w:settings` element, root element for the settings part""" _tag_seq = ( - "w:writeProtection", "w:view", "w:zoom", "w:removePersonalInformation", - "w:removeDateAndTime", "w:doNotDisplayPageBoundaries", - "w:displayBackgroundShape", "w:printPostScriptOverText", - "w:printFractionalCharacterWidth", "w:printFormsData", "w:embedTrueTypeFonts", - "w:embedSystemFonts", "w:saveSubsetFonts", "w:saveFormsData", "w:mirrorMargins", - "w:alignBordersAndEdges", "w:bordersDoNotSurroundHeader", - "w:bordersDoNotSurroundFooter", "w:gutterAtTop", "w:hideSpellingErrors", - "w:hideGrammaticalErrors", "w:activeWritingStyle", "w:proofState", - "w:formsDesign", "w:attachedTemplate", "w:linkStyles", - "w:stylePaneFormatFilter", "w:stylePaneSortMethod", "w:documentType", - "w:mailMerge", "w:revisionView", "w:trackRevisions", "w:doNotTrackMoves", - "w:doNotTrackFormatting", "w:documentProtection", "w:autoFormatOverride", - "w:styleLockTheme", "w:styleLockQFSet", "w:defaultTabStop", "w:autoHyphenation", - "w:consecutiveHyphenLimit", "w:hyphenationZone", "w:doNotHyphenateCaps", - "w:showEnvelope", "w:summaryLength", "w:clickAndTypeStyle", - "w:defaultTableStyle", "w:evenAndOddHeaders", "w:bookFoldRevPrinting", - "w:bookFoldPrinting", "w:bookFoldPrintingSheets", - "w:drawingGridHorizontalSpacing", "w:drawingGridVerticalSpacing", - "w:displayHorizontalDrawingGridEvery", "w:displayVerticalDrawingGridEvery", - "w:doNotUseMarginsForDrawingGridOrigin", "w:drawingGridHorizontalOrigin", - "w:drawingGridVerticalOrigin", "w:doNotShadeFormData", "w:noPunctuationKerning", - "w:characterSpacingControl", "w:printTwoOnOne", "w:strictFirstAndLastChars", - "w:noLineBreaksAfter", "w:noLineBreaksBefore", "w:savePreviewPicture", - "w:doNotValidateAgainstSchema", "w:saveInvalidXml", "w:ignoreMixedContent", - "w:alwaysShowPlaceholderText", "w:doNotDemarcateInvalidXml", - "w:saveXmlDataOnly", "w:useXSLTWhenSaving", "w:saveThroughXslt", - "w:showXMLTags", "w:alwaysMergeEmptyNamespace", "w:updateFields", - "w:hdrShapeDefaults", "w:footnotePr", "w:endnotePr", "w:compat", "w:docVars", - "w:rsids", "m:mathPr", "w:attachedSchema", "w:themeFontLang", - "w:clrSchemeMapping", "w:doNotIncludeSubdocsInStats", - "w:doNotAutoCompressPictures", "w:forceUpgrade", "w:captions", - "w:readModeInkLockDown", "w:smartTagType", "sl:schemaLibrary", - "w:shapeDefaults", "w:doNotEmbedSmartTags", "w:decimalSymbol", "w:listSeparator" + "w:writeProtection", + "w:view", + "w:zoom", + "w:removePersonalInformation", + "w:removeDateAndTime", + "w:doNotDisplayPageBoundaries", + "w:displayBackgroundShape", + "w:printPostScriptOverText", + "w:printFractionalCharacterWidth", + "w:printFormsData", + "w:embedTrueTypeFonts", + "w:embedSystemFonts", + "w:saveSubsetFonts", + "w:saveFormsData", + "w:mirrorMargins", + "w:alignBordersAndEdges", + "w:bordersDoNotSurroundHeader", + "w:bordersDoNotSurroundFooter", + "w:gutterAtTop", + "w:hideSpellingErrors", + "w:hideGrammaticalErrors", + "w:activeWritingStyle", + "w:proofState", + "w:formsDesign", + "w:attachedTemplate", + "w:linkStyles", + "w:stylePaneFormatFilter", + "w:stylePaneSortMethod", + "w:documentType", + "w:mailMerge", + "w:revisionView", + "w:trackRevisions", + "w:doNotTrackMoves", + "w:doNotTrackFormatting", + "w:documentProtection", + "w:autoFormatOverride", + "w:styleLockTheme", + "w:styleLockQFSet", + "w:defaultTabStop", + "w:autoHyphenation", + "w:consecutiveHyphenLimit", + "w:hyphenationZone", + "w:doNotHyphenateCaps", + "w:showEnvelope", + "w:summaryLength", + "w:clickAndTypeStyle", + "w:defaultTableStyle", + "w:evenAndOddHeaders", + "w:bookFoldRevPrinting", + "w:bookFoldPrinting", + "w:bookFoldPrintingSheets", + "w:drawingGridHorizontalSpacing", + "w:drawingGridVerticalSpacing", + "w:displayHorizontalDrawingGridEvery", + "w:displayVerticalDrawingGridEvery", + "w:doNotUseMarginsForDrawingGridOrigin", + "w:drawingGridHorizontalOrigin", + "w:drawingGridVerticalOrigin", + "w:doNotShadeFormData", + "w:noPunctuationKerning", + "w:characterSpacingControl", + "w:printTwoOnOne", + "w:strictFirstAndLastChars", + "w:noLineBreaksAfter", + "w:noLineBreaksBefore", + "w:savePreviewPicture", + "w:doNotValidateAgainstSchema", + "w:saveInvalidXml", + "w:ignoreMixedContent", + "w:alwaysShowPlaceholderText", + "w:doNotDemarcateInvalidXml", + "w:saveXmlDataOnly", + "w:useXSLTWhenSaving", + "w:saveThroughXslt", + "w:showXMLTags", + "w:alwaysMergeEmptyNamespace", + "w:updateFields", + "w:hdrShapeDefaults", + "w:footnotePr", + "w:endnotePr", + "w:compat", + "w:docVars", + "w:rsids", + "m:mathPr", + "w:attachedSchema", + "w:themeFontLang", + "w:clrSchemeMapping", + "w:doNotIncludeSubdocsInStats", + "w:doNotAutoCompressPictures", + "w:forceUpgrade", + "w:captions", + "w:readModeInkLockDown", + "w:smartTagType", + "sl:schemaLibrary", + "w:shapeDefaults", + "w:doNotEmbedSmartTags", + "w:decimalSymbol", + "w:listSeparator", ) evenAndOddHeaders = ZeroOrOne("w:evenAndOddHeaders", successors=_tag_seq[48:]) del _tag_seq diff --git a/docx/oxml/shape.py b/docx/oxml/shape.py index 77ca7db8..885535c7 100644 --- a/docx/oxml/shape.py +++ b/docx/oxml/shape.py @@ -7,12 +7,19 @@ from . import parse_xml from .ns import nsdecls from .simpletypes import ( - ST_Coordinate, ST_DrawingElementId, ST_PositiveCoordinate, - ST_RelationshipId, XsdString, XsdToken + ST_Coordinate, + ST_DrawingElementId, + ST_PositiveCoordinate, + ST_RelationshipId, + XsdString, + XsdToken, ) from .xmlchemy import ( - BaseOxmlElement, OneAndOnlyOne, OptionalAttribute, RequiredAttribute, - ZeroOrOne + BaseOxmlElement, + OneAndOnlyOne, + OptionalAttribute, + RequiredAttribute, + ZeroOrOne, ) @@ -21,41 +28,44 @@ class CT_Blip(BaseOxmlElement): ```` element, specifies image source and adjustments such as alpha and tint. """ - embed = OptionalAttribute('r:embed', ST_RelationshipId) - link = OptionalAttribute('r:link', ST_RelationshipId) + + embed = OptionalAttribute("r:embed", ST_RelationshipId) + link = OptionalAttribute("r:link", ST_RelationshipId) class CT_BlipFillProperties(BaseOxmlElement): """ ```` element, specifies picture properties """ - blip = ZeroOrOne('a:blip', successors=( - 'a:srcRect', 'a:tile', 'a:stretch' - )) + + blip = ZeroOrOne("a:blip", successors=("a:srcRect", "a:tile", "a:stretch")) class CT_GraphicalObject(BaseOxmlElement): """ ```` element, container for a DrawingML object """ - graphicData = OneAndOnlyOne('a:graphicData') + + graphicData = OneAndOnlyOne("a:graphicData") class CT_GraphicalObjectData(BaseOxmlElement): """ ```` element, container for the XML of a DrawingML object """ - pic = ZeroOrOne('pic:pic') - uri = RequiredAttribute('uri', XsdToken) + + pic = ZeroOrOne("pic:pic") + uri = RequiredAttribute("uri", XsdToken) class CT_Inline(BaseOxmlElement): """ ```` element, container for an inline shape. """ - extent = OneAndOnlyOne('wp:extent') - docPr = OneAndOnlyOne('wp:docPr') - graphic = OneAndOnlyOne('a:graphic') + + extent = OneAndOnlyOne("wp:extent") + docPr = OneAndOnlyOne("wp:docPr") + graphic = OneAndOnlyOne("a:graphic") @classmethod def new(cls, cx, cy, shape_id, pic): @@ -67,9 +77,9 @@ def new(cls, cx, cy, shape_id, pic): inline.extent.cx = cx inline.extent.cy = cy inline.docPr.id = shape_id - inline.docPr.name = 'Picture %d' % shape_id + inline.docPr.name = "Picture %d" % shape_id inline.graphic.graphicData.uri = ( - 'http://schemas.openxmlformats.org/drawingml/2006/picture' + "http://schemas.openxmlformats.org/drawingml/2006/picture" ) inline.graphic.graphicData._insert_pic(pic) return inline @@ -89,16 +99,16 @@ def new_pic_inline(cls, shape_id, rId, filename, cx, cy): @classmethod def _inline_xml(cls): return ( - '\n' + "\n" ' \n' ' \n' - ' \n' + " \n" ' \n' - ' \n' - ' \n' + " \n" + " \n" ' \n' - ' \n' - '' % nsdecls('wp', 'a', 'pic', 'r') + " \n" + "" % nsdecls("wp", "a", "pic", "r") ) @@ -107,8 +117,9 @@ class CT_NonVisualDrawingProps(BaseOxmlElement): Used for ```` element, and perhaps others. Specifies the id and name of a DrawingML drawing. """ - id = RequiredAttribute('id', ST_DrawingElementId) - name = RequiredAttribute('name', XsdString) + + id = RequiredAttribute("id", ST_DrawingElementId) + name = RequiredAttribute("name", XsdString) class CT_NonVisualPictureProperties(BaseOxmlElement): @@ -122,9 +133,10 @@ class CT_Picture(BaseOxmlElement): """ ```` element, a DrawingML picture """ - nvPicPr = OneAndOnlyOne('pic:nvPicPr') - blipFill = OneAndOnlyOne('pic:blipFill') - spPr = OneAndOnlyOne('pic:spPr') + + nvPicPr = OneAndOnlyOne("pic:nvPicPr") + blipFill = OneAndOnlyOne("pic:blipFill") + spPr = OneAndOnlyOne("pic:spPr") @classmethod def new(cls, pic_id, filename, rId, cx, cy): @@ -144,25 +156,25 @@ def new(cls, pic_id, filename, rId, cx, cy): @classmethod def _pic_xml(cls): return ( - '\n' - ' \n' + "\n" + " \n" ' \n' - ' \n' - ' \n' - ' \n' - ' \n' - ' \n' - ' \n' - ' \n' - ' \n' - ' \n' - ' \n' + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" ' \n' ' \n' - ' \n' + " \n" ' \n' - ' \n' - '' % nsdecls('pic', 'a', 'r') + " \n" + "" % nsdecls("pic", "a", "r") ) @@ -170,7 +182,8 @@ class CT_PictureNonVisual(BaseOxmlElement): """ ```` element, non-visual picture properties """ - cNvPr = OneAndOnlyOne('pic:cNvPr') + + cNvPr = OneAndOnlyOne("pic:cNvPr") class CT_Point2D(BaseOxmlElement): @@ -178,8 +191,9 @@ class CT_Point2D(BaseOxmlElement): Used for ```` element, and perhaps others. Specifies an x, y coordinate (point). """ - x = RequiredAttribute('x', ST_Coordinate) - y = RequiredAttribute('y', ST_Coordinate) + + x = RequiredAttribute("x", ST_Coordinate) + y = RequiredAttribute("y", ST_Coordinate) class CT_PositiveSize2D(BaseOxmlElement): @@ -187,8 +201,9 @@ class CT_PositiveSize2D(BaseOxmlElement): Used for ```` element, and perhaps others later. Specifies the size of a DrawingML drawing. """ - cx = RequiredAttribute('cx', ST_PositiveCoordinate) - cy = RequiredAttribute('cy', ST_PositiveCoordinate) + + cx = RequiredAttribute("cx", ST_PositiveCoordinate) + cy = RequiredAttribute("cy", ST_PositiveCoordinate) class CT_PresetGeometry2D(BaseOxmlElement): @@ -209,10 +224,20 @@ class CT_ShapeProperties(BaseOxmlElement): """ ```` element, specifies size and shape of picture container. """ - xfrm = ZeroOrOne('a:xfrm', successors=( - 'a:custGeom', 'a:prstGeom', 'a:ln', 'a:effectLst', 'a:effectDag', - 'a:scene3d', 'a:sp3d', 'a:extLst' - )) + + xfrm = ZeroOrOne( + "a:xfrm", + successors=( + "a:custGeom", + "a:prstGeom", + "a:ln", + "a:effectLst", + "a:effectDag", + "a:scene3d", + "a:sp3d", + "a:extLst", + ), + ) @property def cx(self): @@ -256,8 +281,9 @@ class CT_Transform2D(BaseOxmlElement): """ ```` element, specifies size and shape of picture container. """ - off = ZeroOrOne('a:off', successors=('a:ext',)) - ext = ZeroOrOne('a:ext', successors=()) + + off = ZeroOrOne("a:off", successors=("a:ext",)) + ext = ZeroOrOne("a:ext", successors=()) @property def cx(self): diff --git a/docx/oxml/shared.py b/docx/oxml/shared.py index 1e21ba36..4981e920 100644 --- a/docx/oxml/shared.py +++ b/docx/oxml/shared.py @@ -18,7 +18,8 @@ class CT_DecimalNumber(BaseOxmlElement): others, containing a text representation of a decimal number (e.g. 42) in its ``val`` attribute. """ - val = RequiredAttribute('w:val', ST_DecimalNumber) + + val = RequiredAttribute("w:val", ST_DecimalNumber) @classmethod def new(cls, nsptagname, val): @@ -26,7 +27,7 @@ def new(cls, nsptagname, val): Return a new ``CT_DecimalNumber`` element having tagname *nsptagname* and ``val`` attribute set to *val*. """ - return OxmlElement(nsptagname, attrs={qn('w:val'): str(val)}) + return OxmlElement(nsptagname, attrs={qn("w:val"): str(val)}) class CT_OnOff(BaseOxmlElement): @@ -34,7 +35,8 @@ class CT_OnOff(BaseOxmlElement): Used for ````, ```` elements and others, containing a bool-ish string in its ``val`` attribute, xsd:boolean plus 'on' and 'off'. """ - val = OptionalAttribute('w:val', ST_OnOff, default=True) + + val = OptionalAttribute("w:val", ST_OnOff, default=True) class CT_String(BaseOxmlElement): @@ -42,7 +44,8 @@ class CT_String(BaseOxmlElement): Used for ```` and ```` elements and others, containing a style name in its ``val`` attribute. """ - val = RequiredAttribute('w:val', ST_String) + + val = RequiredAttribute("w:val", ST_String) @classmethod def new(cls, nsptagname, val): diff --git a/docx/oxml/simpletypes.py b/docx/oxml/simpletypes.py index 400a2370..8fb6cb89 100644 --- a/docx/oxml/simpletypes.py +++ b/docx/oxml/simpletypes.py @@ -6,16 +6,13 @@ type in the associated XML schema. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals from ..exceptions import InvalidXmlError from ..shared import Emu, Pt, RGBColor, Twips class BaseSimpleType(object): - @classmethod def from_xml(cls, str_value): return cls.convert_from_xml(str_value) @@ -29,17 +26,15 @@ def to_xml(cls, value): @classmethod def validate_int(cls, value): if not isinstance(value, int): - raise TypeError( - "value must be , got %s" % type(value) - ) + raise TypeError("value must be , got %s" % type(value)) @classmethod def validate_int_in_range(cls, value, min_inclusive, max_inclusive): cls.validate_int(value) if value < min_inclusive or value > max_inclusive: raise ValueError( - "value must be in range %d to %d inclusive, got %d" % - (min_inclusive, max_inclusive, value) + "value must be in range %d to %d inclusive, got %d" + % (min_inclusive, max_inclusive, value) ) @classmethod @@ -51,13 +46,10 @@ def validate_string(cls, value): return value except NameError: # means we're on Python 3 pass - raise TypeError( - "value must be a string, got %s" % type(value) - ) + raise TypeError("value must be a string, got %s" % type(value)) class BaseIntType(BaseSimpleType): - @classmethod def convert_from_xml(cls, str_value): return int(str_value) @@ -72,7 +64,6 @@ def validate(cls, value): class BaseStringType(BaseSimpleType): - @classmethod def convert_from_xml(cls, str_value): return str_value @@ -87,14 +78,11 @@ def validate(cls, value): class BaseStringEnumerationType(BaseStringType): - @classmethod def validate(cls, value): cls.validate_string(value) if value not in cls._members: - raise ValueError( - "must be one of %s, got '%s'" % (cls._members, value) - ) + raise ValueError("must be one of %s, got '%s'" % (cls._members, value)) class XsdAnyUri(BaseStringType): @@ -106,19 +94,17 @@ class XsdAnyUri(BaseStringType): class XsdBoolean(BaseSimpleType): - @classmethod def convert_from_xml(cls, str_value): - if str_value not in ('1', '0', 'true', 'false'): + if str_value not in ("1", "0", "true", "false"): raise InvalidXmlError( - "value must be one of '1', '0', 'true' or 'false', got '%s'" - % str_value + "value must be one of '1', '0', 'true' or 'false', got '%s'" % str_value ) - return str_value in ('1', 'true') + return str_value in ("1", "true") @classmethod def convert_to_xml(cls, value): - return {True: '1', False: '0'}[value] + return {True: "1", False: "0"}[value] @classmethod def validate(cls, value): @@ -134,23 +120,20 @@ class XsdId(BaseStringType): String that must begin with a letter or underscore and cannot contain any colons. Not fully validated because not used in external API. """ + pass class XsdInt(BaseIntType): - @classmethod def validate(cls, value): cls.validate_int_in_range(value, -2147483648, 2147483647) class XsdLong(BaseIntType): - @classmethod def validate(cls, value): - cls.validate_int_in_range( - value, -9223372036854775808, 9223372036854775807 - ) + cls.validate_int_in_range(value, -9223372036854775808, 9223372036854775807) class XsdString(BaseStringType): @@ -168,52 +151,44 @@ class XsdToken(BaseStringType): xsd:string with whitespace collapsing, e.g. multiple spaces reduced to one, leading and trailing space stripped. """ + pass class XsdUnsignedInt(BaseIntType): - @classmethod def validate(cls, value): cls.validate_int_in_range(value, 0, 4294967295) class XsdUnsignedLong(BaseIntType): - @classmethod def validate(cls, value): cls.validate_int_in_range(value, 0, 18446744073709551615) class ST_BrClear(XsdString): - @classmethod def validate(cls, value): cls.validate_string(value) - valid_values = ('none', 'left', 'right', 'all') + valid_values = ("none", "left", "right", "all") if value not in valid_values: - raise ValueError( - "must be one of %s, got '%s'" % (valid_values, value) - ) + raise ValueError("must be one of %s, got '%s'" % (valid_values, value)) class ST_BrType(XsdString): - @classmethod def validate(cls, value): cls.validate_string(value) - valid_values = ('page', 'column', 'textWrapping') + valid_values = ("page", "column", "textWrapping") if value not in valid_values: - raise ValueError( - "must be one of %s, got '%s'" % (valid_values, value) - ) + raise ValueError("must be one of %s, got '%s'" % (valid_values, value)) class ST_Coordinate(BaseIntType): - @classmethod def convert_from_xml(cls, str_value): - if 'i' in str_value or 'm' in str_value or 'p' in str_value: + if "i" in str_value or "m" in str_value or "p" in str_value: return ST_UniversalMeasure.convert_from_xml(str_value) return Emu(int(str_value)) @@ -223,7 +198,6 @@ def validate(cls, value): class ST_CoordinateUnqualified(XsdLong): - @classmethod def validate(cls, value): cls.validate_int_in_range(value, -27273042329600, 27273042316900) @@ -238,10 +212,9 @@ class ST_DrawingElementId(XsdUnsignedInt): class ST_HexColor(BaseStringType): - @classmethod def convert_from_xml(cls, str_value): - if str_value == 'auto': + if str_value == "auto": return ST_HexColorAuto.AUTO return RGBColor.from_string(str_value) @@ -251,7 +224,7 @@ def convert_to_xml(cls, value): Keep alpha hex numerals all uppercase just for consistency. """ # expecting 3-tuple of ints in range 0-255 - return '%02X%02X%02X' % value + return "%02X%02X%02X" % value @classmethod def validate(cls, value): @@ -267,7 +240,8 @@ class ST_HexColorAuto(XsdStringEnumeration): """ Value for `w:color/[@val="auto"] attribute setting """ - AUTO = 'auto' + + AUTO = "auto" _members = (AUTO,) @@ -276,11 +250,12 @@ class ST_HpsMeasure(XsdUnsignedLong): """ Half-point measure, e.g. 24.0 represents 12.0 points. """ + @classmethod def convert_from_xml(cls, str_value): - if 'm' in str_value or 'n' in str_value or 'p' in str_value: + if "m" in str_value or "n" in str_value or "p" in str_value: return ST_UniversalMeasure.convert_from_xml(str_value) - return Pt(int(str_value)/2.0) + return Pt(int(str_value) / 2.0) @classmethod def convert_to_xml(cls, value): @@ -293,26 +268,25 @@ class ST_Merge(XsdStringEnumeration): """ Valid values for attribute """ - CONTINUE = 'continue' - RESTART = 'restart' + + CONTINUE = "continue" + RESTART = "restart" _members = (CONTINUE, RESTART) class ST_OnOff(XsdBoolean): - @classmethod def convert_from_xml(cls, str_value): - if str_value not in ('1', '0', 'true', 'false', 'on', 'off'): + if str_value not in ("1", "0", "true", "false", "on", "off"): raise InvalidXmlError( "value must be one of '1', '0', 'true', 'false', 'on', or 'o" "ff', got '%s'" % str_value ) - return str_value in ('1', 'true', 'on') + return str_value in ("1", "true", "on") class ST_PositiveCoordinate(XsdLong): - @classmethod def convert_from_xml(cls, str_value): return Emu(int(str_value)) @@ -327,10 +301,9 @@ class ST_RelationshipId(XsdString): class ST_SignedTwipsMeasure(XsdInt): - @classmethod def convert_from_xml(cls, str_value): - if 'i' in str_value or 'm' in str_value or 'p' in str_value: + if "i" in str_value or "m" in str_value or "p" in str_value: return ST_UniversalMeasure.convert_from_xml(str_value) return Twips(int(str_value)) @@ -346,34 +319,27 @@ class ST_String(XsdString): class ST_TblLayoutType(XsdString): - @classmethod def validate(cls, value): cls.validate_string(value) - valid_values = ('fixed', 'autofit') + valid_values = ("fixed", "autofit") if value not in valid_values: - raise ValueError( - "must be one of %s, got '%s'" % (valid_values, value) - ) + raise ValueError("must be one of %s, got '%s'" % (valid_values, value)) class ST_TblWidth(XsdString): - @classmethod def validate(cls, value): cls.validate_string(value) - valid_values = ('auto', 'dxa', 'nil', 'pct') + valid_values = ("auto", "dxa", "nil", "pct") if value not in valid_values: - raise ValueError( - "must be one of %s, got '%s'" % (valid_values, value) - ) + raise ValueError("must be one of %s, got '%s'" % (valid_values, value)) class ST_TwipsMeasure(XsdUnsignedLong): - @classmethod def convert_from_xml(cls, str_value): - if 'i' in str_value or 'm' in str_value or 'p' in str_value: + if "i" in str_value or "m" in str_value or "p" in str_value: return ST_UniversalMeasure.convert_from_xml(str_value) return Twips(int(str_value)) @@ -385,14 +351,17 @@ def convert_to_xml(cls, value): class ST_UniversalMeasure(BaseSimpleType): - @classmethod def convert_from_xml(cls, str_value): float_part, units_part = str_value[:-2], str_value[-2:] quantity = float(float_part) multiplier = { - 'mm': 36000, 'cm': 360000, 'in': 914400, 'pt': 12700, - 'pc': 152400, 'pi': 152400 + "mm": 36000, + "cm": 360000, + "in": 914400, + "pt": 12700, + "pc": 152400, + "pi": 152400, }[units_part] emu_value = Emu(int(round(quantity * multiplier))) return emu_value @@ -402,8 +371,9 @@ class ST_VerticalAlignRun(XsdStringEnumeration): """ Valid values for `w:vertAlign/@val`. """ - BASELINE = 'baseline' - SUPERSCRIPT = 'superscript' - SUBSCRIPT = 'subscript' + + BASELINE = "baseline" + SUPERSCRIPT = "superscript" + SUBSCRIPT = "subscript" _members = (BASELINE, SUPERSCRIPT, SUBSCRIPT) diff --git a/docx/oxml/styles.py b/docx/oxml/styles.py index 6f27e45e..96b390ba 100644 --- a/docx/oxml/styles.py +++ b/docx/oxml/styles.py @@ -7,8 +7,11 @@ from ..enum.style import WD_STYLE_TYPE from .simpletypes import ST_DecimalNumber, ST_OnOff, ST_String from .xmlchemy import ( - BaseOxmlElement, OptionalAttribute, RequiredAttribute, ZeroOrMore, - ZeroOrOne + BaseOxmlElement, + OptionalAttribute, + RequiredAttribute, + ZeroOrMore, + ZeroOrOne, ) @@ -18,17 +21,17 @@ def styleId_from_name(name): special-case names such as 'Heading 1'. """ return { - 'caption': 'Caption', - 'heading 1': 'Heading1', - 'heading 2': 'Heading2', - 'heading 3': 'Heading3', - 'heading 4': 'Heading4', - 'heading 5': 'Heading5', - 'heading 6': 'Heading6', - 'heading 7': 'Heading7', - 'heading 8': 'Heading8', - 'heading 9': 'Heading9', - }.get(name, name.replace(' ', '')) + "caption": "Caption", + "heading 1": "Heading1", + "heading 2": "Heading2", + "heading 3": "Heading3", + "heading 4": "Heading4", + "heading 5": "Heading5", + "heading 6": "Heading6", + "heading 7": "Heading7", + "heading 8": "Heading8", + "heading 9": "Heading9", + }.get(name, name.replace(" ", "")) class CT_LatentStyles(BaseOxmlElement): @@ -37,14 +40,15 @@ class CT_LatentStyles(BaseOxmlElement): and containing `w:lsdException` child elements that each override those defaults for a named latent style. """ - lsdException = ZeroOrMore('w:lsdException', successors=()) - count = OptionalAttribute('w:count', ST_DecimalNumber) - defLockedState = OptionalAttribute('w:defLockedState', ST_OnOff) - defQFormat = OptionalAttribute('w:defQFormat', ST_OnOff) - defSemiHidden = OptionalAttribute('w:defSemiHidden', ST_OnOff) - defUIPriority = OptionalAttribute('w:defUIPriority', ST_DecimalNumber) - defUnhideWhenUsed = OptionalAttribute('w:defUnhideWhenUsed', ST_OnOff) + lsdException = ZeroOrMore("w:lsdException", successors=()) + + count = OptionalAttribute("w:count", ST_DecimalNumber) + defLockedState = OptionalAttribute("w:defLockedState", ST_OnOff) + defQFormat = OptionalAttribute("w:defQFormat", ST_OnOff) + defSemiHidden = OptionalAttribute("w:defSemiHidden", ST_OnOff) + defUIPriority = OptionalAttribute("w:defUIPriority", ST_DecimalNumber) + defUnhideWhenUsed = OptionalAttribute("w:defUnhideWhenUsed", ST_OnOff) def bool_prop(self, attr_name): """ @@ -78,12 +82,13 @@ class CT_LsdException(BaseOxmlElement): ```` element, defining override visibility behaviors for a named latent style. """ - locked = OptionalAttribute('w:locked', ST_OnOff) - name = RequiredAttribute('w:name', ST_String) - qFormat = OptionalAttribute('w:qFormat', ST_OnOff) - semiHidden = OptionalAttribute('w:semiHidden', ST_OnOff) - uiPriority = OptionalAttribute('w:uiPriority', ST_DecimalNumber) - unhideWhenUsed = OptionalAttribute('w:unhideWhenUsed', ST_OnOff) + + locked = OptionalAttribute("w:locked", ST_OnOff) + name = RequiredAttribute("w:name", ST_String) + qFormat = OptionalAttribute("w:qFormat", ST_OnOff) + semiHidden = OptionalAttribute("w:semiHidden", ST_OnOff) + uiPriority = OptionalAttribute("w:uiPriority", ST_DecimalNumber) + unhideWhenUsed = OptionalAttribute("w:unhideWhenUsed", ST_OnOff) def delete(self): """ @@ -109,29 +114,47 @@ class CT_Style(BaseOxmlElement): """ A ```` element, representing a style definition """ + _tag_seq = ( - 'w:name', 'w:aliases', 'w:basedOn', 'w:next', 'w:link', - 'w:autoRedefine', 'w:hidden', 'w:uiPriority', 'w:semiHidden', - 'w:unhideWhenUsed', 'w:qFormat', 'w:locked', 'w:personal', - 'w:personalCompose', 'w:personalReply', 'w:rsid', 'w:pPr', 'w:rPr', - 'w:tblPr', 'w:trPr', 'w:tcPr', 'w:tblStylePr' + "w:name", + "w:aliases", + "w:basedOn", + "w:next", + "w:link", + "w:autoRedefine", + "w:hidden", + "w:uiPriority", + "w:semiHidden", + "w:unhideWhenUsed", + "w:qFormat", + "w:locked", + "w:personal", + "w:personalCompose", + "w:personalReply", + "w:rsid", + "w:pPr", + "w:rPr", + "w:tblPr", + "w:trPr", + "w:tcPr", + "w:tblStylePr", ) - name = ZeroOrOne('w:name', successors=_tag_seq[1:]) - basedOn = ZeroOrOne('w:basedOn', successors=_tag_seq[3:]) - next = ZeroOrOne('w:next', successors=_tag_seq[4:]) - uiPriority = ZeroOrOne('w:uiPriority', successors=_tag_seq[8:]) - semiHidden = ZeroOrOne('w:semiHidden', successors=_tag_seq[9:]) - unhideWhenUsed = ZeroOrOne('w:unhideWhenUsed', successors=_tag_seq[10:]) - qFormat = ZeroOrOne('w:qFormat', successors=_tag_seq[11:]) - locked = ZeroOrOne('w:locked', successors=_tag_seq[12:]) - pPr = ZeroOrOne('w:pPr', successors=_tag_seq[17:]) - rPr = ZeroOrOne('w:rPr', successors=_tag_seq[18:]) + name = ZeroOrOne("w:name", successors=_tag_seq[1:]) + basedOn = ZeroOrOne("w:basedOn", successors=_tag_seq[3:]) + next = ZeroOrOne("w:next", successors=_tag_seq[4:]) + uiPriority = ZeroOrOne("w:uiPriority", successors=_tag_seq[8:]) + semiHidden = ZeroOrOne("w:semiHidden", successors=_tag_seq[9:]) + unhideWhenUsed = ZeroOrOne("w:unhideWhenUsed", successors=_tag_seq[10:]) + qFormat = ZeroOrOne("w:qFormat", successors=_tag_seq[11:]) + locked = ZeroOrOne("w:locked", successors=_tag_seq[12:]) + pPr = ZeroOrOne("w:pPr", successors=_tag_seq[17:]) + rPr = ZeroOrOne("w:rPr", successors=_tag_seq[18:]) del _tag_seq - type = OptionalAttribute('w:type', WD_STYLE_TYPE) - styleId = OptionalAttribute('w:styleId', ST_String) - default = OptionalAttribute('w:default', ST_OnOff) - customStyle = OptionalAttribute('w:customStyle', ST_OnOff) + type = OptionalAttribute("w:type", WD_STYLE_TYPE) + styleId = OptionalAttribute("w:styleId", ST_String) + default = OptionalAttribute("w:default", ST_OnOff) + customStyle = OptionalAttribute("w:customStyle", ST_OnOff) @property def basedOn_val(self): @@ -291,9 +314,10 @@ class CT_Styles(BaseOxmlElement): ```` element, the root element of a styles part, i.e. styles.xml """ - _tag_seq = ('w:docDefaults', 'w:latentStyles', 'w:style') - latentStyles = ZeroOrOne('w:latentStyles', successors=_tag_seq[2:]) - style = ZeroOrMore('w:style', successors=()) + + _tag_seq = ("w:docDefaults", "w:latentStyles", "w:style") + latentStyles = ZeroOrOne("w:latentStyles", successors=_tag_seq[2:]) + style = ZeroOrMore("w:style", successors=()) del _tag_seq def add_style_of_type(self, name, style_type, builtin): @@ -314,8 +338,7 @@ def default_for(self, style_type): Return `w:style[@w:type="*{style_type}*][-1]` or |None| if not found. """ default_styles_for_type = [ - s for s in self._iter_styles() - if s.type == style_type and s.default + s for s in self._iter_styles() if s.type == style_type and s.default ] if not default_styles_for_type: return None @@ -348,4 +371,4 @@ def _iter_styles(self): """ Generate each of the `w:style` child elements in document order. """ - return (style for style in self.xpath('w:style')) + return (style for style in self.xpath("w:style")) diff --git a/docx/oxml/table.py b/docx/oxml/table.py index e55bf912..f9423da6 100644 --- a/docx/oxml/table.py +++ b/docx/oxml/table.py @@ -2,9 +2,7 @@ """Custom element classes for tables""" -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals from . import parse_xml from ..enum.table import WD_CELL_VERTICAL_ALIGNMENT, WD_ROW_HEIGHT_RULE @@ -12,11 +10,20 @@ from .ns import nsdecls, qn from ..shared import Emu, Twips from .simpletypes import ( - ST_Merge, ST_TblLayoutType, ST_TblWidth, ST_TwipsMeasure, XsdInt + ST_Merge, + ST_TblLayoutType, + ST_TblWidth, + ST_TwipsMeasure, + XsdInt, ) from .xmlchemy import ( - BaseOxmlElement, OneAndOnlyOne, OneOrMore, OptionalAttribute, - RequiredAttribute, ZeroOrOne, ZeroOrMore + BaseOxmlElement, + OneAndOnlyOne, + OneOrMore, + OptionalAttribute, + RequiredAttribute, + ZeroOrOne, + ZeroOrMore, ) @@ -24,17 +31,19 @@ class CT_Height(BaseOxmlElement): """ Used for ```` to specify a row height and row height rule. """ - val = OptionalAttribute('w:val', ST_TwipsMeasure) - hRule = OptionalAttribute('w:hRule', WD_ROW_HEIGHT_RULE) + + val = OptionalAttribute("w:val", ST_TwipsMeasure) + hRule = OptionalAttribute("w:hRule", WD_ROW_HEIGHT_RULE) class CT_Row(BaseOxmlElement): """ ```` element """ - tblPrEx = ZeroOrOne('w:tblPrEx') # custom inserter below - trPr = ZeroOrOne('w:trPr') # custom inserter below - tc = ZeroOrMore('w:tc') + + tblPrEx = ZeroOrOne("w:tblPrEx") # custom inserter below + trPr = ZeroOrOne("w:trPr") # custom inserter below + tc = ZeroOrMore("w:tc") def tc_at_grid_col(self, idx): """ @@ -47,8 +56,8 @@ def tc_at_grid_col(self, idx): return tc grid_col += tc.grid_span if grid_col > idx: - raise ValueError('no cell on grid column %d' % idx) - raise ValueError('index out of bounds') + raise ValueError("no cell on grid column %d" % idx) + raise ValueError("index out of bounds") @property def tr_idx(self): @@ -108,9 +117,10 @@ class CT_Tbl(BaseOxmlElement): """ ```` element """ - tblPr = OneAndOnlyOne('w:tblPr') - tblGrid = OneAndOnlyOne('w:tblGrid') - tr = ZeroOrMore('w:tr') + + tblPr = OneAndOnlyOne("w:tblPr") + tblGrid = OneAndOnlyOne("w:tblGrid") + tr = ZeroOrMore("w:tr") @property def bidiVisual_val(self): @@ -182,54 +192,52 @@ def tblStyle_val(self, styleId): @classmethod def _tbl_xml(cls, rows, cols, width): - col_width = Emu(width/cols) if cols > 0 else Emu(0) + col_width = Emu(width / cols) if cols > 0 else Emu(0) return ( - '\n' - ' \n' + "\n" + " \n" ' \n' ' \n' - ' \n' - '%s' # tblGrid - '%s' # trs - '\n' + " \n" + "%s" # tblGrid + "%s" # trs + "\n" ) % ( - nsdecls('w'), + nsdecls("w"), cls._tblGrid_xml(cols, col_width), - cls._trs_xml(rows, cols, col_width) + cls._trs_xml(rows, cols, col_width), ) @classmethod def _tblGrid_xml(cls, col_count, col_width): - xml = ' \n' + xml = " \n" for i in range(col_count): xml += ' \n' % col_width.twips - xml += ' \n' + xml += " \n" return xml @classmethod def _trs_xml(cls, row_count, col_count, col_width): - xml = '' + xml = "" for i in range(row_count): - xml += ( - ' \n' - '%s' - ' \n' - ) % cls._tcs_xml(col_count, col_width) + xml += (" \n" "%s" " \n") % cls._tcs_xml( + col_count, col_width + ) return xml @classmethod def _tcs_xml(cls, col_count, col_width): - xml = '' + xml = "" for i in range(col_count): xml += ( - ' \n' - ' \n' + " \n" + " \n" ' \n' - ' \n' - ' \n' - ' \n' + " \n" + " \n" + " \n" ) % col_width.twips return xml @@ -239,7 +247,8 @@ class CT_TblGrid(BaseOxmlElement): ```` element, child of ````, holds ```` elements that define column count, width, etc. """ - gridCol = ZeroOrMore('w:gridCol', successors=('w:tblGridChange',)) + + gridCol = ZeroOrMore("w:gridCol", successors=("w:tblGridChange",)) class CT_TblGridCol(BaseOxmlElement): @@ -247,7 +256,8 @@ class CT_TblGridCol(BaseOxmlElement): ```` element, child of ````, defines a table column. """ - w = OptionalAttribute('w:w', ST_TwipsMeasure) + + w = OptionalAttribute("w:w", ST_TwipsMeasure) @property def gridCol_idx(self): @@ -263,7 +273,8 @@ class CT_TblLayoutType(BaseOxmlElement): ```` element, specifying whether column widths are fixed or can be automatically adjusted based on content. """ - type = OptionalAttribute('w:type', ST_TblLayoutType) + + type = OptionalAttribute("w:type", ST_TblLayoutType) class CT_TblPr(BaseOxmlElement): @@ -271,17 +282,31 @@ class CT_TblPr(BaseOxmlElement): ```` element, child of ````, holds child elements that define table properties such as style and borders. """ + _tag_seq = ( - 'w:tblStyle', 'w:tblpPr', 'w:tblOverlap', 'w:bidiVisual', - 'w:tblStyleRowBandSize', 'w:tblStyleColBandSize', 'w:tblW', 'w:jc', - 'w:tblCellSpacing', 'w:tblInd', 'w:tblBorders', 'w:shd', - 'w:tblLayout', 'w:tblCellMar', 'w:tblLook', 'w:tblCaption', - 'w:tblDescription', 'w:tblPrChange' + "w:tblStyle", + "w:tblpPr", + "w:tblOverlap", + "w:bidiVisual", + "w:tblStyleRowBandSize", + "w:tblStyleColBandSize", + "w:tblW", + "w:jc", + "w:tblCellSpacing", + "w:tblInd", + "w:tblBorders", + "w:shd", + "w:tblLayout", + "w:tblCellMar", + "w:tblLook", + "w:tblCaption", + "w:tblDescription", + "w:tblPrChange", ) - tblStyle = ZeroOrOne('w:tblStyle', successors=_tag_seq[1:]) - bidiVisual = ZeroOrOne('w:bidiVisual', successors=_tag_seq[4:]) - jc = ZeroOrOne('w:jc', successors=_tag_seq[8:]) - tblLayout = ZeroOrOne('w:tblLayout', successors=_tag_seq[13:]) + tblStyle = ZeroOrOne("w:tblStyle", successors=_tag_seq[1:]) + bidiVisual = ZeroOrOne("w:bidiVisual", successors=_tag_seq[4:]) + jc = ZeroOrOne("w:jc", successors=_tag_seq[8:]) + tblLayout = ZeroOrOne("w:tblLayout", successors=_tag_seq[13:]) del _tag_seq @property @@ -313,12 +338,12 @@ def autofit(self): tblLayout = self.tblLayout if tblLayout is None: return True - return False if tblLayout.type == 'fixed' else True + return False if tblLayout.type == "fixed" else True @autofit.setter def autofit(self, value): tblLayout = self.get_or_add_tblLayout() - tblLayout.type = 'autofit' if value else 'fixed' + tblLayout.type = "autofit" if value else "fixed" @property def style(self): @@ -344,11 +369,12 @@ class CT_TblWidth(BaseOxmlElement): Used for ```` and ```` elements and many others, to specify a table-related width. """ + # the type for `w` attr is actually ST_MeasurementOrPercent, but using # XsdInt for now because only dxa (twips) values are being used. It's not # entirely clear what the semantics are for other values like -01.4mm - w = RequiredAttribute('w:w', XsdInt) - type = RequiredAttribute('w:type', ST_TblWidth) + w = RequiredAttribute("w:w", XsdInt) + type = RequiredAttribute("w:type", ST_TblWidth) @property def width(self): @@ -356,22 +382,22 @@ def width(self): Return the EMU length value represented by the combined ``w:w`` and ``w:type`` attributes. """ - if self.type != 'dxa': + if self.type != "dxa": return None return Twips(self.w) @width.setter def width(self, value): - self.type = 'dxa' + self.type = "dxa" self.w = Emu(value).twips class CT_Tc(BaseOxmlElement): """`w:tc` table cell element""" - tcPr = ZeroOrOne('w:tcPr') # bunches of successors, overriding insert - p = OneOrMore('w:p') - tbl = OneOrMore('w:tbl') + tcPr = ZeroOrOne("w:tcPr") # bunches of successors, overriding insert + p = OneOrMore("w:p") + tbl = OneOrMore("w:tbl") @property def bottom(self): @@ -422,7 +448,7 @@ def iter_block_items(self): Generate a reference to each of the block-level content elements in this cell, in the order they appear. """ - block_item_tags = (qn('w:p'), qn('w:tbl'), qn('w:sdt')) + block_item_tags = (qn("w:p"), qn("w:tbl"), qn("w:sdt")) for child in self: if child.tag in block_item_tags: yield child @@ -451,11 +477,7 @@ def new(cls): Return a new ```` element, containing an empty paragraph as the required EG_BlockLevelElt. """ - return parse_xml( - '\n' - ' \n' - '' % nsdecls('w') - ) + return parse_xml("\n" " \n" "" % nsdecls("w")) @property def right(self): @@ -532,6 +554,7 @@ def _grow_to(self, width, height, top_tc=None): horizontal spans and creating continuation cells to form vertical spans. """ + def vMerge_val(top_tc): if top_tc is not self: return ST_Merge.CONTINUE @@ -542,7 +565,7 @@ def vMerge_val(top_tc): top_tc = self if top_tc is None else top_tc self._span_to_width(width, top_tc, vMerge_val(top_tc)) if height > 1: - self._tc_below._grow_to(width, height-1, top_tc) + self._tc_below._grow_to(width, height - 1, top_tc) def _insert_tcPr(self, tcPr): """ @@ -591,7 +614,7 @@ def _next_tc(self): The `w:tc` element immediately following this one in this row, or |None| if this is the last `w:tc` element in the row. """ - following_tcs = self.xpath('./following-sibling::w:tc') + following_tcs = self.xpath("./following-sibling::w:tc") return following_tcs[0] if following_tcs else None def _remove(self): @@ -607,7 +630,7 @@ def _remove_trailing_empty_p(self): """ block_items = list(self.iter_block_items()) last_content_elm = block_items[-1] - if last_content_elm.tag != qn('w:p'): + if last_content_elm.tag != qn("w:p"): return p = last_content_elm if len(p.r_lst) > 0: @@ -620,20 +643,21 @@ def _span_dimensions(self, other_tc): the merged cell formed by using this tc and *other_tc* as opposite corner extents. """ + def raise_on_inverted_L(a, b): if a.top == b.top and a.bottom != b.bottom: - raise InvalidSpanError('requested span not rectangular') + raise InvalidSpanError("requested span not rectangular") if a.left == b.left and a.right != b.right: - raise InvalidSpanError('requested span not rectangular') + raise InvalidSpanError("requested span not rectangular") def raise_on_tee_shaped(a, b): top_most, other = (a, b) if a.top < b.top else (b, a) if top_most.top < other.top and top_most.bottom > other.bottom: - raise InvalidSpanError('requested span not rectangular') + raise InvalidSpanError("requested span not rectangular") left_most, other = (a, b) if a.left < b.left else (b, a) if left_most.left < other.left and left_most.right > other.right: - raise InvalidSpanError('requested span not rectangular') + raise InvalidSpanError("requested span not rectangular") raise_on_inverted_L(self, other_tc) raise_on_tee_shaped(self, other_tc) @@ -671,11 +695,12 @@ def _swallow_next_tc(self, grid_width, top_tc): |InvalidSpanError| if the width of the resulting cell is greater than *grid_width* or if there is no next `` element in the row. """ + def raise_on_invalid_swallow(next_tc): if next_tc is None: - raise InvalidSpanError('not enough grid columns') + raise InvalidSpanError("not enough grid columns") if self.grid_span + next_tc.grid_span > grid_width: - raise InvalidSpanError('span is not rectangular') + raise InvalidSpanError("span is not rectangular") next_tc = self._next_tc raise_on_invalid_swallow(next_tc) @@ -689,7 +714,7 @@ def _tbl(self): """ The tbl element this tc element appears in. """ - return self.xpath('./ancestor::w:tbl[position()=1]')[0] + return self.xpath("./ancestor::w:tbl[position()=1]")[0] @property def _tc_above(self): @@ -713,7 +738,7 @@ def _tr(self): """ The tr element this tc element appears in. """ - return self.xpath('./ancestor::w:tr[position()=1]')[0] + return self.xpath("./ancestor::w:tr[position()=1]")[0] @property def _tr_above(self): @@ -724,8 +749,8 @@ def _tr_above(self): tr_lst = self._tbl.tr_lst tr_idx = tr_lst.index(self._tr) if tr_idx == 0: - raise ValueError('no tr above topmost tr') - return tr_lst[tr_idx-1] + raise ValueError("no tr above topmost tr") + return tr_lst[tr_idx - 1] @property def _tr_below(self): @@ -736,7 +761,7 @@ def _tr_below(self): tr_lst = self._tbl.tr_lst tr_idx = tr_lst.index(self._tr) try: - return tr_lst[tr_idx+1] + return tr_lst[tr_idx + 1] except IndexError: return None @@ -752,16 +777,31 @@ class CT_TcPr(BaseOxmlElement): """ ```` element, defining table cell properties """ + _tag_seq = ( - 'w:cnfStyle', 'w:tcW', 'w:gridSpan', 'w:hMerge', 'w:vMerge', - 'w:tcBorders', 'w:shd', 'w:noWrap', 'w:tcMar', 'w:textDirection', - 'w:tcFitText', 'w:vAlign', 'w:hideMark', 'w:headers', 'w:cellIns', - 'w:cellDel', 'w:cellMerge', 'w:tcPrChange' + "w:cnfStyle", + "w:tcW", + "w:gridSpan", + "w:hMerge", + "w:vMerge", + "w:tcBorders", + "w:shd", + "w:noWrap", + "w:tcMar", + "w:textDirection", + "w:tcFitText", + "w:vAlign", + "w:hideMark", + "w:headers", + "w:cellIns", + "w:cellDel", + "w:cellMerge", + "w:tcPrChange", ) - tcW = ZeroOrOne('w:tcW', successors=_tag_seq[2:]) - gridSpan = ZeroOrOne('w:gridSpan', successors=_tag_seq[3:]) - vMerge = ZeroOrOne('w:vMerge', successors=_tag_seq[5:]) - vAlign = ZeroOrOne('w:vAlign', successors=_tag_seq[12:]) + tcW = ZeroOrOne("w:tcW", successors=_tag_seq[2:]) + gridSpan = ZeroOrOne("w:gridSpan", successors=_tag_seq[3:]) + vMerge = ZeroOrOne("w:vMerge", successors=_tag_seq[5:]) + vAlign = ZeroOrOne("w:vAlign", successors=_tag_seq[12:]) del _tag_seq @property @@ -838,13 +878,25 @@ class CT_TrPr(BaseOxmlElement): """ ```` element, defining table row properties """ + _tag_seq = ( - 'w:cnfStyle', 'w:divId', 'w:gridBefore', 'w:gridAfter', 'w:wBefore', - 'w:wAfter', 'w:cantSplit', 'w:trHeight', 'w:tblHeader', - 'w:tblCellSpacing', 'w:jc', 'w:hidden', 'w:ins', 'w:del', - 'w:trPrChange' + "w:cnfStyle", + "w:divId", + "w:gridBefore", + "w:gridAfter", + "w:wBefore", + "w:wAfter", + "w:cantSplit", + "w:trHeight", + "w:tblHeader", + "w:tblCellSpacing", + "w:jc", + "w:hidden", + "w:ins", + "w:del", + "w:trPrChange", ) - trHeight = ZeroOrOne('w:trHeight', successors=_tag_seq[8:]) + trHeight = ZeroOrOne("w:trHeight", successors=_tag_seq[8:]) del _tag_seq @property @@ -884,11 +936,13 @@ def trHeight_val(self, value): class CT_VerticalJc(BaseOxmlElement): """`w:vAlign` element, specifying vertical alignment of cell.""" - val = RequiredAttribute('w:val', WD_CELL_VERTICAL_ALIGNMENT) + + val = RequiredAttribute("w:val", WD_CELL_VERTICAL_ALIGNMENT) class CT_VMerge(BaseOxmlElement): """ ```` element, specifying vertical merging behavior of a cell. """ - val = OptionalAttribute('w:val', ST_Merge, default=ST_Merge.CONTINUE) + + val = OptionalAttribute("w:val", ST_Merge, default=ST_Merge.CONTINUE) diff --git a/docx/oxml/text/font.py b/docx/oxml/text/font.py index 810ec2b3..73913af9 100644 --- a/docx/oxml/text/font.py +++ b/docx/oxml/text/font.py @@ -8,12 +8,8 @@ from ...enum.dml import MSO_THEME_COLOR from ...enum.text import WD_COLOR, WD_UNDERLINE from ..ns import nsdecls, qn -from ..simpletypes import ( - ST_HexColor, ST_HpsMeasure, ST_String, ST_VerticalAlignRun -) -from ..xmlchemy import ( - BaseOxmlElement, OptionalAttribute, RequiredAttribute, ZeroOrOne -) +from ..simpletypes import ST_HexColor, ST_HpsMeasure, ST_String, ST_VerticalAlignRun +from ..xmlchemy import BaseOxmlElement, OptionalAttribute, RequiredAttribute, ZeroOrOne class CT_Color(BaseOxmlElement): @@ -21,8 +17,9 @@ class CT_Color(BaseOxmlElement): `w:color` element, specifying the color of a font and perhaps other objects. """ - val = RequiredAttribute('w:val', ST_HexColor) - themeColor = OptionalAttribute('w:themeColor', MSO_THEME_COLOR) + + val = RequiredAttribute("w:val", ST_HexColor) + themeColor = OptionalAttribute("w:themeColor", MSO_THEME_COLOR) class CT_Fonts(BaseOxmlElement): @@ -30,15 +27,17 @@ class CT_Fonts(BaseOxmlElement): ```` element, specifying typeface name for the various language types. """ - ascii = OptionalAttribute('w:ascii', ST_String) - hAnsi = OptionalAttribute('w:hAnsi', ST_String) + + ascii = OptionalAttribute("w:ascii", ST_String) + hAnsi = OptionalAttribute("w:hAnsi", ST_String) class CT_Highlight(BaseOxmlElement): """ `w:highlight` element, specifying font highlighting/background color. """ - val = RequiredAttribute('w:val', WD_COLOR) + + val = RequiredAttribute("w:val", WD_COLOR) class CT_HpsMeasure(BaseOxmlElement): @@ -46,49 +45,83 @@ class CT_HpsMeasure(BaseOxmlElement): Used for ```` element and others, specifying font size in half-points. """ - val = RequiredAttribute('w:val', ST_HpsMeasure) + + val = RequiredAttribute("w:val", ST_HpsMeasure) class CT_RPr(BaseOxmlElement): """ ```` element, containing the properties for a run. """ + _tag_seq = ( - 'w:rStyle', 'w:rFonts', 'w:b', 'w:bCs', 'w:i', 'w:iCs', 'w:caps', - 'w:smallCaps', 'w:strike', 'w:dstrike', 'w:outline', 'w:shadow', - 'w:emboss', 'w:imprint', 'w:noProof', 'w:snapToGrid', 'w:vanish', - 'w:webHidden', 'w:color', 'w:spacing', 'w:w', 'w:kern', 'w:position', - 'w:sz', 'w:szCs', 'w:highlight', 'w:u', 'w:effect', 'w:bdr', 'w:shd', - 'w:fitText', 'w:vertAlign', 'w:rtl', 'w:cs', 'w:em', 'w:lang', - 'w:eastAsianLayout', 'w:specVanish', 'w:oMath' + "w:rStyle", + "w:rFonts", + "w:b", + "w:bCs", + "w:i", + "w:iCs", + "w:caps", + "w:smallCaps", + "w:strike", + "w:dstrike", + "w:outline", + "w:shadow", + "w:emboss", + "w:imprint", + "w:noProof", + "w:snapToGrid", + "w:vanish", + "w:webHidden", + "w:color", + "w:spacing", + "w:w", + "w:kern", + "w:position", + "w:sz", + "w:szCs", + "w:highlight", + "w:u", + "w:effect", + "w:bdr", + "w:shd", + "w:fitText", + "w:vertAlign", + "w:rtl", + "w:cs", + "w:em", + "w:lang", + "w:eastAsianLayout", + "w:specVanish", + "w:oMath", ) - rStyle = ZeroOrOne('w:rStyle', successors=_tag_seq[1:]) - rFonts = ZeroOrOne('w:rFonts', successors=_tag_seq[2:]) - b = ZeroOrOne('w:b', successors=_tag_seq[3:]) - bCs = ZeroOrOne('w:bCs', successors=_tag_seq[4:]) - i = ZeroOrOne('w:i', successors=_tag_seq[5:]) - iCs = ZeroOrOne('w:iCs', successors=_tag_seq[6:]) - caps = ZeroOrOne('w:caps', successors=_tag_seq[7:]) - smallCaps = ZeroOrOne('w:smallCaps', successors=_tag_seq[8:]) - strike = ZeroOrOne('w:strike', successors=_tag_seq[9:]) - dstrike = ZeroOrOne('w:dstrike', successors=_tag_seq[10:]) - outline = ZeroOrOne('w:outline', successors=_tag_seq[11:]) - shadow = ZeroOrOne('w:shadow', successors=_tag_seq[12:]) - emboss = ZeroOrOne('w:emboss', successors=_tag_seq[13:]) - imprint = ZeroOrOne('w:imprint', successors=_tag_seq[14:]) - noProof = ZeroOrOne('w:noProof', successors=_tag_seq[15:]) - snapToGrid = ZeroOrOne('w:snapToGrid', successors=_tag_seq[16:]) - vanish = ZeroOrOne('w:vanish', successors=_tag_seq[17:]) - webHidden = ZeroOrOne('w:webHidden', successors=_tag_seq[18:]) - color = ZeroOrOne('w:color', successors=_tag_seq[19:]) - sz = ZeroOrOne('w:sz', successors=_tag_seq[24:]) - highlight = ZeroOrOne('w:highlight', successors=_tag_seq[26:]) - u = ZeroOrOne('w:u', successors=_tag_seq[27:]) - vertAlign = ZeroOrOne('w:vertAlign', successors=_tag_seq[32:]) - rtl = ZeroOrOne('w:rtl', successors=_tag_seq[33:]) - cs = ZeroOrOne('w:cs', successors=_tag_seq[34:]) - specVanish = ZeroOrOne('w:specVanish', successors=_tag_seq[38:]) - oMath = ZeroOrOne('w:oMath', successors=_tag_seq[39:]) + rStyle = ZeroOrOne("w:rStyle", successors=_tag_seq[1:]) + rFonts = ZeroOrOne("w:rFonts", successors=_tag_seq[2:]) + b = ZeroOrOne("w:b", successors=_tag_seq[3:]) + bCs = ZeroOrOne("w:bCs", successors=_tag_seq[4:]) + i = ZeroOrOne("w:i", successors=_tag_seq[5:]) + iCs = ZeroOrOne("w:iCs", successors=_tag_seq[6:]) + caps = ZeroOrOne("w:caps", successors=_tag_seq[7:]) + smallCaps = ZeroOrOne("w:smallCaps", successors=_tag_seq[8:]) + strike = ZeroOrOne("w:strike", successors=_tag_seq[9:]) + dstrike = ZeroOrOne("w:dstrike", successors=_tag_seq[10:]) + outline = ZeroOrOne("w:outline", successors=_tag_seq[11:]) + shadow = ZeroOrOne("w:shadow", successors=_tag_seq[12:]) + emboss = ZeroOrOne("w:emboss", successors=_tag_seq[13:]) + imprint = ZeroOrOne("w:imprint", successors=_tag_seq[14:]) + noProof = ZeroOrOne("w:noProof", successors=_tag_seq[15:]) + snapToGrid = ZeroOrOne("w:snapToGrid", successors=_tag_seq[16:]) + vanish = ZeroOrOne("w:vanish", successors=_tag_seq[17:]) + webHidden = ZeroOrOne("w:webHidden", successors=_tag_seq[18:]) + color = ZeroOrOne("w:color", successors=_tag_seq[19:]) + sz = ZeroOrOne("w:sz", successors=_tag_seq[24:]) + highlight = ZeroOrOne("w:highlight", successors=_tag_seq[26:]) + u = ZeroOrOne("w:u", successors=_tag_seq[27:]) + vertAlign = ZeroOrOne("w:vertAlign", successors=_tag_seq[32:]) + rtl = ZeroOrOne("w:rtl", successors=_tag_seq[33:]) + cs = ZeroOrOne("w:cs", successors=_tag_seq[34:]) + specVanish = ZeroOrOne("w:specVanish", successors=_tag_seq[38:]) + oMath = ZeroOrOne("w:oMath", successors=_tag_seq[39:]) del _tag_seq def _new_color(self): @@ -96,7 +129,7 @@ def _new_color(self): Override metaclass method to set `w:color/@val` to RGB black on create. """ - return parse_xml('' % nsdecls('w')) + return parse_xml('' % nsdecls("w")) @property def highlight_val(self): @@ -276,9 +309,9 @@ def _get_bool_val(self, name): def _set_bool_val(self, name, value): if value is None: - getattr(self, '_remove_%s' % name)() + getattr(self, "_remove_%s" % name)() return - element = getattr(self, 'get_or_add_%s' % name)() + element = getattr(self, "get_or_add_%s" % name)() element.val = value @@ -286,12 +319,13 @@ class CT_Underline(BaseOxmlElement): """ ```` element, specifying the underlining style for a run. """ + @property def val(self): """ The underline type corresponding to the ``w:val`` attribute value. """ - val = self.get(qn('w:val')) + val = self.get(qn("w:val")) underline = WD_UNDERLINE.from_xml(val) if underline == WD_UNDERLINE.SINGLE: return True @@ -310,11 +344,12 @@ def val(self, value): value = WD_UNDERLINE.NONE val = WD_UNDERLINE.to_xml(value) - self.set(qn('w:val'), val) + self.set(qn("w:val"), val) class CT_VerticalAlignRun(BaseOxmlElement): """ ```` element, specifying subscript or superscript. """ - val = RequiredAttribute('w:val', ST_VerticalAlignRun) + + val = RequiredAttribute("w:val", ST_VerticalAlignRun) diff --git a/docx/oxml/text/paragraph.py b/docx/oxml/text/paragraph.py index 5e421377..8386420f 100644 --- a/docx/oxml/text/paragraph.py +++ b/docx/oxml/text/paragraph.py @@ -12,8 +12,9 @@ class CT_P(BaseOxmlElement): """ ```` element, containing the properties and text for a paragraph. """ - pPr = ZeroOrOne('w:pPr') - r = ZeroOrMore('w:r') + + pPr = ZeroOrOne("w:pPr") + r = ZeroOrMore("w:r") def _insert_pPr(self, pPr): self.insert(0, pPr) @@ -23,7 +24,7 @@ def add_p_before(self): """ Return a new ```` element inserted directly prior to this one. """ - new_p = OxmlElement('w:p') + new_p = OxmlElement("w:p") self.addprevious(new_p) return new_p @@ -48,7 +49,7 @@ def clear_content(self): Remove all child elements, except the ```` element if present. """ for child in self[:]: - if child.tag == qn('w:pPr'): + if child.tag == qn("w:pPr"): continue self.remove(child) diff --git a/docx/oxml/text/parfmt.py b/docx/oxml/text/parfmt.py index 466b11b1..cae729d5 100644 --- a/docx/oxml/text/parfmt.py +++ b/docx/oxml/text/parfmt.py @@ -5,13 +5,19 @@ """ from ...enum.text import ( - WD_ALIGN_PARAGRAPH, WD_LINE_SPACING, WD_TAB_ALIGNMENT, WD_TAB_LEADER + WD_ALIGN_PARAGRAPH, + WD_LINE_SPACING, + WD_TAB_ALIGNMENT, + WD_TAB_LEADER, ) from ...shared import Length from ..simpletypes import ST_SignedTwipsMeasure, ST_TwipsMeasure from ..xmlchemy import ( - BaseOxmlElement, OneOrMore, OptionalAttribute, RequiredAttribute, - ZeroOrOne + BaseOxmlElement, + OneOrMore, + OptionalAttribute, + RequiredAttribute, + ZeroOrOne, ) @@ -19,45 +25,75 @@ class CT_Ind(BaseOxmlElement): """ ```` element, specifying paragraph indentation. """ - left = OptionalAttribute('w:left', ST_SignedTwipsMeasure) - right = OptionalAttribute('w:right', ST_SignedTwipsMeasure) - firstLine = OptionalAttribute('w:firstLine', ST_TwipsMeasure) - hanging = OptionalAttribute('w:hanging', ST_TwipsMeasure) + + left = OptionalAttribute("w:left", ST_SignedTwipsMeasure) + right = OptionalAttribute("w:right", ST_SignedTwipsMeasure) + firstLine = OptionalAttribute("w:firstLine", ST_TwipsMeasure) + hanging = OptionalAttribute("w:hanging", ST_TwipsMeasure) class CT_Jc(BaseOxmlElement): """ ```` element, specifying paragraph justification. """ - val = RequiredAttribute('w:val', WD_ALIGN_PARAGRAPH) + + val = RequiredAttribute("w:val", WD_ALIGN_PARAGRAPH) class CT_PPr(BaseOxmlElement): """ ```` element, containing the properties for a paragraph. """ + _tag_seq = ( - 'w:pStyle', 'w:keepNext', 'w:keepLines', 'w:pageBreakBefore', - 'w:framePr', 'w:widowControl', 'w:numPr', 'w:suppressLineNumbers', - 'w:pBdr', 'w:shd', 'w:tabs', 'w:suppressAutoHyphens', 'w:kinsoku', - 'w:wordWrap', 'w:overflowPunct', 'w:topLinePunct', 'w:autoSpaceDE', - 'w:autoSpaceDN', 'w:bidi', 'w:adjustRightInd', 'w:snapToGrid', - 'w:spacing', 'w:ind', 'w:contextualSpacing', 'w:mirrorIndents', - 'w:suppressOverlap', 'w:jc', 'w:textDirection', 'w:textAlignment', - 'w:textboxTightWrap', 'w:outlineLvl', 'w:divId', 'w:cnfStyle', - 'w:rPr', 'w:sectPr', 'w:pPrChange' + "w:pStyle", + "w:keepNext", + "w:keepLines", + "w:pageBreakBefore", + "w:framePr", + "w:widowControl", + "w:numPr", + "w:suppressLineNumbers", + "w:pBdr", + "w:shd", + "w:tabs", + "w:suppressAutoHyphens", + "w:kinsoku", + "w:wordWrap", + "w:overflowPunct", + "w:topLinePunct", + "w:autoSpaceDE", + "w:autoSpaceDN", + "w:bidi", + "w:adjustRightInd", + "w:snapToGrid", + "w:spacing", + "w:ind", + "w:contextualSpacing", + "w:mirrorIndents", + "w:suppressOverlap", + "w:jc", + "w:textDirection", + "w:textAlignment", + "w:textboxTightWrap", + "w:outlineLvl", + "w:divId", + "w:cnfStyle", + "w:rPr", + "w:sectPr", + "w:pPrChange", ) - pStyle = ZeroOrOne('w:pStyle', successors=_tag_seq[1:]) - keepNext = ZeroOrOne('w:keepNext', successors=_tag_seq[2:]) - keepLines = ZeroOrOne('w:keepLines', successors=_tag_seq[3:]) - pageBreakBefore = ZeroOrOne('w:pageBreakBefore', successors=_tag_seq[4:]) - widowControl = ZeroOrOne('w:widowControl', successors=_tag_seq[6:]) - numPr = ZeroOrOne('w:numPr', successors=_tag_seq[7:]) - tabs = ZeroOrOne('w:tabs', successors=_tag_seq[11:]) - spacing = ZeroOrOne('w:spacing', successors=_tag_seq[22:]) - ind = ZeroOrOne('w:ind', successors=_tag_seq[23:]) - jc = ZeroOrOne('w:jc', successors=_tag_seq[27:]) - sectPr = ZeroOrOne('w:sectPr', successors=_tag_seq[35:]) + pStyle = ZeroOrOne("w:pStyle", successors=_tag_seq[1:]) + keepNext = ZeroOrOne("w:keepNext", successors=_tag_seq[2:]) + keepLines = ZeroOrOne("w:keepLines", successors=_tag_seq[3:]) + pageBreakBefore = ZeroOrOne("w:pageBreakBefore", successors=_tag_seq[4:]) + widowControl = ZeroOrOne("w:widowControl", successors=_tag_seq[6:]) + numPr = ZeroOrOne("w:numPr", successors=_tag_seq[7:]) + tabs = ZeroOrOne("w:tabs", successors=_tag_seq[11:]) + spacing = ZeroOrOne("w:spacing", successors=_tag_seq[22:]) + ind = ZeroOrOne("w:ind", successors=_tag_seq[23:]) + jc = ZeroOrOne("w:jc", successors=_tag_seq[27:]) + sectPr = ZeroOrOne("w:sectPr", successors=_tag_seq[35:]) del _tag_seq @property @@ -311,28 +347,29 @@ class CT_Spacing(BaseOxmlElement): ```` element, specifying paragraph spacing attributes such as space before and line spacing. """ - after = OptionalAttribute('w:after', ST_TwipsMeasure) - before = OptionalAttribute('w:before', ST_TwipsMeasure) - line = OptionalAttribute('w:line', ST_SignedTwipsMeasure) - lineRule = OptionalAttribute('w:lineRule', WD_LINE_SPACING) + + after = OptionalAttribute("w:after", ST_TwipsMeasure) + before = OptionalAttribute("w:before", ST_TwipsMeasure) + line = OptionalAttribute("w:line", ST_SignedTwipsMeasure) + lineRule = OptionalAttribute("w:lineRule", WD_LINE_SPACING) class CT_TabStop(BaseOxmlElement): """ ```` element, representing an individual tab stop. """ - val = RequiredAttribute('w:val', WD_TAB_ALIGNMENT) - leader = OptionalAttribute( - 'w:leader', WD_TAB_LEADER, default=WD_TAB_LEADER.SPACES - ) - pos = RequiredAttribute('w:pos', ST_SignedTwipsMeasure) + + val = RequiredAttribute("w:val", WD_TAB_ALIGNMENT) + leader = OptionalAttribute("w:leader", WD_TAB_LEADER, default=WD_TAB_LEADER.SPACES) + pos = RequiredAttribute("w:pos", ST_SignedTwipsMeasure) class CT_TabStops(BaseOxmlElement): """ ```` element, container for a sorted sequence of tab stops. """ - tab = OneOrMore('w:tab', successors=()) + + tab = OneOrMore("w:tab", successors=()) def insert_tab_in_order(self, pos, align, leader): """ diff --git a/docx/oxml/text/run.py b/docx/oxml/text/run.py index 8f0a62e8..3d3d3cdf 100644 --- a/docx/oxml/text/run.py +++ b/docx/oxml/text/run.py @@ -6,29 +6,29 @@ from ..ns import qn from ..simpletypes import ST_BrClear, ST_BrType -from ..xmlchemy import ( - BaseOxmlElement, OptionalAttribute, ZeroOrMore, ZeroOrOne -) +from ..xmlchemy import BaseOxmlElement, OptionalAttribute, ZeroOrMore, ZeroOrOne class CT_Br(BaseOxmlElement): """ ```` element, indicating a line, page, or column break in a run. """ - type = OptionalAttribute('w:type', ST_BrType) - clear = OptionalAttribute('w:clear', ST_BrClear) + + type = OptionalAttribute("w:type", ST_BrType) + clear = OptionalAttribute("w:clear", ST_BrClear) class CT_R(BaseOxmlElement): """ ```` element, containing the properties and text for a run. """ - rPr = ZeroOrOne('w:rPr') - t = ZeroOrMore('w:t') - br = ZeroOrMore('w:br') - cr = ZeroOrMore('w:cr') - tab = ZeroOrMore('w:tab') - drawing = ZeroOrMore('w:drawing') + + rPr = ZeroOrOne("w:rPr") + t = ZeroOrMore("w:t") + br = ZeroOrMore("w:br") + cr = ZeroOrMore("w:cr") + tab = ZeroOrMore("w:tab") + drawing = ZeroOrMore("w:drawing") def _insert_rPr(self, rPr): self.insert(0, rPr) @@ -40,7 +40,7 @@ def add_t(self, text): """ t = self._add_t(text=text) if len(text.strip()) < len(text): - t.set(qn('xml:space'), 'preserve') + t.set(qn("xml:space"), "preserve") return t def add_drawing(self, inline_or_anchor): @@ -87,15 +87,15 @@ def text(self): child elements like ```` translated to their Python equivalent. """ - text = '' + text = "" for child in self: - if child.tag == qn('w:t'): + if child.tag == qn("w:t"): t_text = child.text - text += t_text if t_text is not None else '' - elif child.tag == qn('w:tab'): - text += '\t' - elif child.tag in (qn('w:br'), qn('w:cr')): - text += '\n' + text += t_text if t_text is not None else "" + elif child.tag == qn("w:tab"): + text += "\t" + elif child.tag in (qn("w:br"), qn("w:cr")): + text += "\n" return text @text.setter @@ -119,6 +119,7 @@ class _RunContentAppender(object): appended. Likewise a newline or carriage return character ('\n', '\r') causes a ```` element to be appended. """ + def __init__(self, r): self._r = r self._bfr = [] @@ -150,17 +151,17 @@ def add_char(self, char): which must be called at the end of text to ensure any pending ```` element is written. """ - if char == '\t': + if char == "\t": self.flush() self._r.add_tab() - elif char in '\r\n': + elif char in "\r\n": self.flush() self._r.add_br() else: self._bfr.append(char) def flush(self): - text = ''.join(self._bfr) + text = "".join(self._bfr) if text: self._r.add_t(text) del self._bfr[:] diff --git a/docx/package.py b/docx/package.py index 9f5ccc66..07f0718a 100644 --- a/docx/package.py +++ b/docx/package.py @@ -104,10 +104,12 @@ def _next_image_partname(self, ext): partname is unique by number, without regard to the extension. *ext* does not include the leading period. """ + def image_partname(n): - return PackURI('/word/media/image%d.%s' % (n, ext)) + return PackURI("/word/media/image%d.%s" % (n, ext)) + used_numbers = [image_part.partname.idx for image_part in self] - for n in range(1, len(self)+1): + for n in range(1, len(self) + 1): if n not in used_numbers: return image_partname(n) - return image_partname(len(self)+1) + return image_partname(len(self) + 1) diff --git a/docx/parts/hdrftr.py b/docx/parts/hdrftr.py index 549805b2..22ea874a 100644 --- a/docx/parts/hdrftr.py +++ b/docx/parts/hdrftr.py @@ -26,9 +26,9 @@ def new(cls, package): def _default_footer_xml(cls): """Return bytes containing XML for a default footer part.""" path = os.path.join( - os.path.split(__file__)[0], '..', 'templates', 'default-footer.xml' + os.path.split(__file__)[0], "..", "templates", "default-footer.xml" ) - with open(path, 'rb') as f: + with open(path, "rb") as f: xml_bytes = f.read() return xml_bytes @@ -48,8 +48,8 @@ def new(cls, package): def _default_header_xml(cls): """Return bytes containing XML for a default header part.""" path = os.path.join( - os.path.split(__file__)[0], '..', 'templates', 'default-header.xml' + os.path.split(__file__)[0], "..", "templates", "default-header.xml" ) - with open(path, 'rb') as f: + with open(path, "rb") as f: xml_bytes = f.read() return xml_bytes diff --git a/docx/parts/image.py b/docx/parts/image.py index 6ece20d8..a235b465 100644 --- a/docx/parts/image.py +++ b/docx/parts/image.py @@ -4,9 +4,7 @@ The proxy class for an image part, and related objects. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals import hashlib @@ -20,6 +18,7 @@ class ImagePart(Part): An image part. Corresponds to the target part of a relationship with type RELATIONSHIP_TYPE.IMAGE. """ + def __init__(self, partname, content_type, blob, image=None): super(ImagePart, self).__init__(partname, content_type, blob) self._image = image @@ -57,7 +56,7 @@ def filename(self): """ if self._image is not None: return self._image.filename - return 'image.%s' % self.partname.ext + return "image.%s" % self.partname.ext @classmethod def from_image(cls, image, partname): diff --git a/docx/parts/settings.py b/docx/parts/settings.py index a701b172..e0f751b3 100644 --- a/docx/parts/settings.py +++ b/docx/parts/settings.py @@ -4,9 +4,7 @@ |SettingsPart| and closely related objects """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals import os @@ -21,13 +19,14 @@ class SettingsPart(XmlPart): """ Document-level settings part of a WordprocessingML (WML) package. """ + @classmethod def default(cls, package): """ Return a newly created settings part, containing a default `w:settings` element tree. """ - partname = PackURI('/word/settings.xml') + partname = PackURI("/word/settings.xml") content_type = CT.WML_SETTINGS element = parse_xml(cls._default_settings_xml()) return cls(partname, content_type, element, package) @@ -46,9 +45,8 @@ def _default_settings_xml(cls): Return a bytestream containing XML for a default settings part. """ path = os.path.join( - os.path.split(__file__)[0], '..', 'templates', - 'default-settings.xml' + os.path.split(__file__)[0], "..", "templates", "default-settings.xml" ) - with open(path, 'rb') as f: + with open(path, "rb") as f: xml_bytes = f.read() return xml_bytes diff --git a/docx/parts/story.py b/docx/parts/story.py index 129b8f1c..49cfa396 100644 --- a/docx/parts/story.py +++ b/docx/parts/story.py @@ -66,7 +66,7 @@ def next_id(self): the existing id sequence are not filled. The id attribute value is unique in the document, without regard to the element type it appears on. """ - id_str_lst = self._element.xpath('//@id') + id_str_lst = self._element.xpath("//@id") used_ids = [int(id_str) for id_str in id_str_lst if id_str.isdigit()] if not used_ids: return 1 diff --git a/docx/parts/styles.py b/docx/parts/styles.py index 00c7cb3c..a16b4188 100644 --- a/docx/parts/styles.py +++ b/docx/parts/styles.py @@ -4,9 +4,7 @@ Provides StylesPart and related objects """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals import os @@ -22,13 +20,14 @@ class StylesPart(XmlPart): Proxy for the styles.xml part containing style definitions for a document or glossary. """ + @classmethod def default(cls, package): """ Return a newly created styles part, containing a default set of elements. """ - partname = PackURI('/word/styles.xml') + partname = PackURI("/word/styles.xml") content_type = CT.WML_STYLES element = parse_xml(cls._default_styles_xml()) return cls(partname, content_type, element, package) @@ -47,9 +46,8 @@ def _default_styles_xml(cls): Return a bytestream containing XML for a default styles part. """ path = os.path.join( - os.path.split(__file__)[0], '..', 'templates', - 'default-styles.xml' + os.path.split(__file__)[0], "..", "templates", "default-styles.xml" ) - with open(path, 'rb') as f: + with open(path, "rb") as f: xml_bytes = f.read() return xml_bytes diff --git a/docx/shape.py b/docx/shape.py index e4f885d7..036118d4 100644 --- a/docx/shape.py +++ b/docx/shape.py @@ -5,9 +5,7 @@ a document. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals from .enum.shape import WD_INLINE_SHAPE from .oxml.ns import nsmap @@ -19,6 +17,7 @@ class InlineShapes(Parented): Sequence of |InlineShape| instances, supporting len(), iteration, and indexed access. """ + def __init__(self, body_elm, parent): super(InlineShapes, self).__init__(parent) self._body = body_elm @@ -43,7 +42,7 @@ def __len__(self): @property def _inline_lst(self): body = self._body - xpath = '//w:p/w:r/w:drawing/wp:inline' + xpath = "//w:p/w:r/w:drawing/wp:inline" return body.xpath(xpath) @@ -52,6 +51,7 @@ class InlineShape(object): Proxy for an ```` element, representing the container for an inline graphical object. """ + def __init__(self, inline): super(InlineShape, self).__init__() self._inline = inline @@ -78,14 +78,14 @@ def type(self): """ graphicData = self._inline.graphic.graphicData uri = graphicData.uri - if uri == nsmap['pic']: + if uri == nsmap["pic"]: blip = graphicData.pic.blipFill.blip if blip.link is not None: return WD_INLINE_SHAPE.LINKED_PICTURE return WD_INLINE_SHAPE.PICTURE - if uri == nsmap['c']: + if uri == nsmap["c"]: return WD_INLINE_SHAPE.CHART - if uri == nsmap['dgm']: + if uri == nsmap["dgm"]: return WD_INLINE_SHAPE.SMART_ART return WD_INLINE_SHAPE.NOT_IMPLEMENTED diff --git a/docx/shared.py b/docx/shared.py index 91996432..ea855a21 100644 --- a/docx/shared.py +++ b/docx/shared.py @@ -14,6 +14,7 @@ class Length(int): 36,000 to the mm. Provides convenience unit conversion methods in the form of read-only properties. Immutable. """ + _EMUS_PER_INCH = 914400 _EMUS_PER_CM = 360000 _EMUS_PER_MM = 36000 @@ -71,6 +72,7 @@ class Inches(Length): Convenience constructor for length in inches, e.g. ``width = Inches(0.5)``. """ + def __new__(cls, inches): emu = int(inches * Length._EMUS_PER_INCH) return Length.__new__(cls, emu) @@ -81,6 +83,7 @@ class Cm(Length): Convenience constructor for length in centimeters, e.g. ``height = Cm(12)``. """ + def __new__(cls, cm): emu = int(cm * Length._EMUS_PER_CM) return Length.__new__(cls, emu) @@ -91,6 +94,7 @@ class Emu(Length): Convenience constructor for length in English Metric Units, e.g. ``width = Emu(457200)``. """ + def __new__(cls, emu): return Length.__new__(cls, int(emu)) @@ -100,6 +104,7 @@ class Mm(Length): Convenience constructor for length in millimeters, e.g. ``width = Mm(240.5)``. """ + def __new__(cls, mm): emu = int(mm * Length._EMUS_PER_MM) return Length.__new__(cls, emu) @@ -109,6 +114,7 @@ class Pt(Length): """ Convenience value class for specifying a length in points """ + def __new__(cls, points): emu = int(points * Length._EMUS_PER_PT) return Length.__new__(cls, emu) @@ -119,6 +125,7 @@ class Twips(Length): Convenience constructor for length in twips, e.g. ``width = Twips(42)``. A twip is a twentieth of a point, 635 EMU. """ + def __new__(cls, twips): emu = int(twips * Length._EMUS_PER_TWIP) return Length.__new__(cls, emu) @@ -128,21 +135,22 @@ class RGBColor(tuple): """ Immutable value object defining a particular RGB color. """ + def __new__(cls, r, g, b): - msg = 'RGBColor() takes three integer values 0-255' + msg = "RGBColor() takes three integer values 0-255" for val in (r, g, b): if not isinstance(val, int) or val < 0 or val > 255: raise ValueError(msg) return super(RGBColor, cls).__new__(cls, (r, g, b)) def __repr__(self): - return 'RGBColor(0x%02x, 0x%02x, 0x%02x)' % self + return "RGBColor(0x%02x, 0x%02x, 0x%02x)" % self def __str__(self): """ Return a hex string rgb value, like '3C2F80' """ - return '%02X%02X%02X' % self + return "%02X%02X%02X" % self @classmethod def from_string(cls, rgb_hex_str): @@ -161,7 +169,7 @@ def lazyproperty(f): to calculate a cached property value. After that, the cached value is returned. """ - cache_attr_name = '_%s' % f.__name__ # like '_foobar' for prop 'foobar' + cache_attr_name = "_%s" % f.__name__ # like '_foobar' for prop 'foobar' docstring = f.__doc__ def get_prop_value(obj): @@ -193,7 +201,7 @@ class ElementProxy(object): type of class in python-docx other than custom element (oxml) classes. """ - __slots__ = ('_element', '_parent') + __slots__ = ("_element", "_parent") def __init__(self, element, parent=None): self._element = element @@ -238,6 +246,7 @@ class Parented(object): such as add or drop a relationship. Provides ``self._parent`` attribute to subclasses. """ + def __init__(self, parent): super(Parented, self).__init__() self._parent = parent diff --git a/docx/styles/__init__.py b/docx/styles/__init__.py index 63ebaa2b..61d011d3 100644 --- a/docx/styles/__init__.py +++ b/docx/styles/__init__.py @@ -4,9 +4,7 @@ Sub-package module for docx.styles sub-package. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals class BabelFish(object): @@ -16,18 +14,18 @@ class BabelFish(object): """ style_aliases = ( - ('Caption', 'caption'), - ('Footer', 'footer'), - ('Header', 'header'), - ('Heading 1', 'heading 1'), - ('Heading 2', 'heading 2'), - ('Heading 3', 'heading 3'), - ('Heading 4', 'heading 4'), - ('Heading 5', 'heading 5'), - ('Heading 6', 'heading 6'), - ('Heading 7', 'heading 7'), - ('Heading 8', 'heading 8'), - ('Heading 9', 'heading 9'), + ("Caption", "caption"), + ("Footer", "footer"), + ("Header", "header"), + ("Heading 1", "heading 1"), + ("Heading 2", "heading 2"), + ("Heading 3", "heading 3"), + ("Heading 4", "heading 4"), + ("Heading 5", "heading 5"), + ("Heading 6", "heading 6"), + ("Heading 7", "heading 7"), + ("Heading 8", "heading 8"), + ("Heading 9", "heading 9"), ) internal_style_names = dict(style_aliases) @@ -47,6 +45,4 @@ def internal2ui(cls, internal_style_name): Return the user interface style name corresponding to *internal_style_name*, such as 'Heading 1' for 'heading 1'. """ - return cls.ui_style_names.get( - internal_style_name, internal_style_name - ) + return cls.ui_style_names.get(internal_style_name, internal_style_name) diff --git a/docx/styles/latent.py b/docx/styles/latent.py index 99b1514f..6f723692 100644 --- a/docx/styles/latent.py +++ b/docx/styles/latent.py @@ -4,9 +4,7 @@ Latent style-related objects. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals from . import BabelFish from ..shared import ElementProxy @@ -67,11 +65,11 @@ def default_to_hidden(self): to be hidden. A hidden style does not appear in the recommended list or in the style gallery. """ - return self._element.bool_prop('defSemiHidden') + return self._element.bool_prop("defSemiHidden") @default_to_hidden.setter def default_to_hidden(self, value): - self._element.set_bool_prop('defSemiHidden', value) + self._element.set_bool_prop("defSemiHidden", value) @property def default_to_locked(self): @@ -82,11 +80,11 @@ def default_to_locked(self): behavior is only active when formatting protection is turned on for the document (via the Developer menu). """ - return self._element.bool_prop('defLockedState') + return self._element.bool_prop("defLockedState") @default_to_locked.setter def default_to_locked(self, value): - self._element.set_bool_prop('defLockedState', value) + self._element.set_bool_prop("defLockedState", value) @property def default_to_quick_style(self): @@ -94,11 +92,11 @@ def default_to_quick_style(self): Boolean specifying whether the default behavior for latent styles is to appear in the style gallery when not hidden. """ - return self._element.bool_prop('defQFormat') + return self._element.bool_prop("defQFormat") @default_to_quick_style.setter def default_to_quick_style(self, value): - self._element.set_bool_prop('defQFormat', value) + self._element.set_bool_prop("defQFormat", value) @property def default_to_unhide_when_used(self): @@ -106,11 +104,11 @@ def default_to_unhide_when_used(self): Boolean specifying whether the default behavior for latent styles is to be unhidden when first applied to content. """ - return self._element.bool_prop('defUnhideWhenUsed') + return self._element.bool_prop("defUnhideWhenUsed") @default_to_unhide_when_used.setter def default_to_unhide_when_used(self, value): - self._element.set_bool_prop('defUnhideWhenUsed', value) + self._element.set_bool_prop("defUnhideWhenUsed", value) @property def load_count(self): @@ -155,11 +153,11 @@ def hidden(self): the recommended list. |None| indicates the effective value is inherited from the parent ```` element. """ - return self._element.on_off_prop('semiHidden') + return self._element.on_off_prop("semiHidden") @hidden.setter def hidden(self, value): - self._element.set_on_off_prop('semiHidden', value) + self._element.set_on_off_prop("semiHidden", value) @property def locked(self): @@ -170,11 +168,11 @@ def locked(self): only active when formatting protection is turned on for the document (via the Developer menu). """ - return self._element.on_off_prop('locked') + return self._element.on_off_prop("locked") @locked.setter def locked(self, value): - self._element.set_on_off_prop('locked', value) + self._element.set_on_off_prop("locked", value) @property def name(self): @@ -202,11 +200,11 @@ def quick_style(self): effective value should be inherited from the default values in its parent |LatentStyles| object. """ - return self._element.on_off_prop('qFormat') + return self._element.on_off_prop("qFormat") @quick_style.setter def quick_style(self, value): - self._element.set_on_off_prop('qFormat', value) + self._element.set_on_off_prop("qFormat", value) @property def unhide_when_used(self): @@ -217,8 +215,8 @@ def unhide_when_used(self): inherited from the default specified by its parent |LatentStyles| object. """ - return self._element.on_off_prop('unhideWhenUsed') + return self._element.on_off_prop("unhideWhenUsed") @unhide_when_used.setter def unhide_when_used(self, value): - self._element.set_on_off_prop('unhideWhenUsed', value) + self._element.set_on_off_prop("unhideWhenUsed", value) diff --git a/docx/styles/style.py b/docx/styles/style.py index 24371b23..ff63a819 100644 --- a/docx/styles/style.py +++ b/docx/styles/style.py @@ -4,9 +4,7 @@ Style object hierarchy. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals from . import BabelFish from ..enum.style import WD_STYLE_TYPE @@ -23,8 +21,8 @@ def StyleFactory(style_elm): style_cls = { WD_STYLE_TYPE.PARAGRAPH: _ParagraphStyle, WD_STYLE_TYPE.CHARACTER: _CharacterStyle, - WD_STYLE_TYPE.TABLE: _TableStyle, - WD_STYLE_TYPE.LIST: _NumberingStyle + WD_STYLE_TYPE.TABLE: _TableStyle, + WD_STYLE_TYPE.LIST: _NumberingStyle, }[style_elm.type] return style_cls(style_elm) @@ -211,7 +209,7 @@ class _ParagraphStyle(_CharacterStyle): __slots__ = () def __repr__(self): - return '_ParagraphStyle(\'%s\') id: %s' % (self.name, id(self)) + return "_ParagraphStyle('%s') id: %s" % (self.name, id(self)) @property def next_paragraph_style(self): @@ -254,7 +252,7 @@ class _TableStyle(_ParagraphStyle): __slots__ = () def __repr__(self): - return '_TableStyle(\'%s\') id: %s' % (self.name, id(self)) + return "_TableStyle('%s') id: %s" % (self.name, id(self)) class _NumberingStyle(BaseStyle): diff --git a/docx/styles/styles.py b/docx/styles/styles.py index f9f1cd2f..d09fbd13 100644 --- a/docx/styles/styles.py +++ b/docx/styles/styles.py @@ -44,8 +44,8 @@ def __getitem__(self, key): style_elm = self._element.get_by_id(key) if style_elm is not None: msg = ( - 'style lookup by style_id is deprecated. Use style name as ' - 'key instead.' + "style lookup by style_id is deprecated. Use style name as " + "key instead." ) warn(msg, UserWarning, stacklevel=2) return StyleFactory(style_elm) @@ -67,9 +67,7 @@ def add_style(self, name, style_type, builtin=False): style_name = BabelFish.ui2internal(name) if style_name in self: raise ValueError("document already contains style '%s'" % name) - style = self._element.add_style_of_type( - style_name, style_type, builtin - ) + style = self._element.add_style_of_type(style_name, style_type, builtin) return StyleFactory(style) def default(self, style_type): @@ -145,8 +143,7 @@ def _get_style_id_from_style(self, style, style_type): """ if style.type != style_type: raise ValueError( - "assigned style is type %s, need type %s" % - (style.type, style_type) + "assigned style is type %s, need type %s" % (style.type, style_type) ) if style == self.default(style_type): return None diff --git a/docx/table.py b/docx/table.py index b3bc090f..bd4e1e27 100644 --- a/docx/table.py +++ b/docx/table.py @@ -16,6 +16,7 @@ class Table(Parented): """ Proxy class for a WordprocessingML ```` element. """ + def __init__(self, tbl, parent): super(Table, self).__init__(parent) self._element = self._tbl = tbl @@ -130,9 +131,7 @@ def style(self): @style.setter def style(self, style_or_name): - style_id = self.part.get_style_id( - style_or_name, WD_STYLE_TYPE.TABLE - ) + style_id = self.part.get_style_id(style_or_name, WD_STYLE_TYPE.TABLE) self._tbl.tblStyle_val = style_id @property @@ -196,7 +195,7 @@ def __init__(self, tc, parent): super(_Cell, self).__init__(tc, parent) self._tc = self._element = tc - def add_paragraph(self, text='', style=None): + def add_paragraph(self, text="", style=None): """ Return a paragraph newly added to the end of the content in this cell. If present, *text* is added to the paragraph in a single run. @@ -255,7 +254,7 @@ def text(self): a string to this property replaces all existing content with a single paragraph containing the assigned text in a single run. """ - return '\n'.join(p.text for p in self.paragraphs) + return "\n".join(p.text for p in self.paragraphs) @text.setter def text(self, text): @@ -303,6 +302,7 @@ class _Column(Parented): """ Table column """ + def __init__(self, gridCol, parent): super(_Column, self).__init__(parent) self._gridCol = gridCol @@ -346,6 +346,7 @@ class _Columns(Parented): Sequence of |_Column| instances corresponding to the columns in a table. Supports ``len()``, iteration and indexed access. """ + def __init__(self, tbl, parent): super(_Columns, self).__init__(parent) self._tbl = tbl @@ -389,6 +390,7 @@ class _Row(Parented): """ Table row """ + def __init__(self, tr, parent): super(_Row, self).__init__(parent) self._tr = self._element = tr @@ -445,6 +447,7 @@ class _Rows(Parented): Sequence of |_Row| objects corresponding to the rows in a table. Supports ``len()``, iteration, indexed access, and slicing. """ + def __init__(self, tbl, parent): super(_Rows, self).__init__(parent) self._tbl = tbl diff --git a/docx/text/font.py b/docx/text/font.py index 16283210..5a88e8af 100644 --- a/docx/text/font.py +++ b/docx/text/font.py @@ -4,9 +4,7 @@ Font-related proxy objects. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals from ..dml.color import ColorFormat from ..shared import ElementProxy @@ -26,22 +24,22 @@ def all_caps(self): """ Read/write. Causes text in this font to appear in capital letters. """ - return self._get_bool_prop('caps') + return self._get_bool_prop("caps") @all_caps.setter def all_caps(self, value): - self._set_bool_prop('caps', value) + self._set_bool_prop("caps", value) @property def bold(self): """ Read/write. Causes text in this font to appear in bold. """ - return self._get_bool_prop('b') + return self._get_bool_prop("b") @bold.setter def bold(self, value): - self._set_bool_prop('b', value) + self._set_bool_prop("b", value) @property def color(self): @@ -58,11 +56,11 @@ def complex_script(self): run to be treated as complex script regardless of their Unicode values. """ - return self._get_bool_prop('cs') + return self._get_bool_prop("cs") @complex_script.setter def complex_script(self, value): - self._set_bool_prop('cs', value) + self._set_bool_prop("cs", value) @property def cs_bold(self): @@ -70,11 +68,11 @@ def cs_bold(self): Read/write tri-state value. When |True|, causes the complex script characters in the run to be displayed in bold typeface. """ - return self._get_bool_prop('bCs') + return self._get_bool_prop("bCs") @cs_bold.setter def cs_bold(self, value): - self._set_bool_prop('bCs', value) + self._set_bool_prop("bCs", value) @property def cs_italic(self): @@ -82,11 +80,11 @@ def cs_italic(self): Read/write tri-state value. When |True|, causes the complex script characters in the run to be displayed in italic typeface. """ - return self._get_bool_prop('iCs') + return self._get_bool_prop("iCs") @cs_italic.setter def cs_italic(self, value): - self._set_bool_prop('iCs', value) + self._set_bool_prop("iCs", value) @property def double_strike(self): @@ -94,11 +92,11 @@ def double_strike(self): Read/write tri-state value. When |True|, causes the text in the run to appear with double strikethrough. """ - return self._get_bool_prop('dstrike') + return self._get_bool_prop("dstrike") @double_strike.setter def double_strike(self, value): - self._set_bool_prop('dstrike', value) + self._set_bool_prop("dstrike", value) @property def emboss(self): @@ -106,11 +104,11 @@ def emboss(self): Read/write tri-state value. When |True|, causes the text in the run to appear as if raised off the page in relief. """ - return self._get_bool_prop('emboss') + return self._get_bool_prop("emboss") @emboss.setter def emboss(self, value): - self._set_bool_prop('emboss', value) + self._set_bool_prop("emboss", value) @property def hidden(self): @@ -119,11 +117,11 @@ def hidden(self): to be hidden from display, unless applications settings force hidden text to be shown. """ - return self._get_bool_prop('vanish') + return self._get_bool_prop("vanish") @hidden.setter def hidden(self, value): - self._set_bool_prop('vanish', value) + self._set_bool_prop("vanish", value) @property def highlight_color(self): @@ -148,11 +146,11 @@ def italic(self): to appear in italics. |None| indicates the effective value is inherited from the style hierarchy. """ - return self._get_bool_prop('i') + return self._get_bool_prop("i") @italic.setter def italic(self, value): - self._set_bool_prop('i', value) + self._set_bool_prop("i", value) @property def imprint(self): @@ -160,11 +158,11 @@ def imprint(self): Read/write tri-state value. When |True|, causes the text in the run to appear as if pressed into the page. """ - return self._get_bool_prop('imprint') + return self._get_bool_prop("imprint") @imprint.setter def imprint(self, value): - self._set_bool_prop('imprint', value) + self._set_bool_prop("imprint", value) @property def math(self): @@ -172,11 +170,11 @@ def math(self): Read/write tri-state value. When |True|, specifies this run contains WML that should be handled as though it was Office Open XML Math. """ - return self._get_bool_prop('oMath') + return self._get_bool_prop("oMath") @math.setter def math(self, value): - self._set_bool_prop('oMath', value) + self._set_bool_prop("oMath", value) @property def name(self): @@ -204,11 +202,11 @@ def no_proof(self): of this run should not report any errors when the document is scanned for spelling and grammar. """ - return self._get_bool_prop('noProof') + return self._get_bool_prop("noProof") @no_proof.setter def no_proof(self, value): - self._set_bool_prop('noProof', value) + self._set_bool_prop("noProof", value) @property def outline(self): @@ -217,11 +215,11 @@ def outline(self): run to appear as if they have an outline, by drawing a one pixel wide border around the inside and outside borders of each character glyph. """ - return self._get_bool_prop('outline') + return self._get_bool_prop("outline") @outline.setter def outline(self, value): - self._set_bool_prop('outline', value) + self._set_bool_prop("outline", value) @property def rtl(self): @@ -229,11 +227,11 @@ def rtl(self): Read/write tri-state value. When |True| causes the text in the run to have right-to-left characteristics. """ - return self._get_bool_prop('rtl') + return self._get_bool_prop("rtl") @rtl.setter def rtl(self, value): - self._set_bool_prop('rtl', value) + self._set_bool_prop("rtl", value) @property def shadow(self): @@ -241,11 +239,11 @@ def shadow(self): Read/write tri-state value. When |True| causes the text in the run to appear as if each character has a shadow. """ - return self._get_bool_prop('shadow') + return self._get_bool_prop("shadow") @shadow.setter def shadow(self, value): - self._set_bool_prop('shadow', value) + self._set_bool_prop("shadow", value) @property def size(self): @@ -280,11 +278,11 @@ def small_caps(self): characters in the run to appear as capital letters two points smaller than the font size specified for the run. """ - return self._get_bool_prop('smallCaps') + return self._get_bool_prop("smallCaps") @small_caps.setter def small_caps(self, value): - self._set_bool_prop('smallCaps', value) + self._set_bool_prop("smallCaps", value) @property def snap_to_grid(self): @@ -293,11 +291,11 @@ def snap_to_grid(self): document grid characters per line settings defined in the docGrid element when laying out the characters in this run. """ - return self._get_bool_prop('snapToGrid') + return self._get_bool_prop("snapToGrid") @snap_to_grid.setter def snap_to_grid(self, value): - self._set_bool_prop('snapToGrid', value) + self._set_bool_prop("snapToGrid", value) @property def spec_vanish(self): @@ -308,11 +306,11 @@ def spec_vanish(self): narrow, specialized use related to the table of contents. Consult the spec (§17.3.2.36) for more details. """ - return self._get_bool_prop('specVanish') + return self._get_bool_prop("specVanish") @spec_vanish.setter def spec_vanish(self, value): - self._set_bool_prop('specVanish', value) + self._set_bool_prop("specVanish", value) @property def strike(self): @@ -321,11 +319,11 @@ def strike(self): to appear with a single horizontal line through the center of the line. """ - return self._get_bool_prop('strike') + return self._get_bool_prop("strike") @strike.setter def strike(self, value): - self._set_bool_prop('strike', value) + self._set_bool_prop("strike", value) @property def subscript(self): @@ -388,11 +386,11 @@ def web_hidden(self): of this run shall be hidden when the document is displayed in web page view. """ - return self._get_bool_prop('webHidden') + return self._get_bool_prop("webHidden") @web_hidden.setter def web_hidden(self, value): - self._set_bool_prop('webHidden', value) + self._set_bool_prop("webHidden", value) def _get_bool_prop(self, name): """ diff --git a/docx/text/paragraph.py b/docx/text/paragraph.py index 4fb583b9..d349e537 100644 --- a/docx/text/paragraph.py +++ b/docx/text/paragraph.py @@ -4,9 +4,7 @@ Paragraph-related proxy types. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals from ..enum.style import WD_STYLE_TYPE from .parfmt import ParagraphFormat @@ -18,6 +16,7 @@ class Paragraph(Parented): """ Proxy object wrapping ```` element. """ + def __init__(self, p, parent): super(Paragraph, self).__init__(parent) self._p = self._element = p @@ -107,9 +106,7 @@ def style(self): @style.setter def style(self, style_or_name): - style_id = self.part.get_style_id( - style_or_name, WD_STYLE_TYPE.PARAGRAPH - ) + style_id = self.part.get_style_id(style_or_name, WD_STYLE_TYPE.PARAGRAPH) self._p.style = style_id @property @@ -126,7 +123,7 @@ def text(self): Paragraph-level formatting, such as style, is preserved. All run-level formatting, such as bold or italic, is removed. """ - text = '' + text = "" for run in self.runs: text += run.text return text diff --git a/docx/text/parfmt.py b/docx/text/parfmt.py index 37206729..6d921554 100644 --- a/docx/text/parfmt.py +++ b/docx/text/parfmt.py @@ -4,9 +4,7 @@ Paragraph-related proxy types. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals from ..enum.text import WD_LINE_SPACING from ..shared import ElementProxy, Emu, lazyproperty, Length, Pt, Twips @@ -20,7 +18,7 @@ class ParagraphFormat(ElementProxy): control. """ - __slots__ = ('_tab_stops',) + __slots__ = ("_tab_stops",) @property def alignment(self): @@ -153,9 +151,7 @@ def line_spacing_rule(self): pPr = self._element.pPr if pPr is None: return None - return self._line_spacing_rule( - pPr.spacing_line, pPr.spacing_lineRule - ) + return self._line_spacing_rule(pPr.spacing_line, pPr.spacing_lineRule) @line_spacing_rule.setter def line_spacing_rule(self, value): diff --git a/docx/text/run.py b/docx/text/run.py index 97d6da7d..88c37fa3 100644 --- a/docx/text/run.py +++ b/docx/text/run.py @@ -21,6 +21,7 @@ class Run(Parented): not specified directly on the run and its effective value is taken from the style hierarchy. """ + def __init__(self, r, parent): super(Run, self).__init__(parent) self._r = self._element = self.element = r @@ -33,12 +34,12 @@ def add_break(self, break_type=WD_BREAK.LINE): *break_type* defaults to `WD_BREAK.LINE`. """ type_, clear = { - WD_BREAK.LINE: (None, None), - WD_BREAK.PAGE: ('page', None), - WD_BREAK.COLUMN: ('column', None), - WD_BREAK.LINE_CLEAR_LEFT: ('textWrapping', 'left'), - WD_BREAK.LINE_CLEAR_RIGHT: ('textWrapping', 'right'), - WD_BREAK.LINE_CLEAR_ALL: ('textWrapping', 'all'), + WD_BREAK.LINE: (None, None), + WD_BREAK.PAGE: ("page", None), + WD_BREAK.COLUMN: ("column", None), + WD_BREAK.LINE_CLEAR_LEFT: ("textWrapping", "left"), + WD_BREAK.LINE_CLEAR_RIGHT: ("textWrapping", "right"), + WD_BREAK.LINE_CLEAR_ALL: ("textWrapping", "all"), }[break_type] br = self._r.add_br() if type_ is not None: @@ -133,9 +134,7 @@ def style(self): @style.setter def style(self, style_or_name): - style_id = self.part.get_style_id( - style_or_name, WD_STYLE_TYPE.CHARACTER - ) + style_id = self.part.get_style_id(style_or_name, WD_STYLE_TYPE.CHARACTER) self._r.style = style_id @property @@ -186,6 +185,7 @@ class _Text(object): """ Proxy object wrapping ```` element. """ + def __init__(self, t_elm): super(_Text, self).__init__() self._t = t_elm diff --git a/docx/text/tabstops.py b/docx/text/tabstops.py index c22b9bc9..6915285c 100644 --- a/docx/text/tabstops.py +++ b/docx/text/tabstops.py @@ -4,9 +4,7 @@ Tabstop-related proxy types. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals from ..shared import ElementProxy from docx.enum.text import WD_TAB_ALIGNMENT, WD_TAB_LEADER @@ -21,7 +19,7 @@ class TabStops(ElementProxy): directly. """ - __slots__ = ('_pPr') + __slots__ = "_pPr" def __init__(self, element): super(TabStops, self).__init__(element, None) @@ -35,7 +33,7 @@ def __delitem__(self, idx): try: tabs.remove(tabs[idx]) except (AttributeError, IndexError): - raise IndexError('tab index out of range') + raise IndexError("tab index out of range") if len(tabs) == 0: self._pPr.remove(tabs) @@ -46,7 +44,7 @@ def __getitem__(self, idx): """ tabs = self._pPr.tabs if tabs is None: - raise IndexError('TabStops object is empty') + raise IndexError("TabStops object is empty") tab = tabs.tab_lst[idx] return TabStop(tab) @@ -66,8 +64,9 @@ def __len__(self): return 0 return len(tabs.tab_lst) - def add_tab_stop(self, position, alignment=WD_TAB_ALIGNMENT.LEFT, - leader=WD_TAB_LEADER.SPACES): + def add_tab_stop( + self, position, alignment=WD_TAB_ALIGNMENT.LEFT, leader=WD_TAB_LEADER.SPACES + ): """ Add a new tab stop at *position*, a |Length| object specifying the location of the tab stop relative to the paragraph edge. A negative @@ -94,7 +93,7 @@ class TabStop(ElementProxy): list semantics on its containing |TabStops| object. """ - __slots__ = ('_tab') + __slots__ = "_tab" def __init__(self, element): super(TabStop, self).__init__(element, None) diff --git a/features/environment.py b/features/environment.py index e144106c..f180da73 100644 --- a/features/environment.py +++ b/features/environment.py @@ -7,9 +7,7 @@ import os -scratch_dir = os.path.abspath( - os.path.join(os.path.split(__file__)[0], '_scratch') -) +scratch_dir = os.path.abspath(os.path.join(os.path.split(__file__)[0], "_scratch")) def before_all(context): diff --git a/features/steps/api.py b/features/steps/api.py index a3325567..1c66c4c8 100644 --- a/features/steps/api.py +++ b/features/steps/api.py @@ -15,32 +15,35 @@ # given ==================================================== -@given('I have python-docx installed') + +@given("I have python-docx installed") def given_I_have_python_docx_installed(context): pass # when ===================================================== -@when('I call docx.Document() with no arguments') + +@when("I call docx.Document() with no arguments") def when_I_call_docx_Document_with_no_arguments(context): context.document = Document() -@when('I call docx.Document() with the path of a .docx file') +@when("I call docx.Document() with the path of a .docx file") def when_I_call_docx_Document_with_the_path_of_a_docx_file(context): - context.document = Document(test_docx('doc-default')) + context.document = Document(test_docx("doc-default")) # then ===================================================== -@then('document is a Document object') + +@then("document is a Document object") def then_document_is_a_Document_object(context): document = context.document assert isinstance(document, docx.document.Document) -@then('the last paragraph contains the text I specified') +@then("the last paragraph contains the text I specified") def then_last_p_contains_specified_text(context): document = context.document text = context.paragraph_text @@ -48,15 +51,15 @@ def then_last_p_contains_specified_text(context): assert p.text == text -@then('the last paragraph has the style I specified') +@then("the last paragraph has the style I specified") def then_the_last_paragraph_has_the_style_I_specified(context): document, expected_style = context.document, context.style paragraph = document.paragraphs[-1] assert paragraph.style == expected_style -@then('the last paragraph is the empty paragraph I added') +@then("the last paragraph is the empty paragraph I added") def then_last_p_is_empty_paragraph_added(context): document = context.document p = document.paragraphs[-1] - assert p.text == '' + assert p.text == "" diff --git a/features/steps/block.py b/features/steps/block.py index 1eee70cd..686da2c9 100644 --- a/features/steps/block.py +++ b/features/steps/block.py @@ -14,12 +14,13 @@ # given =================================================== -@given('a document containing a table') + +@given("a document containing a table") def given_a_document_containing_a_table(context): - context.document = Document(test_docx('blk-containing-table')) + context.document = Document(test_docx("blk-containing-table")) -@given('a paragraph') +@given("a paragraph") def given_a_paragraph(context): context.document = Document() context.paragraph = context.document.add_paragraph() @@ -27,13 +28,14 @@ def given_a_paragraph(context): # when ==================================================== -@when('I add a paragraph') + +@when("I add a paragraph") def when_add_paragraph(context): document = context.document context.p = document.add_paragraph() -@when('I add a table') +@when("I add a table") def when_add_table(context): rows, cols = 2, 2 context.document.add_table(rows, cols) @@ -41,13 +43,14 @@ def when_add_table(context): # then ===================================================== -@then('I can access the table') + +@then("I can access the table") def then_can_access_table(context): table = context.document.tables[-1] assert isinstance(table, Table) -@then('the new table appears in the document') +@then("the new table appears in the document") def then_new_table_appears_in_document(context): table = context.document.tables[-1] assert isinstance(table, Table) diff --git a/features/steps/cell.py b/features/steps/cell.py index d1385c92..4ec633ae 100644 --- a/features/steps/cell.py +++ b/features/steps/cell.py @@ -15,30 +15,33 @@ # given =================================================== -@given('a table cell') + +@given("a table cell") def given_a_table_cell(context): - table = Document(test_docx('tbl-2x2-table')).tables[0] + table = Document(test_docx("tbl-2x2-table")).tables[0] context.cell = table.cell(0, 0) # when ===================================================== -@when('I add a 2 x 2 table into the first cell') + +@when("I add a 2 x 2 table into the first cell") def when_I_add_a_2x2_table_into_the_first_cell(context): context.table_ = context.cell.add_table(2, 2) -@when('I assign a string to the cell text attribute') +@when("I assign a string to the cell text attribute") def when_assign_string_to_cell_text_attribute(context): cell = context.cell - text = 'foobar' + text = "foobar" cell.text = text context.expected_text = text # then ===================================================== -@then('cell.tables[0] is a 2 x 2 table') + +@then("cell.tables[0] is a 2 x 2 table") def then_cell_tables_0_is_a_2x2_table(context): cell = context.cell table = cell.tables[0] @@ -46,7 +49,7 @@ def then_cell_tables_0_is_a_2x2_table(context): assert len(table.columns) == 2 -@then('the cell contains the string I assigned') +@then("the cell contains the string I assigned") def then_cell_contains_string_assigned(context): cell, expected_text = context.cell, context.expected_text text = cell.paragraphs[0].runs[0].text diff --git a/features/steps/coreprops.py b/features/steps/coreprops.py index dc6be2e6..e13c5f8f 100644 --- a/features/steps/coreprops.py +++ b/features/steps/coreprops.py @@ -4,9 +4,7 @@ Gherkin step implementations for core properties-related features. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals from datetime import datetime, timedelta @@ -20,19 +18,21 @@ # given =================================================== -@given('a document having known core properties') + +@given("a document having known core properties") def given_a_document_having_known_core_properties(context): - context.document = Document(test_docx('doc-coreprops')) + context.document = Document(test_docx("doc-coreprops")) -@given('a document having no core properties part') +@given("a document having no core properties part") def given_a_document_having_no_core_properties_part(context): - context.document = Document(test_docx('doc-no-coreprops')) + context.document = Document(test_docx("doc-no-coreprops")) # when ==================================================== -@when('I access the core properties object') + +@when("I access the core properties object") def when_I_access_the_core_properties_object(context): context.document.core_properties @@ -40,21 +40,21 @@ def when_I_access_the_core_properties_object(context): @when("I assign new values to the properties") def when_I_assign_new_values_to_the_properties(context): context.propvals = ( - ('author', 'Creator'), - ('category', 'Category'), - ('comments', 'Description'), - ('content_status', 'Content Status'), - ('created', datetime(2013, 6, 15, 12, 34, 56)), - ('identifier', 'Identifier'), - ('keywords', 'key; word; keyword'), - ('language', 'Language'), - ('last_modified_by', 'Last Modified By'), - ('last_printed', datetime(2013, 6, 15, 12, 34, 56)), - ('modified', datetime(2013, 6, 15, 12, 34, 56)), - ('revision', 9), - ('subject', 'Subject'), - ('title', 'Title'), - ('version', 'Version'), + ("author", "Creator"), + ("category", "Category"), + ("comments", "Description"), + ("content_status", "Content Status"), + ("created", datetime(2013, 6, 15, 12, 34, 56)), + ("identifier", "Identifier"), + ("keywords", "key; word; keyword"), + ("language", "Language"), + ("last_modified_by", "Last Modified By"), + ("last_printed", datetime(2013, 6, 15, 12, 34, 56)), + ("modified", datetime(2013, 6, 15, 12, 34, 56)), + ("revision", 9), + ("subject", "Subject"), + ("title", "Title"), + ("version", "Version"), ) core_properties = context.document.core_properties for name, value in context.propvals: @@ -63,11 +63,12 @@ def when_I_assign_new_values_to_the_properties(context): # then ==================================================== -@then('a core properties part with default values is added') + +@then("a core properties part with default values is added") def then_a_core_properties_part_with_default_values_is_added(context): core_properties = context.document.core_properties - assert core_properties.title == 'Word Document' - assert core_properties.last_modified_by == 'python-docx' + assert core_properties.title == "Word Document" + assert core_properties.last_modified_by == "python-docx" assert core_properties.revision == 1 # core_properties.modified only stores time with seconds resolution, so # comparison needs to be a little loose (within two seconds) @@ -76,45 +77,47 @@ def then_a_core_properties_part_with_default_values_is_added(context): assert modified_timedelta < max_expected_timedelta -@then('I can access the core properties object') +@then("I can access the core properties object") def then_I_can_access_the_core_properties_object(context): document = context.document core_properties = document.core_properties assert isinstance(core_properties, CoreProperties) -@then('the core property values match the known values') +@then("the core property values match the known values") def then_the_core_property_values_match_the_known_values(context): known_propvals = ( - ('author', 'Steve Canny'), - ('category', 'Category'), - ('comments', 'Description'), - ('content_status', 'Content Status'), - ('created', datetime(2014, 12, 13, 22, 2, 0)), - ('identifier', 'Identifier'), - ('keywords', 'key; word; keyword'), - ('language', 'Language'), - ('last_modified_by', 'Steve Canny'), - ('last_printed', datetime(2014, 12, 13, 22, 2, 42)), - ('modified', datetime(2014, 12, 13, 22, 6, 0)), - ('revision', 2), - ('subject', 'Subject'), - ('title', 'Title'), - ('version', '0.7.1a3'), + ("author", "Steve Canny"), + ("category", "Category"), + ("comments", "Description"), + ("content_status", "Content Status"), + ("created", datetime(2014, 12, 13, 22, 2, 0)), + ("identifier", "Identifier"), + ("keywords", "key; word; keyword"), + ("language", "Language"), + ("last_modified_by", "Steve Canny"), + ("last_printed", datetime(2014, 12, 13, 22, 2, 42)), + ("modified", datetime(2014, 12, 13, 22, 6, 0)), + ("revision", 2), + ("subject", "Subject"), + ("title", "Title"), + ("version", "0.7.1a3"), ) core_properties = context.document.core_properties for name, expected_value in known_propvals: value = getattr(core_properties, name) - assert value == expected_value, ( - "got '%s' for core property '%s'" % (value, name) + assert value == expected_value, "got '%s' for core property '%s'" % ( + value, + name, ) -@then('the core property values match the new values') +@then("the core property values match the new values") def then_the_core_property_values_match_the_new_values(context): core_properties = context.document.core_properties for name, expected_value in context.propvals: value = getattr(core_properties, name) - assert value == expected_value, ( - "got '%s' for core property '%s'" % (value, name) + assert value == expected_value, "got '%s' for core property '%s'" % ( + value, + name, ) diff --git a/features/steps/customprops.py b/features/steps/customprops.py index d3c06c9d..3ae029bf 100644 --- a/features/steps/customprops.py +++ b/features/steps/customprops.py @@ -4,9 +4,7 @@ Gherkin step implementations for custom properties-related features. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals from datetime import datetime, timedelta @@ -20,19 +18,21 @@ # given =================================================== -@given('a document having known custom properties') + +@given("a document having known custom properties") def given_a_document_having_known_custom_properties(context): - context.document = Document(test_docx('doc-customprops')) + context.document = Document(test_docx("doc-customprops")) -@given('a document having no custom properties part') +@given("a document having no custom properties part") def given_a_document_having_no_custom_properties_part(context): - context.document = Document(test_docx('doc-no-customprops')) + context.document = Document(test_docx("doc-no-customprops")) # when ==================================================== -@when('I access the custom properties object') + +@when("I access the custom properties object") def when_I_access_the_custom_properties_object(context): context.document.custom_properties @@ -40,9 +40,9 @@ def when_I_access_the_custom_properties_object(context): @when("I assign new values to the custom properties") def when_I_assign_new_values_to_the_custom_properties(context): context.propvals = ( - ('CustomPropBool', False), - ('CustomPropInt', 1), - ('CustomPropString', 'Lorem ipsum'), + ("CustomPropBool", False), + ("CustomPropInt", 1), + ("CustomPropString", "Lorem ipsum"), ) custom_properties = context.document.custom_properties for name, value in context.propvals: @@ -51,39 +51,42 @@ def when_I_assign_new_values_to_the_custom_properties(context): # then ==================================================== -@then('a custom properties part with no values is added') + +@then("a custom properties part with no values is added") def then_a_custom_properties_part_with_no_values_is_added(context): custom_properties = context.document.custom_properties assert len(custom_properties) == 0 -@then('I can access the custom properties object') +@then("I can access the custom properties object") def then_I_can_access_the_custom_properties_object(context): document = context.document custom_properties = document.custom_properties assert isinstance(custom_properties, CustomProperties) -@then('the custom property values match the known values') +@then("the custom property values match the known values") def then_the_custom_property_values_match_the_known_values(context): known_propvals = ( - ('CustomPropBool', True), - ('CustomPropInt', 13), - ('CustomPropString', 'Test String'), + ("CustomPropBool", True), + ("CustomPropInt", 13), + ("CustomPropString", "Test String"), ) custom_properties = context.document.custom_properties for name, expected_value in known_propvals: value = custom_properties[name] - assert value == expected_value, ( - "got '%s' for custom property '%s'" % (value, name) + assert value == expected_value, "got '%s' for custom property '%s'" % ( + value, + name, ) -@then('the custom property values match the new values') +@then("the custom property values match the new values") def then_the_custom_property_values_match_the_new_values(context): custom_properties = context.document.custom_properties for name, expected_value in context.propvals: value = custom_properties[name] - assert value == expected_value, ( - "got '%s' for custom property '%s'" % (value, name) + assert value == expected_value, "got '%s' for custom property '%s'" % ( + value, + name, ) diff --git a/features/steps/document.py b/features/steps/document.py index a8e4d1ad..2aae3e19 100644 --- a/features/steps/document.py +++ b/features/steps/document.py @@ -22,39 +22,40 @@ # given =================================================== -@given('a blank document') + +@given("a blank document") def given_a_blank_document(context): - context.document = Document(test_docx('doc-word-default-blank')) + context.document = Document(test_docx("doc-word-default-blank")) -@given('a document having built-in styles') +@given("a document having built-in styles") def given_a_document_having_builtin_styles(context): context.document = Document() -@given('a document having inline shapes') +@given("a document having inline shapes") def given_a_document_having_inline_shapes(context): - context.document = Document(test_docx('shp-inline-shape-access')) + context.document = Document(test_docx("shp-inline-shape-access")) -@given('a document having sections') +@given("a document having sections") def given_a_document_having_sections(context): - context.document = Document(test_docx('doc-access-sections')) + context.document = Document(test_docx("doc-access-sections")) -@given('a document having styles') +@given("a document having styles") def given_a_document_having_styles(context): - context.document = Document(test_docx('sty-having-styles-part')) + context.document = Document(test_docx("sty-having-styles-part")) -@given('a document having three tables') +@given("a document having three tables") def given_a_document_having_three_tables(context): - context.document = Document(test_docx('tbl-having-tables')) + context.document = Document(test_docx("tbl-having-tables")) -@given('a single-section document having portrait layout') +@given("a single-section document having portrait layout") def given_a_single_section_document_having_portrait_layout(context): - context.document = Document(test_docx('doc-add-section')) + context.document = Document(test_docx("doc-add-section")) section = context.document.sections[-1] context.original_dimensions = (section.page_width, section.page_height) @@ -66,55 +67,56 @@ def given_a_single_section_Document_object_with_headers_and_footers(context): # when ==================================================== -@when('I add a 2 x 2 table specifying only row and column count') + +@when("I add a 2 x 2 table specifying only row and column count") def when_add_2x2_table_specifying_only_row_and_col_count(context): document = context.document document.add_table(rows=2, cols=2) -@when('I add a 2 x 2 table specifying style \'{style_name}\'') +@when("I add a 2 x 2 table specifying style '{style_name}'") def when_add_2x2_table_specifying_style_name(context, style_name): document = context.document document.add_table(rows=2, cols=2, style=style_name) -@when('I add a heading specifying level={level}') +@when("I add a heading specifying level={level}") def when_add_heading_specifying_level(context, level): context.document.add_heading(level=int(level)) -@when('I add a heading specifying only its text') +@when("I add a heading specifying only its text") def when_add_heading_specifying_only_its_text(context): document = context.document - context.heading_text = text = 'Spam vs. Eggs' + context.heading_text = text = "Spam vs. Eggs" document.add_heading(text) -@when('I add a page break to the document') +@when("I add a page break to the document") def when_add_page_break_to_document(context): document = context.document document.add_page_break() -@when('I add a paragraph specifying its style as a {kind}') +@when("I add a paragraph specifying its style as a {kind}") def when_I_add_a_paragraph_specifying_its_style_as_a(context, kind): document = context.document - style = context.style = document.styles['Heading 1'] + style = context.style = document.styles["Heading 1"] style_spec = { - 'style object': style, - 'style name': 'Heading 1', + "style object": style, + "style name": "Heading 1", }[kind] document.add_paragraph(style=style_spec) -@when('I add a paragraph specifying its text') +@when("I add a paragraph specifying its text") def when_add_paragraph_specifying_text(context): document = context.document - context.paragraph_text = 'foobar' + context.paragraph_text = "foobar" document.add_paragraph(context.paragraph_text) -@when('I add a paragraph without specifying text or style') +@when("I add a paragraph without specifying text or style") def when_add_paragraph_without_specifying_text_or_style(context): document = context.document document.add_paragraph() @@ -124,39 +126,38 @@ def when_add_paragraph_without_specifying_text_or_style(context): def when_add_picture_specifying_width_and_height(context): document = context.document context.picture = document.add_picture( - test_file('monty-truth.png'), - width=Inches(1.75), height=Inches(2.5) + test_file("monty-truth.png"), width=Inches(1.75), height=Inches(2.5) ) -@when('I add a picture specifying a height of 1.5 inches') +@when("I add a picture specifying a height of 1.5 inches") def when_add_picture_specifying_height(context): document = context.document context.picture = document.add_picture( - test_file('monty-truth.png'), height=Inches(1.5) + test_file("monty-truth.png"), height=Inches(1.5) ) -@when('I add a picture specifying a width of 1.5 inches') +@when("I add a picture specifying a width of 1.5 inches") def when_add_picture_specifying_width(context): document = context.document context.picture = document.add_picture( - test_file('monty-truth.png'), width=Inches(1.5) + test_file("monty-truth.png"), width=Inches(1.5) ) -@when('I add a picture specifying only the image file') +@when("I add a picture specifying only the image file") def when_add_picture_specifying_only_image_file(context): document = context.document - context.picture = document.add_picture(test_file('monty-truth.png')) + context.picture = document.add_picture(test_file("monty-truth.png")) -@when('I add an even-page section to the document') +@when("I add an even-page section to the document") def when_I_add_an_even_page_section_to_the_document(context): context.section = context.document.add_section(WD_SECTION.EVEN_PAGE) -@when('I change the new section layout to landscape') +@when("I change the new section layout to landscape") def when_I_change_the_new_section_layout_to_landscape(context): new_height, new_width = context.original_dimensions section = context.section @@ -172,14 +173,15 @@ def when_I_execute_section_eq_document_add_section(context): # then ==================================================== -@then('document.inline_shapes is an InlineShapes object') + +@then("document.inline_shapes is an InlineShapes object") def then_document_inline_shapes_is_an_InlineShapes_object(context): document = context.document inline_shapes = document.inline_shapes assert isinstance(inline_shapes, InlineShapes) -@then('document.paragraphs is a list containing three paragraphs') +@then("document.paragraphs is a list containing three paragraphs") def then_document_paragraphs_is_a_list_containing_three_paragraphs(context): document = context.document paragraphs = document.paragraphs @@ -189,20 +191,20 @@ def then_document_paragraphs_is_a_list_containing_three_paragraphs(context): assert isinstance(paragraph, Paragraph) -@then('document.sections is a Sections object') +@then("document.sections is a Sections object") def then_document_sections_is_a_Sections_object(context): sections = context.document.sections - msg = 'document.sections not instance of Sections' + msg = "document.sections not instance of Sections" assert isinstance(sections, Sections), msg -@then('document.styles is a Styles object') +@then("document.styles is a Styles object") def then_document_styles_is_a_Styles_object(context): styles = context.document.styles assert isinstance(styles, Styles) -@then('document.tables is a list containing three tables') +@then("document.tables is a list containing three tables") def then_document_tables_is_a_list_containing_three_tables(context): document = context.document tables = document.tables @@ -212,7 +214,7 @@ def then_document_tables_is_a_list_containing_three_tables(context): assert isinstance(table, Table) -@then('the document contains a 2 x 2 table') +@then("the document contains a 2 x 2 table") def then_the_document_contains_a_2x2_table(context): table = context.document.tables[-1] assert isinstance(table, Table) @@ -221,12 +223,12 @@ def then_the_document_contains_a_2x2_table(context): context.table_ = table -@then('the document has two sections') +@then("the document has two sections") def then_the_document_has_two_sections(context): assert len(context.document.sections) == 2 -@then('the first section is portrait') +@then("the first section is portrait") def then_the_first_section_is_portrait(context): first_section = context.document.sections[0] expected_width, expected_height = context.original_dimensions @@ -235,16 +237,16 @@ def then_the_first_section_is_portrait(context): assert first_section.page_height == expected_height -@then('the last paragraph contains only a page break') +@then("the last paragraph contains only a page break") def then_last_paragraph_contains_only_a_page_break(context): document = context.document paragraph = document.paragraphs[-1] assert len(paragraph.runs) == 1 assert len(paragraph.runs[0]._r) == 1 - assert paragraph.runs[0]._r[0].type == 'page' + assert paragraph.runs[0]._r[0].type == "page" -@then('the last paragraph contains the heading text') +@then("the last paragraph contains the heading text") def then_last_p_contains_heading_text(context): document = context.document text = context.heading_text @@ -252,7 +254,7 @@ def then_last_p_contains_heading_text(context): assert paragraph.text == text -@then('the second section is landscape') +@then("the second section is landscape") def then_the_second_section_is_landscape(context): new_section = context.document.sections[-1] expected_height, expected_width = context.original_dimensions @@ -261,10 +263,8 @@ def then_the_second_section_is_landscape(context): assert new_section.page_height == expected_height -@then('the style of the last paragraph is \'{style_name}\'') +@then("the style of the last paragraph is '{style_name}'") def then_the_style_of_the_last_paragraph_is_style(context, style_name): document = context.document paragraph = document.paragraphs[-1] - assert paragraph.style.name == style_name, ( - 'got %s' % paragraph.style.name - ) + assert paragraph.style.name == style_name, "got %s" % paragraph.style.name diff --git a/features/steps/font.py b/features/steps/font.py index 60f308d8..ed6e51f2 100644 --- a/features/steps/font.py +++ b/features/steps/font.py @@ -4,9 +4,7 @@ Step implementations for font-related features. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals from behave import given, then, when @@ -21,137 +19,137 @@ # given =================================================== -@given('a font') + +@given("a font") def given_a_font(context): - document = Document(test_docx('txt-font-props')) + document = Document(test_docx("txt-font-props")) context.font = document.paragraphs[0].runs[0].font -@given('a font having {color} highlighting') +@given("a font having {color} highlighting") def given_a_font_having_color_highlighting(context, color): paragraph_index = { - 'no': 0, - 'yellow': 1, - 'bright green': 2, + "no": 0, + "yellow": 1, + "bright green": 2, }[color] - document = Document(test_docx('txt-font-highlight-color')) + document = Document(test_docx("txt-font-highlight-color")) context.font = document.paragraphs[paragraph_index].runs[0].font -@given('a font having {type} color') +@given("a font having {type} color") def given_a_font_having_type_color(context, type): - run_idx = ['no', 'auto', 'an RGB', 'a theme'].index(type) - document = Document(test_docx('fnt-color')) + run_idx = ["no", "auto", "an RGB", "a theme"].index(type) + document = Document(test_docx("fnt-color")) context.font = document.paragraphs[0].runs[run_idx].font -@given('a font having typeface name {name}') +@given("a font having typeface name {name}") def given_a_font_having_typeface_name(context, name): - document = Document(test_docx('txt-font-props')) + document = Document(test_docx("txt-font-props")) style_name = { - 'not specified': 'Normal', - 'Avenir Black': 'Having Typeface', + "not specified": "Normal", + "Avenir Black": "Having Typeface", }[name] context.font = document.styles[style_name].font -@given('a font having {underline_type} underline') +@given("a font having {underline_type} underline") def given_a_font_having_type_underline(context, underline_type): style_name = { - 'inherited': 'Normal', - 'no': 'None Underlined', - 'single': 'Underlined', - 'double': 'Double Underlined', + "inherited": "Normal", + "no": "None Underlined", + "single": "Underlined", + "double": "Double Underlined", }[underline_type] - document = Document(test_docx('txt-font-props')) + document = Document(test_docx("txt-font-props")) context.font = document.styles[style_name].font -@given('a font having {vertAlign_state} vertical alignment') +@given("a font having {vertAlign_state} vertical alignment") def given_a_font_having_vertAlign_state(context, vertAlign_state): style_name = { - 'inherited': 'Normal', - 'subscript': 'Subscript', - 'superscript': 'Superscript', + "inherited": "Normal", + "subscript": "Subscript", + "superscript": "Superscript", }[vertAlign_state] - document = Document(test_docx('txt-font-props')) + document = Document(test_docx("txt-font-props")) context.font = document.styles[style_name].font -@given('a font of size {size}') +@given("a font of size {size}") def given_a_font_of_size(context, size): - document = Document(test_docx('txt-font-props')) + document = Document(test_docx("txt-font-props")) style_name = { - 'unspecified': 'Normal', - '14 pt': 'Having Typeface', - '18 pt': 'Large Size', + "unspecified": "Normal", + "14 pt": "Having Typeface", + "18 pt": "Large Size", }[size] context.font = document.styles[style_name].font # when ==================================================== -@when('I assign {value} to font.color.rgb') + +@when("I assign {value} to font.color.rgb") def when_I_assign_value_to_font_color_rgb(context, value): font = context.font - new_value = None if value == 'None' else RGBColor.from_string(value) + new_value = None if value == "None" else RGBColor.from_string(value) font.color.rgb = new_value -@when('I assign {value} to font.color.theme_color') +@when("I assign {value} to font.color.theme_color") def when_I_assign_value_to_font_color_theme_color(context, value): font = context.font - new_value = None if value == 'None' else getattr(MSO_THEME_COLOR, value) + new_value = None if value == "None" else getattr(MSO_THEME_COLOR, value) font.color.theme_color = new_value -@when('I assign {value} to font.highlight_color') +@when("I assign {value} to font.highlight_color") def when_I_assign_value_to_font_highlight_color(context, value): font = context.font - expected_value = ( - None if value == 'None' else getattr(WD_COLOR_INDEX, value) - ) + expected_value = None if value == "None" else getattr(WD_COLOR_INDEX, value) font.highlight_color = expected_value -@when('I assign {value} to font.name') +@when("I assign {value} to font.name") def when_I_assign_value_to_font_name(context, value): font = context.font - value = None if value == 'None' else value + value = None if value == "None" else value font.name = value -@when('I assign {value} to font.size') +@when("I assign {value} to font.size") def when_I_assign_value_str_to_font_size(context, value): - value = None if value == 'None' else int(value) + value = None if value == "None" else int(value) font = context.font font.size = value -@when('I assign {value} to font.underline') +@when("I assign {value} to font.underline") def when_I_assign_value_to_font_underline(context, value): new_value = { - 'True': True, - 'False': False, - 'None': None, - 'WD_UNDERLINE.SINGLE': WD_UNDERLINE.SINGLE, - 'WD_UNDERLINE.DOUBLE': WD_UNDERLINE.DOUBLE, + "True": True, + "False": False, + "None": None, + "WD_UNDERLINE.SINGLE": WD_UNDERLINE.SINGLE, + "WD_UNDERLINE.DOUBLE": WD_UNDERLINE.DOUBLE, }[value] font = context.font font.underline = new_value -@when('I assign {value} to font.{sub_super}script') +@when("I assign {value} to font.{sub_super}script") def when_I_assign_value_to_font_sub_super(context, value, sub_super): font = context.font name = { - 'sub': 'subscript', - 'super': 'superscript', + "sub": "subscript", + "super": "superscript", }[sub_super] new_value = { - 'None': None, - 'True': True, - 'False': False, + "None": None, + "True": True, + "False": False, }[value] setattr(font, name, new_value) @@ -159,82 +157,77 @@ def when_I_assign_value_to_font_sub_super(context, value, sub_super): # then ===================================================== -@then('font.color is a ColorFormat object') + +@then("font.color is a ColorFormat object") def then_font_color_is_a_ColorFormat_object(context): font = context.font assert isinstance(font.color, ColorFormat) -@then('font.color.rgb is {value}') +@then("font.color.rgb is {value}") def then_font_color_rgb_is_value(context, value): font = context.font - expected_value = None if value == 'None' else RGBColor.from_string(value) + expected_value = None if value == "None" else RGBColor.from_string(value) assert font.color.rgb == expected_value -@then('font.color.theme_color is {value}') +@then("font.color.theme_color is {value}") def then_font_color_theme_color_is_value(context, value): font = context.font - expected_value = ( - None if value == 'None' else getattr(MSO_THEME_COLOR, value) - ) + expected_value = None if value == "None" else getattr(MSO_THEME_COLOR, value) assert font.color.theme_color == expected_value -@then('font.color.type is {value}') +@then("font.color.type is {value}") def then_font_color_type_is_value(context, value): font = context.font - expected_value = ( - None if value == 'None' else getattr(MSO_COLOR_TYPE, value) - ) + expected_value = None if value == "None" else getattr(MSO_COLOR_TYPE, value) assert font.color.type == expected_value -@then('font.highlight_color is {value}') +@then("font.highlight_color is {value}") def then_font_highlight_color_is_value(context, value): font = context.font - expected_value = ( - None if value == 'None' else getattr(WD_COLOR_INDEX, value) - ) + expected_value = None if value == "None" else getattr(WD_COLOR_INDEX, value) assert font.highlight_color == expected_value -@then('font.name is {value}') +@then("font.name is {value}") def then_font_name_is_value(context, value): font = context.font - value = None if value == 'None' else value + value = None if value == "None" else value assert font.name == value -@then('font.size is {value}') +@then("font.size is {value}") def then_font_size_is_value(context, value): - value = None if value == 'None' else int(value) + value = None if value == "None" else int(value) font = context.font assert font.size == value -@then('font.underline is {value}') +@then("font.underline is {value}") def then_font_underline_is_value(context, value): expected_value = { - 'None': None, - 'True': True, - 'False': False, - 'WD_UNDERLINE.DOUBLE': WD_UNDERLINE.DOUBLE, + "None": None, + "True": True, + "False": False, + "WD_UNDERLINE.DOUBLE": WD_UNDERLINE.DOUBLE, }[value] font = context.font assert font.underline == expected_value -@then('font.{sub_super}script is {value}') +@then("font.{sub_super}script is {value}") def then_font_sub_super_is_value(context, sub_super, value): name = { - 'sub': 'subscript', - 'super': 'superscript', + "sub": "subscript", + "super": "superscript", }[sub_super] expected_value = { - 'None': None, - 'True': True, - 'False': False, + "None": None, + "True": True, + "False": False, }[value] font = context.font actual_value = getattr(font, name) diff --git a/features/steps/hdrftr.py b/features/steps/hdrftr.py index 786673db..4f0e3b91 100644 --- a/features/steps/hdrftr.py +++ b/features/steps/hdrftr.py @@ -13,6 +13,7 @@ # given ==================================================== + @given("a _Footer object {with_or_no} footer definition as footer") def given_a_Footer_object_with_or_no_footer_definition(context, with_or_no): section_idx = {"with a": 0, "with no": 1}[with_or_no] @@ -51,12 +52,13 @@ def given_the_next_Header_object_with_no_header_definition(context): # when ===================================================== -@when("I assign \"Normal\" to footer.paragraphs[0].style") + +@when('I assign "Normal" to footer.paragraphs[0].style') def when_I_assign_Body_Text_to_footer_style(context): context.footer.paragraphs[0].style = "Normal" -@when("I assign \"Normal\" to header.paragraphs[0].style") +@when('I assign "Normal" to header.paragraphs[0].style') def when_I_assign_Body_Text_to_header_style(context): context.header.paragraphs[0].style = "Normal" @@ -78,6 +80,7 @@ def when_I_call_run_add_picture(context): # then ===================================================== + @then("footer.is_linked_to_previous is {value}") def then_footer_is_linked_to_previous_is_value(context, value): actual = context.footer.is_linked_to_previous @@ -85,7 +88,7 @@ def then_footer_is_linked_to_previous_is_value(context, value): assert actual == expected, "footer.is_linked_to_previous is %s" % actual -@then("footer.paragraphs[0].style.name == \"Normal\"") +@then('footer.paragraphs[0].style.name == "Normal"') def then_footer_paragraphs_0_style_name_eq_Normal(context): actual = context.footer.paragraphs[0].style.name expected = "Normal" @@ -113,7 +116,7 @@ def then_header_is_linked_to_previous_is_value(context, value): assert actual == expected, "header.is_linked_to_previous is %s" % actual -@then("header.paragraphs[0].style.name == \"Normal\"") +@then('header.paragraphs[0].style.name == "Normal"') def then_header_paragraphs_0_style_name_eq_Normal(context): actual = context.header.paragraphs[0].style.name expected = "Normal" diff --git a/features/steps/helpers.py b/features/steps/helpers.py index 6733bfc1..cd64a786 100644 --- a/features/steps/helpers.py +++ b/features/steps/helpers.py @@ -12,22 +12,19 @@ def absjoin(*paths): thisdir = os.path.split(__file__)[0] -scratch_dir = absjoin(thisdir, '../_scratch') +scratch_dir = absjoin(thisdir, "../_scratch") # scratch output docx file ------------- -saved_docx_path = absjoin(scratch_dir, 'test_out.docx') +saved_docx_path = absjoin(scratch_dir, "test_out.docx") -bool_vals = { - 'True': True, - 'False': False -} +bool_vals = {"True": True, "False": False} -test_text = 'python-docx was here!' +test_text = "python-docx was here!" tri_state_vals = { - 'True': True, - 'False': False, - 'None': None, + "True": True, + "False": False, + "None": None, } @@ -35,11 +32,11 @@ def test_docx(name): """ Return the absolute path to test .docx file with root name *name*. """ - return absjoin(thisdir, 'test_files', '%s.docx' % name) + return absjoin(thisdir, "test_files", "%s.docx" % name) def test_file(name): """ Return the absolute path to file with *name* in test_files directory """ - return absjoin(thisdir, 'test_files', '%s' % name) + return absjoin(thisdir, "test_files", "%s" % name) diff --git a/features/steps/image.py b/features/steps/image.py index ee2a35c1..7f80baa5 100644 --- a/features/steps/image.py +++ b/features/steps/image.py @@ -15,59 +15,67 @@ # given =================================================== -@given('the image file \'{filename}\'') + +@given("the image file '{filename}'") def given_image_filename(context, filename): context.image_path = test_file(filename) # when ==================================================== -@when('I construct an image using the image path') + +@when("I construct an image using the image path") def when_construct_image_using_path(context): context.image = Image.from_file(context.image_path) # then ==================================================== -@then('the image has content type \'{mime_type}\'') + +@then("the image has content type '{mime_type}'") def then_image_has_content_type(context, mime_type): content_type = context.image.content_type - assert content_type == mime_type, ( - "expected MIME type '%s', got '%s'" % (mime_type, content_type) + assert content_type == mime_type, "expected MIME type '%s', got '%s'" % ( + mime_type, + content_type, ) -@then('the image has {horz_dpi_str} horizontal dpi') +@then("the image has {horz_dpi_str} horizontal dpi") def then_image_has_horizontal_dpi(context, horz_dpi_str): expected_horz_dpi = int(horz_dpi_str) horz_dpi = context.image.horz_dpi - assert horz_dpi == expected_horz_dpi, ( - "expected horizontal dpi %d, got %d" % (expected_horz_dpi, horz_dpi) + assert horz_dpi == expected_horz_dpi, "expected horizontal dpi %d, got %d" % ( + expected_horz_dpi, + horz_dpi, ) -@then('the image has {vert_dpi_str} vertical dpi') +@then("the image has {vert_dpi_str} vertical dpi") def then_image_has_vertical_dpi(context, vert_dpi_str): expected_vert_dpi = int(vert_dpi_str) vert_dpi = context.image.vert_dpi - assert vert_dpi == expected_vert_dpi, ( - "expected vertical dpi %d, got %d" % (expected_vert_dpi, vert_dpi) + assert vert_dpi == expected_vert_dpi, "expected vertical dpi %d, got %d" % ( + expected_vert_dpi, + vert_dpi, ) -@then('the image is {px_height_str} pixels high') +@then("the image is {px_height_str} pixels high") def then_image_is_cx_pixels_high(context, px_height_str): expected_px_height = int(px_height_str) px_height = context.image.px_height - assert px_height == expected_px_height, ( - "expected pixel height %d, got %d" % (expected_px_height, px_height) + assert px_height == expected_px_height, "expected pixel height %d, got %d" % ( + expected_px_height, + px_height, ) -@then('the image is {px_width_str} pixels wide') +@then("the image is {px_width_str} pixels wide") def then_image_is_cx_pixels_wide(context, px_width_str): expected_px_width = int(px_width_str) px_width = context.image.px_width - assert px_width == expected_px_width, ( - "expected pixel width %d, got %d" % (expected_px_width, px_width) + assert px_width == expected_px_width, "expected pixel width %d, got %d" % ( + expected_px_width, + px_width, ) diff --git a/features/steps/numbering.py b/features/steps/numbering.py index ea41cdeb..2a20fd08 100644 --- a/features/steps/numbering.py +++ b/features/steps/numbering.py @@ -13,14 +13,16 @@ # given =================================================== -@given('a document having a numbering part') + +@given("a document having a numbering part") def given_a_document_having_a_numbering_part(context): - context.document = Document(test_docx('num-having-numbering-part')) + context.document = Document(test_docx("num-having-numbering-part")) # when ==================================================== -@when('I get the numbering part from the document') + +@when("I get the numbering part from the document") def when_get_numbering_part_from_document(context): document = context.document context.numbering_part = document.part.numbering_part @@ -28,7 +30,8 @@ def when_get_numbering_part_from_document(context): # then ===================================================== -@then('the numbering part has the expected numbering definitions') + +@then("the numbering part has the expected numbering definitions") def then_numbering_part_has_expected_numbering_definitions(context): numbering_part = context.numbering_part assert len(numbering_part.numbering_definitions) == 10 diff --git a/features/steps/paragraph.py b/features/steps/paragraph.py index 3f47df9f..d372983a 100644 --- a/features/steps/paragraph.py +++ b/features/steps/paragraph.py @@ -15,83 +15,86 @@ # given =================================================== -@given('a document containing three paragraphs') + +@given("a document containing three paragraphs") def given_a_document_containing_three_paragraphs(context): document = Document() - document.add_paragraph('foo') - document.add_paragraph('bar') - document.add_paragraph('baz') + document.add_paragraph("foo") + document.add_paragraph("bar") + document.add_paragraph("baz") context.document = document -@given('a paragraph having {align_type} alignment') +@given("a paragraph having {align_type} alignment") def given_a_paragraph_align_type_alignment(context, align_type): paragraph_idx = { - 'inherited': 0, - 'left': 1, - 'center': 2, - 'right': 3, - 'justified': 4, + "inherited": 0, + "left": 1, + "center": 2, + "right": 3, + "justified": 4, }[align_type] - document = Document(test_docx('par-alignment')) + document = Document(test_docx("par-alignment")) context.paragraph = document.paragraphs[paragraph_idx] -@given('a paragraph having {style_state} style') +@given("a paragraph having {style_state} style") def given_a_paragraph_having_style(context, style_state): paragraph_idx = { - 'no specified': 0, - 'a missing': 1, - 'Heading 1': 2, - 'Body Text': 3, + "no specified": 0, + "a missing": 1, + "Heading 1": 2, + "Body Text": 3, }[style_state] - document = context.document = Document(test_docx('par-known-styles')) + document = context.document = Document(test_docx("par-known-styles")) context.paragraph = document.paragraphs[paragraph_idx] -@given('a paragraph with content and formatting') +@given("a paragraph with content and formatting") def given_a_paragraph_with_content_and_formatting(context): - document = Document(test_docx('par-known-paragraphs')) + document = Document(test_docx("par-known-paragraphs")) context.paragraph = document.paragraphs[0] # when ==================================================== -@when('I add a run to the paragraph') + +@when("I add a run to the paragraph") def when_add_new_run_to_paragraph(context): context.run = context.p.add_run() -@when('I assign a {style_type} to paragraph.style') +@when("I assign a {style_type} to paragraph.style") def when_I_assign_a_style_type_to_paragraph_style(context, style_type): paragraph = context.paragraph - style = context.style = context.document.styles['Heading 1'] + style = context.style = context.document.styles["Heading 1"] style_spec = { - 'style object': style, - 'style name': 'Heading 1', + "style object": style, + "style name": "Heading 1", }[style_type] paragraph.style = style_spec -@when('I clear the paragraph content') +@when("I clear the paragraph content") def when_I_clear_the_paragraph_content(context): context.paragraph.clear() -@when('I insert a paragraph above the second paragraph') +@when("I insert a paragraph above the second paragraph") def when_I_insert_a_paragraph_above_the_second_paragraph(context): paragraph = context.document.paragraphs[1] - paragraph.insert_paragraph_before('foobar', 'Heading1') + paragraph.insert_paragraph_before("foobar", "Heading1") -@when('I set the paragraph text') +@when("I set the paragraph text") def when_I_set_the_paragraph_text(context): - context.paragraph.text = 'bar\tfoo\r' + context.paragraph.text = "bar\tfoo\r" # then ===================================================== -@then('paragraph.paragraph_format is its ParagraphFormat object') + +@then("paragraph.paragraph_format is its ParagraphFormat object") def then_paragraph_paragraph_format_is_its_parfmt_object(context): paragraph = context.paragraph paragraph_format = paragraph.paragraph_format @@ -99,24 +102,24 @@ def then_paragraph_paragraph_format_is_its_parfmt_object(context): assert paragraph_format.element is paragraph._element -@then('paragraph.style is {value_key}') +@then("paragraph.style is {value_key}") def then_paragraph_style_is_value(context, value_key): styles = context.document.styles expected_value = { - 'Normal': styles['Normal'], - 'Heading 1': styles['Heading 1'], - 'Body Text': styles['Body Text'], + "Normal": styles["Normal"], + "Heading 1": styles["Heading 1"], + "Body Text": styles["Body Text"], }[value_key] paragraph = context.paragraph assert paragraph.style == expected_value -@then('the document contains four paragraphs') +@then("the document contains four paragraphs") def then_the_document_contains_four_paragraphs(context): assert len(context.document.paragraphs) == 4 -@then('the document contains the text I added') +@then("the document contains the text I added") def then_document_contains_text_I_added(context): document = Document(saved_docx_path) paragraphs = document.paragraphs @@ -125,46 +128,46 @@ def then_document_contains_text_I_added(context): assert r.text == test_text -@then('the paragraph alignment property value is {align_value}') +@then("the paragraph alignment property value is {align_value}") def then_the_paragraph_alignment_prop_value_is_value(context, align_value): expected_value = { - 'None': None, - 'WD_ALIGN_PARAGRAPH.LEFT': WD_ALIGN_PARAGRAPH.LEFT, - 'WD_ALIGN_PARAGRAPH.CENTER': WD_ALIGN_PARAGRAPH.CENTER, - 'WD_ALIGN_PARAGRAPH.RIGHT': WD_ALIGN_PARAGRAPH.RIGHT, + "None": None, + "WD_ALIGN_PARAGRAPH.LEFT": WD_ALIGN_PARAGRAPH.LEFT, + "WD_ALIGN_PARAGRAPH.CENTER": WD_ALIGN_PARAGRAPH.CENTER, + "WD_ALIGN_PARAGRAPH.RIGHT": WD_ALIGN_PARAGRAPH.RIGHT, }[align_value] assert context.paragraph.alignment == expected_value -@then('the paragraph formatting is preserved') +@then("the paragraph formatting is preserved") def then_the_paragraph_formatting_is_preserved(context): paragraph = context.paragraph - assert paragraph.style.name == 'Heading 1' + assert paragraph.style.name == "Heading 1" -@then('the paragraph has no content') +@then("the paragraph has no content") def then_the_paragraph_has_no_content(context): - assert context.paragraph.text == '' + assert context.paragraph.text == "" -@then('the paragraph has the style I set') +@then("the paragraph has the style I set") def then_the_paragraph_has_the_style_I_set(context): paragraph, expected_style = context.paragraph, context.style assert paragraph.style == expected_style -@then('the paragraph has the text I set') +@then("the paragraph has the text I set") def then_the_paragraph_has_the_text_I_set(context): - assert context.paragraph.text == 'bar\tfoo\n' + assert context.paragraph.text == "bar\tfoo\n" -@then('the style of the second paragraph matches the style I set') +@then("the style of the second paragraph matches the style I set") def then_the_style_of_the_second_paragraph_matches_the_style_I_set(context): second_paragraph = context.document.paragraphs[1] - assert second_paragraph.style.name == 'Heading 1' + assert second_paragraph.style.name == "Heading 1" -@then('the text of the second paragraph matches the text I set') +@then("the text of the second paragraph matches the text I set") def then_the_text_of_the_second_paragraph_matches_the_text_I_set(context): second_paragraph = context.document.paragraphs[1] - assert second_paragraph.text == 'foobar' + assert second_paragraph.text == "foobar" diff --git a/features/steps/parfmt.py b/features/steps/parfmt.py index f3203f7e..197cf162 100644 --- a/features/steps/parfmt.py +++ b/features/steps/parfmt.py @@ -4,9 +4,7 @@ Step implementations for paragraph format-related features. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals from behave import given, then, when @@ -20,156 +18,157 @@ # given =================================================== -@given('a paragraph format') + +@given("a paragraph format") def given_a_paragraph_format(context): - document = Document(test_docx('tab-stops')) + document = Document(test_docx("tab-stops")) context.paragraph_format = document.paragraphs[0].paragraph_format -@given('a paragraph format having {prop_name} set {setting}') +@given("a paragraph format having {prop_name} set {setting}") def given_a_paragraph_format_having_prop_set(context, prop_name, setting): style_name = { - 'to inherit': 'Normal', - 'On': 'Base', - 'Off': 'Citation', + "to inherit": "Normal", + "On": "Base", + "Off": "Citation", }[setting] - document = Document(test_docx('sty-known-styles')) + document = Document(test_docx("sty-known-styles")) context.paragraph_format = document.styles[style_name].paragraph_format -@given('a paragraph format having {setting} line spacing') +@given("a paragraph format having {setting} line spacing") def given_a_paragraph_format_having_setting_line_spacing(context, setting): style_name = { - 'inherited': 'Normal', - '14 pt': 'Base', - 'double': 'Citation', + "inherited": "Normal", + "14 pt": "Base", + "double": "Citation", }[setting] - document = Document(test_docx('sty-known-styles')) + document = Document(test_docx("sty-known-styles")) context.paragraph_format = document.styles[style_name].paragraph_format -@given('a paragraph format having {setting} space {side}') +@given("a paragraph format having {setting} space {side}") def given_a_paragraph_format_having_setting_spacing(context, setting, side): - style_name = 'Normal' if setting == 'inherited' else 'Base' - document = Document(test_docx('sty-known-styles')) + style_name = "Normal" if setting == "inherited" else "Base" + document = Document(test_docx("sty-known-styles")) context.paragraph_format = document.styles[style_name].paragraph_format -@given('a paragraph format having {type} alignment') +@given("a paragraph format having {type} alignment") def given_a_paragraph_format_having_align_type_alignment(context, type): style_name = { - 'inherited': 'Normal', - 'center': 'Base', - 'right': 'Citation', + "inherited": "Normal", + "center": "Base", + "right": "Citation", }[type] - document = Document(test_docx('sty-known-styles')) + document = Document(test_docx("sty-known-styles")) context.paragraph_format = document.styles[style_name].paragraph_format -@given('a paragraph format having {type} indent of {value}') +@given("a paragraph format having {type} indent of {value}") def given_a_paragraph_format_having_type_indent_value(context, type, value): style_name = { - 'inherit': 'Normal', - '18 pt': 'Base', - '17.3 pt': 'Base', - '-17.3 pt': 'Citation', - '46.1 pt': 'Citation', + "inherit": "Normal", + "18 pt": "Base", + "17.3 pt": "Base", + "-17.3 pt": "Citation", + "46.1 pt": "Citation", }[value] - document = Document(test_docx('sty-known-styles')) + document = Document(test_docx("sty-known-styles")) context.paragraph_format = document.styles[style_name].paragraph_format # when ==================================================== -@when('I assign {value} to paragraph_format.line_spacing') + +@when("I assign {value} to paragraph_format.line_spacing") def when_I_assign_value_to_paragraph_format_line_spacing(context, value): new_value = { - 'Pt(14)': Pt(14), - '2': 2, + "Pt(14)": Pt(14), + "2": 2, }.get(value) new_value = float(value) if new_value is None else new_value context.paragraph_format.line_spacing = new_value -@when('I assign {value} to paragraph_format.line_spacing_rule') +@when("I assign {value} to paragraph_format.line_spacing_rule") def when_I_assign_value_to_paragraph_format_line_rule(context, value): new_value = { - 'None': None, - 'WD_LINE_SPACING.EXACTLY': WD_LINE_SPACING.EXACTLY, - 'WD_LINE_SPACING.MULTIPLE': WD_LINE_SPACING.MULTIPLE, - 'WD_LINE_SPACING.SINGLE': WD_LINE_SPACING.SINGLE, - 'WD_LINE_SPACING.DOUBLE': WD_LINE_SPACING.DOUBLE, - 'WD_LINE_SPACING.AT_LEAST': WD_LINE_SPACING.AT_LEAST, - 'WD_LINE_SPACING.ONE_POINT_FIVE': WD_LINE_SPACING.ONE_POINT_FIVE, + "None": None, + "WD_LINE_SPACING.EXACTLY": WD_LINE_SPACING.EXACTLY, + "WD_LINE_SPACING.MULTIPLE": WD_LINE_SPACING.MULTIPLE, + "WD_LINE_SPACING.SINGLE": WD_LINE_SPACING.SINGLE, + "WD_LINE_SPACING.DOUBLE": WD_LINE_SPACING.DOUBLE, + "WD_LINE_SPACING.AT_LEAST": WD_LINE_SPACING.AT_LEAST, + "WD_LINE_SPACING.ONE_POINT_FIVE": WD_LINE_SPACING.ONE_POINT_FIVE, }[value] paragraph_format = context.paragraph_format paragraph_format.line_spacing_rule = new_value -@when('I assign {value} to paragraph_format.alignment') +@when("I assign {value} to paragraph_format.alignment") def when_I_assign_value_to_paragraph_format_alignment(context, value): new_value = { - 'None': None, - 'WD_ALIGN_PARAGRAPH.CENTER': WD_ALIGN_PARAGRAPH.CENTER, - 'WD_ALIGN_PARAGRAPH.RIGHT': WD_ALIGN_PARAGRAPH.RIGHT, + "None": None, + "WD_ALIGN_PARAGRAPH.CENTER": WD_ALIGN_PARAGRAPH.CENTER, + "WD_ALIGN_PARAGRAPH.RIGHT": WD_ALIGN_PARAGRAPH.RIGHT, }[value] paragraph_format = context.paragraph_format paragraph_format.alignment = new_value -@when('I assign {value} to paragraph_format.space_{side}') +@when("I assign {value} to paragraph_format.space_{side}") def when_I_assign_value_to_paragraph_format_space(context, value, side): paragraph_format = context.paragraph_format - prop_name = 'space_%s' % side + prop_name = "space_%s" % side new_value = { - 'None': None, - 'Pt(12)': Pt(12), - 'Pt(18)': Pt(18), + "None": None, + "Pt(12)": Pt(12), + "Pt(18)": Pt(18), }[value] setattr(paragraph_format, prop_name, new_value) -@when('I assign {value} to paragraph_format.{type_}_indent') +@when("I assign {value} to paragraph_format.{type_}_indent") def when_I_assign_value_to_paragraph_format_indent(context, value, type_): paragraph_format = context.paragraph_format - prop_name = '%s_indent' % type_ - value = None if value == 'None' else Pt(float(value.split()[0])) + prop_name = "%s_indent" % type_ + value = None if value == "None" else Pt(float(value.split()[0])) setattr(paragraph_format, prop_name, value) -@when('I assign {value} to paragraph_format.{prop_name}') +@when("I assign {value} to paragraph_format.{prop_name}") def when_I_assign_value_to_paragraph_format_prop(context, value, prop_name): paragraph_format = context.paragraph_format - value = {'None': None, 'True': True, 'False': False}[value] + value = {"None": None, "True": True, "False": False}[value] setattr(paragraph_format, prop_name, value) # then ===================================================== -@then('paragraph_format.tab_stops is a TabStops object') + +@then("paragraph_format.tab_stops is a TabStops object") def then_paragraph_format_tab_stops_is_a_tabstops_object(context): tab_stops = context.paragraph_format.tab_stops assert isinstance(tab_stops, TabStops) -@then('paragraph_format.alignment is {value}') +@then("paragraph_format.alignment is {value}") def then_paragraph_format_alignment_is_value(context, value): expected_value = { - 'None': None, - 'WD_ALIGN_PARAGRAPH.LEFT': WD_ALIGN_PARAGRAPH.LEFT, - 'WD_ALIGN_PARAGRAPH.CENTER': WD_ALIGN_PARAGRAPH.CENTER, - 'WD_ALIGN_PARAGRAPH.RIGHT': WD_ALIGN_PARAGRAPH.RIGHT, + "None": None, + "WD_ALIGN_PARAGRAPH.LEFT": WD_ALIGN_PARAGRAPH.LEFT, + "WD_ALIGN_PARAGRAPH.CENTER": WD_ALIGN_PARAGRAPH.CENTER, + "WD_ALIGN_PARAGRAPH.RIGHT": WD_ALIGN_PARAGRAPH.RIGHT, }[value] paragraph_format = context.paragraph_format assert paragraph_format.alignment == expected_value -@then('paragraph_format.line_spacing is {value}') +@then("paragraph_format.line_spacing is {value}") def then_paragraph_format_line_spacing_is_value(context, value): expected_value = ( - None if value == 'None' else - float(value) if '.' in value else - int(value) + None if value == "None" else float(value) if "." in value else int(value) ) paragraph_format = context.paragraph_format @@ -179,42 +178,42 @@ def then_paragraph_format_line_spacing_is_value(context, value): assert abs(paragraph_format.line_spacing - expected_value) < 0.001 -@then('paragraph_format.line_spacing_rule is {value}') +@then("paragraph_format.line_spacing_rule is {value}") def then_paragraph_format_line_spacing_rule_is_value(context, value): expected_value = { - 'None': None, - 'WD_LINE_SPACING.EXACTLY': WD_LINE_SPACING.EXACTLY, - 'WD_LINE_SPACING.MULTIPLE': WD_LINE_SPACING.MULTIPLE, - 'WD_LINE_SPACING.SINGLE': WD_LINE_SPACING.SINGLE, - 'WD_LINE_SPACING.DOUBLE': WD_LINE_SPACING.DOUBLE, - 'WD_LINE_SPACING.AT_LEAST': WD_LINE_SPACING.AT_LEAST, - 'WD_LINE_SPACING.ONE_POINT_FIVE': WD_LINE_SPACING.ONE_POINT_FIVE, + "None": None, + "WD_LINE_SPACING.EXACTLY": WD_LINE_SPACING.EXACTLY, + "WD_LINE_SPACING.MULTIPLE": WD_LINE_SPACING.MULTIPLE, + "WD_LINE_SPACING.SINGLE": WD_LINE_SPACING.SINGLE, + "WD_LINE_SPACING.DOUBLE": WD_LINE_SPACING.DOUBLE, + "WD_LINE_SPACING.AT_LEAST": WD_LINE_SPACING.AT_LEAST, + "WD_LINE_SPACING.ONE_POINT_FIVE": WD_LINE_SPACING.ONE_POINT_FIVE, }[value] paragraph_format = context.paragraph_format assert paragraph_format.line_spacing_rule == expected_value -@then('paragraph_format.space_{side} is {value}') +@then("paragraph_format.space_{side} is {value}") def then_paragraph_format_space_side_is_value(context, side, value): - expected_value = None if value == 'None' else int(value) - prop_name = 'space_%s' % side + expected_value = None if value == "None" else int(value) + prop_name = "space_%s" % side paragraph_format = context.paragraph_format actual_value = getattr(paragraph_format, prop_name) assert actual_value == expected_value -@then('paragraph_format.{type_}_indent is {value}') +@then("paragraph_format.{type_}_indent is {value}") def then_paragraph_format_type_indent_is_value(context, type_, value): - expected_value = None if value == 'None' else int(value) - prop_name = '%s_indent' % type_ + expected_value = None if value == "None" else int(value) + prop_name = "%s_indent" % type_ paragraph_format = context.paragraph_format actual_value = getattr(paragraph_format, prop_name) assert actual_value == expected_value -@then('paragraph_format.{prop_name} is {value}') +@then("paragraph_format.{prop_name} is {value}") def then_paragraph_format_prop_name_is_value(context, prop_name, value): - expected_value = {'None': None, 'True': True, 'False': False}[value] + expected_value = {"None": None, "True": True, "False": False}[value] paragraph_format = context.paragraph_format actual_value = getattr(paragraph_format, prop_name) assert actual_value == expected_value diff --git a/features/steps/section.py b/features/steps/section.py index 91209eac..1eae8017 100644 --- a/features/steps/section.py +++ b/features/steps/section.py @@ -18,6 +18,7 @@ # given ==================================================== + @given("a Section object as section") def given_a_Section_object_as_section(context): context.section = Document(test_docx("sct-section-props")).sections[-1] @@ -29,105 +30,104 @@ def given_a_Section_object_with_or_without_first_page_header(context, with_or_wi context.section = Document(test_docx("sct-first-page-hdrftr")).sections[section_idx] -@given('a section collection containing 3 sections') +@given("a section collection containing 3 sections") def given_a_section_collection_containing_3_sections(context): - document = Document(test_docx('doc-access-sections')) + document = Document(test_docx("doc-access-sections")) context.sections = document.sections -@given('a section having known page dimension') +@given("a section having known page dimension") def given_a_section_having_known_page_dimension(context): - document = Document(test_docx('sct-section-props')) + document = Document(test_docx("sct-section-props")) context.section = document.sections[-1] -@given('a section having known page margins') +@given("a section having known page margins") def given_a_section_having_known_page_margins(context): - document = Document(test_docx('sct-section-props')) + document = Document(test_docx("sct-section-props")) context.section = document.sections[0] -@given('a section having start type {start_type}') +@given("a section having start type {start_type}") def given_a_section_having_start_type(context, start_type): section_idx = { - 'CONTINUOUS': 0, - 'NEW_PAGE': 1, - 'ODD_PAGE': 2, - 'EVEN_PAGE': 3, - 'NEW_COLUMN': 4, + "CONTINUOUS": 0, + "NEW_PAGE": 1, + "ODD_PAGE": 2, + "EVEN_PAGE": 3, + "NEW_COLUMN": 4, }[start_type] - document = Document(test_docx('sct-section-props')) + document = Document(test_docx("sct-section-props")) context.section = document.sections[section_idx] -@given('a section known to have {orientation} orientation') +@given("a section known to have {orientation} orientation") def given_a_section_having_known_orientation(context, orientation): - section_idx = { - 'landscape': 0, - 'portrait': 1 - }[orientation] - document = Document(test_docx('sct-section-props')) + section_idx = {"landscape": 0, "portrait": 1}[orientation] + document = Document(test_docx("sct-section-props")) context.section = document.sections[section_idx] # when ===================================================== + @when("I assign {bool_val} to section.different_first_page_header_footer") def when_I_assign_value_to_section_different_first_page_hdrftr(context, bool_val): context.section.different_first_page_header_footer = eval(bool_val) -@when('I set the {margin_side} margin to {inches} inches') +@when("I set the {margin_side} margin to {inches} inches") def when_I_set_the_margin_side_length(context, margin_side, inches): prop_name = { - 'left': 'left_margin', - 'right': 'right_margin', - 'top': 'top_margin', - 'bottom': 'bottom_margin', - 'gutter': 'gutter', - 'header': 'header_distance', - 'footer': 'footer_distance', + "left": "left_margin", + "right": "right_margin", + "top": "top_margin", + "bottom": "bottom_margin", + "gutter": "gutter", + "header": "header_distance", + "footer": "footer_distance", }[margin_side] new_value = Inches(float(inches)) setattr(context.section, prop_name, new_value) -@when('I set the section orientation to {orientation}') +@when("I set the section orientation to {orientation}") def when_I_set_the_section_orientation(context, orientation): new_orientation = { - 'WD_ORIENT.PORTRAIT': WD_ORIENT.PORTRAIT, - 'WD_ORIENT.LANDSCAPE': WD_ORIENT.LANDSCAPE, - 'None': None, + "WD_ORIENT.PORTRAIT": WD_ORIENT.PORTRAIT, + "WD_ORIENT.LANDSCAPE": WD_ORIENT.LANDSCAPE, + "None": None, }[orientation] context.section.orientation = new_orientation -@when('I set the section page height to {y} inches') +@when("I set the section page height to {y} inches") def when_I_set_the_section_page_height_to_y_inches(context, y): context.section.page_height = Inches(float(y)) -@when('I set the section page width to {x} inches') +@when("I set the section page width to {x} inches") def when_I_set_the_section_page_width_to_x_inches(context, x): context.section.page_width = Inches(float(x)) -@when('I set the section start type to {start_type}') +@when("I set the section start type to {start_type}") def when_I_set_the_section_start_type_to_start_type(context, start_type): new_start_type = { - 'None': None, - 'CONTINUOUS': WD_SECTION.CONTINUOUS, - 'EVEN_PAGE': WD_SECTION.EVEN_PAGE, - 'NEW_COLUMN': WD_SECTION.NEW_COLUMN, - 'NEW_PAGE': WD_SECTION.NEW_PAGE, - 'ODD_PAGE': WD_SECTION.ODD_PAGE, + "None": None, + "CONTINUOUS": WD_SECTION.CONTINUOUS, + "EVEN_PAGE": WD_SECTION.EVEN_PAGE, + "NEW_COLUMN": WD_SECTION.NEW_COLUMN, + "NEW_PAGE": WD_SECTION.NEW_PAGE, + "ODD_PAGE": WD_SECTION.ODD_PAGE, }[start_type] context.section.start_type = new_start_type # then ===================================================== -@then('I can access a section by index') + +@then("I can access a section by index") def then_I_can_access_a_section_by_index(context): sections = context.sections for idx in range(3): @@ -135,7 +135,7 @@ def then_I_can_access_a_section_by_index(context): assert isinstance(section, Section) -@then('I can iterate over the sections') +@then("I can iterate over the sections") def then_I_can_iterate_over_the_sections(context): sections = context.sections actual_count = 0 @@ -145,12 +145,10 @@ def then_I_can_iterate_over_the_sections(context): assert actual_count == 3 -@then('len(sections) is 3') +@then("len(sections) is 3") def then_len_sections_is_3(context): sections = context.sections - assert len(sections) == 3, ( - 'expected len(sections) of 3, got %s' % len(sections) - ) + assert len(sections) == 3, "expected len(sections) of 3, got %s" % len(sections) @then("section.different_first_page_header_footer is {bool_val}") @@ -208,53 +206,54 @@ def then_section_header_is_a_Header_object(context): def then_section_hdrftr_prop_is_linked_to_previous_is_True(context, propname): actual = getattr(context.section, propname).is_linked_to_previous expected = True - assert actual == expected, ( - "section.%s.is_linked_to_previous is %s" % (propname, actual) + assert actual == expected, "section.%s.is_linked_to_previous is %s" % ( + propname, + actual, ) -@then('the reported {margin_side} margin is {inches} inches') +@then("the reported {margin_side} margin is {inches} inches") def then_the_reported_margin_is_inches(context, margin_side, inches): prop_name = { - 'left': 'left_margin', - 'right': 'right_margin', - 'top': 'top_margin', - 'bottom': 'bottom_margin', - 'gutter': 'gutter', - 'header': 'header_distance', - 'footer': 'footer_distance', + "left": "left_margin", + "right": "right_margin", + "top": "top_margin", + "bottom": "bottom_margin", + "gutter": "gutter", + "header": "header_distance", + "footer": "footer_distance", }[margin_side] expected_value = Inches(float(inches)) actual_value = getattr(context.section, prop_name) assert actual_value == expected_value -@then('the reported page orientation is {orientation}') +@then("the reported page orientation is {orientation}") def then_the_reported_page_orientation_is_orientation(context, orientation): expected_value = { - 'WD_ORIENT.LANDSCAPE': WD_ORIENT.LANDSCAPE, - 'WD_ORIENT.PORTRAIT': WD_ORIENT.PORTRAIT, + "WD_ORIENT.LANDSCAPE": WD_ORIENT.LANDSCAPE, + "WD_ORIENT.PORTRAIT": WD_ORIENT.PORTRAIT, }[orientation] assert context.section.orientation == expected_value -@then('the reported page width is {x} inches') +@then("the reported page width is {x} inches") def then_the_reported_page_width_is_width(context, x): assert context.section.page_width == Inches(float(x)) -@then('the reported page height is {y} inches') +@then("the reported page height is {y} inches") def then_the_reported_page_height_is_11_inches(context, y): assert context.section.page_height == Inches(float(y)) -@then('the reported section start type is {start_type}') +@then("the reported section start type is {start_type}") def then_the_reported_section_start_type_is_type(context, start_type): expected_start_type = { - 'CONTINUOUS': WD_SECTION.CONTINUOUS, - 'EVEN_PAGE': WD_SECTION.EVEN_PAGE, - 'NEW_COLUMN': WD_SECTION.NEW_COLUMN, - 'NEW_PAGE': WD_SECTION.NEW_PAGE, - 'ODD_PAGE': WD_SECTION.ODD_PAGE, + "CONTINUOUS": WD_SECTION.CONTINUOUS, + "EVEN_PAGE": WD_SECTION.EVEN_PAGE, + "NEW_COLUMN": WD_SECTION.NEW_COLUMN, + "NEW_PAGE": WD_SECTION.NEW_PAGE, + "ODD_PAGE": WD_SECTION.ODD_PAGE, }[start_type] assert context.section.start_type == expected_start_type diff --git a/features/steps/settings.py b/features/steps/settings.py index f770f8c1..9c6d94e2 100644 --- a/features/steps/settings.py +++ b/features/steps/settings.py @@ -14,26 +14,28 @@ # given ==================================================== -@given('a document having a settings part') + +@given("a document having a settings part") def given_a_document_having_a_settings_part(context): - context.document = Document(test_docx('doc-word-default-blank')) + context.document = Document(test_docx("doc-word-default-blank")) -@given('a document having no settings part') +@given("a document having no settings part") def given_a_document_having_no_settings_part(context): - context.document = Document(test_docx('set-no-settings-part')) + context.document = Document(test_docx("set-no-settings-part")) @given("a Settings object {with_or_without} odd and even page headers as settings") def given_a_Settings_object_with_or_without_odd_and_even_hdrs(context, with_or_without): - testfile_name = { - "with": "doc-odd-even-hdrs", "without": "sct-section-props" - }[with_or_without] + testfile_name = {"with": "doc-odd-even-hdrs", "without": "sct-section-props"}[ + with_or_without + ] context.settings = Document(test_docx(testfile_name)).settings # when ===================================================== + @when("I assign {bool_val} to settings.odd_and_even_pages_header_footer") def when_I_assign_value_to_settings_odd_and_even_pages_header_footer(context, bool_val): context.settings.odd_and_even_pages_header_footer = eval(bool_val) @@ -41,7 +43,8 @@ def when_I_assign_value_to_settings_odd_and_even_pages_header_footer(context, bo # then ===================================================== -@then('document.settings is a Settings object') + +@then("document.settings is a Settings object") def then_document_settings_is_a_Settings_object(context): document = context.document assert type(document.settings) is Settings diff --git a/features/steps/shape.py b/features/steps/shape.py index 1a8d0c60..b35b385a 100644 --- a/features/steps/shape.py +++ b/features/steps/shape.py @@ -20,36 +20,38 @@ # given =================================================== -@given('an inline shape collection containing five shapes') + +@given("an inline shape collection containing five shapes") def given_an_inline_shape_collection_containing_five_shapes(context): - docx_path = test_docx('shp-inline-shape-access') + docx_path = test_docx("shp-inline-shape-access") document = Document(docx_path) context.inline_shapes = document.inline_shapes -@given('an inline shape of known dimensions') +@given("an inline shape of known dimensions") def given_inline_shape_of_known_dimensions(context): - document = Document(test_docx('shp-inline-shape-access')) + document = Document(test_docx("shp-inline-shape-access")) context.inline_shape = document.inline_shapes[0] -@given('an inline shape known to be {shp_of_type}') +@given("an inline shape known to be {shp_of_type}") def given_inline_shape_known_to_be_shape_of_type(context, shp_of_type): inline_shape_idx = { - 'an embedded picture': 0, - 'a linked picture': 1, - 'a link+embed picture': 2, - 'a smart art diagram': 3, - 'a chart': 4, + "an embedded picture": 0, + "a linked picture": 1, + "a link+embed picture": 2, + "a smart art diagram": 3, + "a chart": 4, }[shp_of_type] - docx_path = test_docx('shp-inline-shape-access') + docx_path = test_docx("shp-inline-shape-access") document = Document(docx_path) context.inline_shape = document.inline_shapes[inline_shape_idx] # when ===================================================== -@when('I change the dimensions of the inline shape') + +@when("I change the dimensions of the inline shape") def when_change_dimensions_of_inline_shape(context): inline_shape = context.inline_shape inline_shape.width = Inches(1) @@ -58,7 +60,8 @@ def when_change_dimensions_of_inline_shape(context): # then ===================================================== -@then('I can access each inline shape by index') + +@then("I can access each inline shape by index") def then_can_access_each_inline_shape_by_index(context): inline_shapes = context.inline_shapes for idx in range(2): @@ -66,7 +69,7 @@ def then_can_access_each_inline_shape_by_index(context): assert isinstance(inline_shape, InlineShape) -@then('I can iterate over the inline shape collection') +@then("I can iterate over the inline shape collection") def then_can_iterate_over_inline_shape_collection(context): inline_shapes = context.inline_shapes shape_count = 0 @@ -74,38 +77,39 @@ def then_can_iterate_over_inline_shape_collection(context): shape_count += 1 assert isinstance(inline_shape, InlineShape) expected_count = 5 - assert shape_count == expected_count, ( - 'expected %d, got %d' % (expected_count, shape_count) + assert shape_count == expected_count, "expected %d, got %d" % ( + expected_count, + shape_count, ) -@then('its inline shape type is {shape_type}') +@then("its inline shape type is {shape_type}") def then_inline_shape_type_is_shape_type(context, shape_type): expected_value = { - 'WD_INLINE_SHAPE.CHART': WD_INLINE_SHAPE.CHART, - 'WD_INLINE_SHAPE.LINKED_PICTURE': WD_INLINE_SHAPE.LINKED_PICTURE, - 'WD_INLINE_SHAPE.PICTURE': WD_INLINE_SHAPE.PICTURE, - 'WD_INLINE_SHAPE.SMART_ART': WD_INLINE_SHAPE.SMART_ART, + "WD_INLINE_SHAPE.CHART": WD_INLINE_SHAPE.CHART, + "WD_INLINE_SHAPE.LINKED_PICTURE": WD_INLINE_SHAPE.LINKED_PICTURE, + "WD_INLINE_SHAPE.PICTURE": WD_INLINE_SHAPE.PICTURE, + "WD_INLINE_SHAPE.SMART_ART": WD_INLINE_SHAPE.SMART_ART, }[shape_type] inline_shape = context.inline_shape assert inline_shape.type == expected_value -@then('the dimensions of the inline shape match the known values') +@then("the dimensions of the inline shape match the known values") def then_dimensions_of_inline_shape_match_known_values(context): inline_shape = context.inline_shape - assert inline_shape.width == 1778000, 'got %s' % inline_shape.width - assert inline_shape.height == 711200, 'got %s' % inline_shape.height + assert inline_shape.width == 1778000, "got %s" % inline_shape.width + assert inline_shape.height == 711200, "got %s" % inline_shape.height -@then('the dimensions of the inline shape match the new values') +@then("the dimensions of the inline shape match the new values") def then_dimensions_of_inline_shape_match_new_values(context): inline_shape = context.inline_shape - assert inline_shape.width == 914400, 'got %s' % inline_shape.width - assert inline_shape.height == 457200, 'got %s' % inline_shape.height + assert inline_shape.width == 914400, "got %s" % inline_shape.width + assert inline_shape.height == 457200, "got %s" % inline_shape.height -@then('the document contains the inline picture') +@then("the document contains the inline picture") def then_the_document_contains_the_inline_picture(context): document = context.document picture_shape = document.inline_shapes[0] @@ -113,42 +117,41 @@ def then_the_document_contains_the_inline_picture(context): rId = blip.embed image_part = document.part.related_parts[rId] image_sha1 = hashlib.sha1(image_part.blob).hexdigest() - expected_sha1 = '79769f1e202add2e963158b532e36c2c0f76a70c' - assert image_sha1 == expected_sha1, ( - "image SHA1 doesn't match, expected %s, got %s" % - (expected_sha1, image_sha1) - ) + expected_sha1 = "79769f1e202add2e963158b532e36c2c0f76a70c" + assert ( + image_sha1 == expected_sha1 + ), "image SHA1 doesn't match, expected %s, got %s" % (expected_sha1, image_sha1) -@then('the length of the inline shape collection is 5') +@then("the length of the inline shape collection is 5") def then_len_of_inline_shape_collection_is_5(context): inline_shapes = context.inline_shapes shape_count = len(inline_shapes) - assert shape_count == 5, 'got %s' % shape_count + assert shape_count == 5, "got %s" % shape_count -@then('the picture has its native width and height') +@then("the picture has its native width and height") def then_picture_has_native_width_and_height(context): picture = context.picture - assert picture.width == 1905000, 'got %d' % picture.width - assert picture.height == 2717800, 'got %d' % picture.height + assert picture.width == 1905000, "got %d" % picture.width + assert picture.height == 2717800, "got %d" % picture.height -@then('picture.height is {inches} inches') +@then("picture.height is {inches} inches") def then_picture_height_is_value(context, inches): expected_value = { - '2.14': 1956816, - '2.5': 2286000, + "2.14": 1956816, + "2.5": 2286000, }[inches] picture = context.picture - assert picture.height == expected_value, 'got %d' % picture.height + assert picture.height == expected_value, "got %d" % picture.height -@then('picture.width is {inches} inches') +@then("picture.width is {inches} inches") def then_picture_width_is_value(context, inches): expected_value = { - '1.05': 961402, - '1.75': 1600200, + "1.05": 961402, + "1.75": 1600200, }[inches] picture = context.picture - assert picture.width == expected_value, 'got %d' % picture.width + assert picture.width == expected_value, "got %d" % picture.width diff --git a/features/steps/shared.py b/features/steps/shared.py index 5e82e24a..c5e2881f 100644 --- a/features/steps/shared.py +++ b/features/steps/shared.py @@ -15,14 +15,16 @@ # given =================================================== -@given('a document') + +@given("a document") def given_a_document(context): context.document = Document() # when ==================================================== -@when('I save the document') + +@when("I save the document") def when_save_document(context): if os.path.isfile(saved_docx_path): os.remove(saved_docx_path) diff --git a/features/steps/styles.py b/features/steps/styles.py index 01927bcd..c4b34be8 100644 --- a/features/steps/styles.py +++ b/features/steps/styles.py @@ -16,266 +16,266 @@ from helpers import bool_vals, test_docx, tri_state_vals style_types = { - 'WD_STYLE_TYPE.CHARACTER': WD_STYLE_TYPE.CHARACTER, - 'WD_STYLE_TYPE.PARAGRAPH': WD_STYLE_TYPE.PARAGRAPH, - 'WD_STYLE_TYPE.LIST': WD_STYLE_TYPE.LIST, - 'WD_STYLE_TYPE.TABLE': WD_STYLE_TYPE.TABLE, + "WD_STYLE_TYPE.CHARACTER": WD_STYLE_TYPE.CHARACTER, + "WD_STYLE_TYPE.PARAGRAPH": WD_STYLE_TYPE.PARAGRAPH, + "WD_STYLE_TYPE.LIST": WD_STYLE_TYPE.LIST, + "WD_STYLE_TYPE.TABLE": WD_STYLE_TYPE.TABLE, } # given =================================================== -@given('a document having a styles part') + +@given("a document having a styles part") def given_a_document_having_a_styles_part(context): - docx_path = test_docx('sty-having-styles-part') + docx_path = test_docx("sty-having-styles-part") context.document = Document(docx_path) -@given('a document having known styles') +@given("a document having known styles") def given_a_document_having_known_styles(context): - docx_path = test_docx('sty-known-styles') + docx_path = test_docx("sty-known-styles") document = Document(docx_path) context.document = document context.style_count = len(document.styles) -@given('a document having no styles part') +@given("a document having no styles part") def given_a_document_having_no_styles_part(context): - docx_path = test_docx('sty-having-no-styles-part') + docx_path = test_docx("sty-having-no-styles-part") context.document = Document(docx_path) -@given('a latent style collection') +@given("a latent style collection") def given_a_latent_style_collection(context): - document = Document(test_docx('sty-known-styles')) + document = Document(test_docx("sty-known-styles")) context.latent_styles = document.styles.latent_styles -@given('a latent style having a known name') +@given("a latent style having a known name") def given_a_latent_style_having_a_known_name(context): - document = Document(test_docx('sty-known-styles')) + document = Document(test_docx("sty-known-styles")) latent_styles = list(document.styles.latent_styles) context.latent_style = latent_styles[0] # should be 'Normal' -@given('a latent style having priority of {setting}') +@given("a latent style having priority of {setting}") def given_a_latent_style_having_priority_of_setting(context, setting): latent_style_name = { - '42': 'Normal', - 'no setting': 'Subtitle', + "42": "Normal", + "no setting": "Subtitle", }[setting] - document = Document(test_docx('sty-known-styles')) + document = Document(test_docx("sty-known-styles")) latent_styles = document.styles.latent_styles context.latent_style = latent_styles[latent_style_name] -@given('a latent style having {prop_name} set {setting}') +@given("a latent style having {prop_name} set {setting}") def given_a_latent_style_having_prop_setting(context, prop_name, setting): latent_style_name = { - 'on': 'Normal', - 'off': 'Title', - 'no setting': 'Subtitle', + "on": "Normal", + "off": "Title", + "no setting": "Subtitle", }[setting] - document = Document(test_docx('sty-known-styles')) + document = Document(test_docx("sty-known-styles")) latent_styles = document.styles.latent_styles context.latent_style = latent_styles[latent_style_name] -@given('a latent styles object with known defaults') +@given("a latent styles object with known defaults") def given_a_latent_styles_object_with_known_defaults(context): - document = Document(test_docx('sty-known-styles')) + document = Document(test_docx("sty-known-styles")) context.latent_styles = document.styles.latent_styles -@given('a style based on {base_style}') +@given("a style based on {base_style}") def given_a_style_based_on_setting(context, base_style): style_name = { - 'no style': 'Base', - 'Normal': 'Sub Normal', - 'Base': 'Citation', + "no style": "Base", + "Normal": "Sub Normal", + "Base": "Citation", }[base_style] - document = Document(test_docx('sty-known-styles')) + document = Document(test_docx("sty-known-styles")) context.styles = document.styles context.style = document.styles[style_name] -@given('a style having a known {attr_name}') +@given("a style having a known {attr_name}") def given_a_style_having_a_known_attr_name(context, attr_name): - docx_path = test_docx('sty-having-styles-part') + docx_path = test_docx("sty-having-styles-part") document = Document(docx_path) - context.style = document.styles['Normal'] + context.style = document.styles["Normal"] -@given('a style having hidden set {setting}') +@given("a style having hidden set {setting}") def given_a_style_having_hidden_set_setting(context, setting): - document = Document(test_docx('sty-behav-props')) + document = Document(test_docx("sty-behav-props")) style_name = { - 'on': 'Foo', - 'off': 'Bar', - 'no setting': 'Baz', + "on": "Foo", + "off": "Bar", + "no setting": "Baz", }[setting] context.style = document.styles[style_name] -@given('a style having locked set {setting}') +@given("a style having locked set {setting}") def given_a_style_having_locked_setting(context, setting): - document = Document(test_docx('sty-behav-props')) + document = Document(test_docx("sty-behav-props")) style_name = { - 'on': 'Foo', - 'off': 'Bar', - 'no setting': 'Baz', + "on": "Foo", + "off": "Bar", + "no setting": "Baz", }[setting] context.style = document.styles[style_name] -@given('a style having next paragraph style set to {setting}') +@given("a style having next paragraph style set to {setting}") def given_a_style_having_next_paragraph_style_setting(context, setting): - document = Document(test_docx('sty-known-styles')) + document = Document(test_docx("sty-known-styles")) style_name = { - 'Sub Normal': 'Citation', - 'Foobar': 'Sub Normal', - 'Base': 'Foo', - 'no setting': 'Base', + "Sub Normal": "Citation", + "Foobar": "Sub Normal", + "Base": "Foo", + "no setting": "Base", }[setting] context.styles = document.styles context.style = document.styles[style_name] -@given('a style having priority of {setting}') +@given("a style having priority of {setting}") def given_a_style_having_priority_of_setting(context, setting): - document = Document(test_docx('sty-behav-props')) + document = Document(test_docx("sty-behav-props")) style_name = { - 'no setting': 'Baz', - '42': 'Foo', + "no setting": "Baz", + "42": "Foo", }[setting] context.style = document.styles[style_name] -@given('a style having quick-style set {setting}') +@given("a style having quick-style set {setting}") def given_a_style_having_quick_style_setting(context, setting): - document = Document(test_docx('sty-behav-props')) + document = Document(test_docx("sty-behav-props")) style_name = { - 'on': 'Foo', - 'off': 'Bar', - 'no setting': 'Baz', + "on": "Foo", + "off": "Bar", + "no setting": "Baz", }[setting] context.style = document.styles[style_name] -@given('a style having unhide-when-used set {setting}') +@given("a style having unhide-when-used set {setting}") def given_a_style_having_unhide_when_used_setting(context, setting): - document = Document(test_docx('sty-behav-props')) + document = Document(test_docx("sty-behav-props")) style_name = { - 'on': 'Foo', - 'off': 'Bar', - 'no setting': 'Baz', + "on": "Foo", + "off": "Bar", + "no setting": "Baz", }[setting] context.style = document.styles[style_name] -@given('a style of type {style_type}') +@given("a style of type {style_type}") def given_a_style_of_type(context, style_type): - document = Document(test_docx('sty-known-styles')) + document = Document(test_docx("sty-known-styles")) name = { - 'WD_STYLE_TYPE.CHARACTER': 'Default Paragraph Font', - 'WD_STYLE_TYPE.LIST': 'No List', - 'WD_STYLE_TYPE.PARAGRAPH': 'Normal', - 'WD_STYLE_TYPE.TABLE': 'Normal Table', + "WD_STYLE_TYPE.CHARACTER": "Default Paragraph Font", + "WD_STYLE_TYPE.LIST": "No List", + "WD_STYLE_TYPE.PARAGRAPH": "Normal", + "WD_STYLE_TYPE.TABLE": "Normal Table", }[style_type] context.style = document.styles[name] -@given('the style collection of a document') +@given("the style collection of a document") def given_the_style_collection_of_a_document(context): - document = Document(test_docx('sty-known-styles')) + document = Document(test_docx("sty-known-styles")) context.styles = document.styles # when ===================================================== -@when('I add a latent style named \'Foobar\'') + +@when("I add a latent style named 'Foobar'") def when_I_add_a_latent_style_named_Foobar(context): latent_styles = context.document.styles.latent_styles context.latent_styles = latent_styles context.latent_style_count = len(latent_styles) - latent_styles.add_latent_style('Foobar') + latent_styles.add_latent_style("Foobar") -@when('I assign a new name to the style') +@when("I assign a new name to the style") def when_I_assign_a_new_name_to_the_style(context): - context.style.name = 'Foobar' + context.style.name = "Foobar" -@when('I assign a new value to style.style_id') +@when("I assign a new value to style.style_id") def when_I_assign_a_new_value_to_style_style_id(context): - context.style.style_id = 'Foo42' + context.style.style_id = "Foo42" -@when('I assign {value} to latent_style.{prop_name}') +@when("I assign {value} to latent_style.{prop_name}") def when_I_assign_value_to_latent_style_prop(context, value, prop_name): latent_style = context.latent_style - new_value = ( - tri_state_vals[value] if value in tri_state_vals else int(value) - ) + new_value = tri_state_vals[value] if value in tri_state_vals else int(value) setattr(latent_style, prop_name, new_value) -@when('I assign {value} to latent_styles.{prop_name}') +@when("I assign {value} to latent_styles.{prop_name}") def when_I_assign_value_to_latent_styles_prop(context, value, prop_name): latent_styles = context.latent_styles new_value = bool_vals[value] if value in bool_vals else int(value) setattr(latent_styles, prop_name, new_value) -@when('I assign {value_key} to style.base_style') +@when("I assign {value_key} to style.base_style") def when_I_assign_value_to_style_base_style(context, value_key): value = { - 'None': None, - 'styles[\'Normal\']': context.styles['Normal'], - 'styles[\'Base\']': context.styles['Base'], + "None": None, + "styles['Normal']": context.styles["Normal"], + "styles['Base']": context.styles["Base"], }[value_key] context.style.base_style = value -@when('I assign {value} to style.hidden') +@when("I assign {value} to style.hidden") def when_I_assign_value_to_style_hidden(context, value): style, new_value = context.style, tri_state_vals[value] style.hidden = new_value -@when('I assign {value} to style.locked') +@when("I assign {value} to style.locked") def when_I_assign_value_to_style_locked(context, value): style, new_value = context.style, bool_vals[value] style.locked = new_value -@when('I assign {value} to style.next_paragraph_style') +@when("I assign {value} to style.next_paragraph_style") def when_I_assign_value_to_style_next_paragraph_style(context, value): styles, style = context.styles, context.style - new_value = None if value == 'None' else styles[value] + new_value = None if value == "None" else styles[value] style.next_paragraph_style = new_value -@when('I assign {value} to style.priority') +@when("I assign {value} to style.priority") def when_I_assign_value_to_style_priority(context, value): style = context.style - new_value = None if value == 'None' else int(value) + new_value = None if value == "None" else int(value) style.priority = new_value -@when('I assign {value} to style.quick_style') +@when("I assign {value} to style.quick_style") def when_I_assign_value_to_style_quick_style(context, value): style, new_value = context.style, bool_vals[value] style.quick_style = new_value -@when('I assign {value} to style.unhide_when_used') +@when("I assign {value} to style.unhide_when_used") def when_I_assign_value_to_style_unhide_when_used(context, value): style, new_value = context.style, bool_vals[value] style.unhide_when_used = new_value -@when('I call add_style(\'{name}\', {type_str}, builtin={builtin_str})') +@when("I call add_style('{name}', {type_str}, builtin={builtin_str})") def when_I_call_add_style(context, name, type_str, builtin_str): styles = context.document.styles type = style_types[type_str] @@ -283,70 +283,71 @@ def when_I_call_add_style(context, name, type_str, builtin_str): styles.add_style(name, type, builtin=builtin) -@when('I delete a latent style') +@when("I delete a latent style") def when_I_delete_a_latent_style(context): latent_styles = context.document.styles.latent_styles context.latent_styles = latent_styles context.latent_style_count = len(latent_styles) - latent_styles['Normal'].delete() + latent_styles["Normal"].delete() -@when('I delete a style') +@when("I delete a style") def when_I_delete_a_style(context): - context.document.styles['No List'].delete() + context.document.styles["No List"].delete() # then ===================================================== -@then('I can access a latent style by name') + +@then("I can access a latent style by name") def then_I_can_access_a_latent_style_by_name(context): latent_styles = context.latent_styles - latent_style = latent_styles['Colorful Shading'] + latent_style = latent_styles["Colorful Shading"] assert isinstance(latent_style, _LatentStyle) -@then('I can access a style by its UI name') +@then("I can access a style by its UI name") def then_I_can_access_a_style_by_its_UI_name(context): styles = context.document.styles - style = styles['Default Paragraph Font'] + style = styles["Default Paragraph Font"] assert isinstance(style, BaseStyle) -@then('I can access a style by style id') +@then("I can access a style by style id") def then_I_can_access_a_style_by_style_id(context): styles = context.document.styles - style = styles['DefaultParagraphFont'] + style = styles["DefaultParagraphFont"] assert isinstance(style, BaseStyle) -@then('I can iterate over its styles') +@then("I can iterate over its styles") def then_I_can_iterate_over_its_styles(context): styles = [s for s in context.document.styles] assert len(styles) > 0 assert all(isinstance(s, BaseStyle) for s in styles) -@then('I can iterate over the latent styles') +@then("I can iterate over the latent styles") def then_I_can_iterate_over_the_latent_styles(context): latent_styles = [ls for ls in context.latent_styles] assert len(latent_styles) == 137 assert all(isinstance(ls, _LatentStyle) for ls in latent_styles) -@then('latent_style.name is the known name') +@then("latent_style.name is the known name") def then_latent_style_name_is_the_known_name(context): latent_style = context.latent_style - assert latent_style.name == 'Normal' + assert latent_style.name == "Normal" -@then('latent_style.priority is {value}') +@then("latent_style.priority is {value}") def then_latent_style_priority_is_value(context, value): latent_style = context.latent_style - expected_value = None if value == 'None' else int(value) + expected_value = None if value == "None" else int(value) assert latent_style.priority == expected_value -@then('latent_style.{prop_name} is {value}') +@then("latent_style.{prop_name} is {value}") def then_latent_style_prop_name_is_value(context, prop_name, value): latent_style = context.latent_style actual_value = getattr(latent_style, prop_name) @@ -354,14 +355,14 @@ def then_latent_style_prop_name_is_value(context, prop_name, value): assert actual_value == expected_value -@then('latent_styles[\'Foobar\'] is a latent style') +@then("latent_styles['Foobar'] is a latent style") def then_latentStyles_Foobar_is_a_latent_style(context): latent_styles = context.latent_styles - latent_style = latent_styles['Foobar'] + latent_style = latent_styles["Foobar"] assert isinstance(latent_style, _LatentStyle) -@then('latent_styles.{prop_name} is {value}') +@then("latent_styles.{prop_name} is {value}") def then_latent_styles_prop_name_is_value(context, prop_name, value): latent_styles = context.latent_styles expected_value = bool_vals[value] if value in bool_vals else int(value) @@ -369,35 +370,35 @@ def then_latent_styles_prop_name_is_value(context, prop_name, value): assert actual_value == expected_value -@then('len(latent_styles) is 137') +@then("len(latent_styles) is 137") def then_len_latent_styles_is_137(context): assert len(context.latent_styles) == 137 -@then('len(styles) is {style_count_str}') +@then("len(styles) is {style_count_str}") def then_len_styles_is_style_count(context, style_count_str): assert len(context.document.styles) == int(style_count_str) -@then('style.base_style is {value_key}') +@then("style.base_style is {value_key}") def then_style_base_style_is_value(context, value_key): expected_value = { - 'None': None, - 'styles[\'Normal\']': context.styles['Normal'], - 'styles[\'Base\']': context.styles['Base'], + "None": None, + "styles['Normal']": context.styles["Normal"], + "styles['Base']": context.styles["Base"], }[value_key] style = context.style assert style.base_style == expected_value -@then('style.builtin is {builtin_str}') +@then("style.builtin is {builtin_str}") def then_style_builtin_is_builtin(context, builtin_str): style = context.style builtin = bool_vals[builtin_str] assert style.builtin == builtin -@then('style.font is the Font object for the style') +@then("style.font is the Font object for the style") def then_style_font_is_the_Font_object_for_the_style(context): style = context.style font = style.font @@ -405,37 +406,37 @@ def then_style_font_is_the_Font_object_for_the_style(context): assert font.element is style.element -@then('style.hidden is {value}') +@then("style.hidden is {value}") def then_style_hidden_is_value(context, value): style, expected_value = context.style, tri_state_vals[value] assert style.hidden is expected_value -@then('style.locked is {value}') +@then("style.locked is {value}") def then_style_locked_is_value(context, value): style, expected_value = context.style, bool_vals[value] assert style.locked is expected_value -@then('style.name is the {which} name') +@then("style.name is the {which} name") def then_style_name_is_the_which_name(context, which): expected_name = { - 'known': 'Normal', - 'new': 'Foobar', + "known": "Normal", + "new": "Foobar", }[which] style = context.style assert style.name == expected_name -@then('style.next_paragraph_style is {value}') +@then("style.next_paragraph_style is {value}") def then_style_next_paragraph_style_is_value(context, value): style, styles = context.style, context.styles actual_value = style.next_paragraph_style expected_value = styles[value] - assert actual_value == expected_value, 'got %s' % actual_value + assert actual_value == expected_value, "got %s" % actual_value -@then('style.paragraph_format is the ParagraphFormat object for the style') +@then("style.paragraph_format is the ParagraphFormat object for the style") def then_style_paragraph_format_is_the_ParagraphFormat_object(context): style = context.style paragraph_format = style.paragraph_format @@ -443,49 +444,49 @@ def then_style_paragraph_format_is_the_ParagraphFormat_object(context): assert paragraph_format.element is style.element -@then('style.priority is {value}') +@then("style.priority is {value}") def then_style_priority_is_value(context, value): style = context.style - expected_value = None if value == 'None' else int(value) + expected_value = None if value == "None" else int(value) assert style.priority == expected_value -@then('style.quick_style is {value}') +@then("style.quick_style is {value}") def then_style_quick_style_is_value(context, value): style, expected_value = context.style, bool_vals[value] assert style.quick_style is expected_value -@then('style.style_id is the {which} style id') +@then("style.style_id is the {which} style id") def then_style_style_id_is_the_which_style_id(context, which): expected_style_id = { - 'known': 'Normal', - 'new': 'Foo42', + "known": "Normal", + "new": "Foo42", }[which] style = context.style assert style.style_id == expected_style_id -@then('style.type is the known type') +@then("style.type is the known type") def then_style_type_is_the_known_type(context): style = context.style assert style.type == WD_STYLE_TYPE.PARAGRAPH -@then('style.type is {type_str}') +@then("style.type is {type_str}") def then_style_type_is_type(context, type_str): style = context.style style_type = style_types[type_str] assert style.type == style_type -@then('style.unhide_when_used is {value}') +@then("style.unhide_when_used is {value}") def then_style_unhide_when_used_is_value(context, value): style, expected_value = context.style, bool_vals[value] assert style.unhide_when_used is expected_value -@then('styles.latent_styles is the LatentStyles object for the document') +@then("styles.latent_styles is the LatentStyles object for the document") def then_styles_latent_styles_is_the_LatentStyles_object(context): styles = context.styles context.latent_styles = latent_styles = styles.latent_styles @@ -493,34 +494,34 @@ def then_styles_latent_styles_is_the_LatentStyles_object(context): assert latent_styles.element is styles.element.latentStyles -@then('styles[\'{name}\'] is a style') +@then("styles['{name}'] is a style") def then_styles_name_is_a_style(context, name): styles = context.document.styles style = context.style = styles[name] assert isinstance(style, BaseStyle) -@then('the deleted latent style is not in the latent styles collection') +@then("the deleted latent style is not in the latent styles collection") def then_the_deleted_latent_style_is_not_in_the_collection(context): latent_styles = context.latent_styles try: - latent_styles['Normal'] + latent_styles["Normal"] except KeyError: return - raise AssertionError('Latent style not deleted') + raise AssertionError("Latent style not deleted") -@then('the deleted style is not in the styles collection') +@then("the deleted style is not in the styles collection") def then_the_deleted_style_is_not_in_the_styles_collection(context): document = context.document try: - document.styles['No List'] + document.styles["No List"] except KeyError: return - raise AssertionError('Style not deleted') + raise AssertionError("Style not deleted") -@then('the document has one additional latent style') +@then("the document has one additional latent style") def then_the_document_has_one_additional_latent_style(context): latent_styles = context.document.styles.latent_styles latent_style_count = len(latent_styles) @@ -528,7 +529,7 @@ def then_the_document_has_one_additional_latent_style(context): assert latent_style_count == expected_count -@then('the document has one additional style') +@then("the document has one additional style") def then_the_document_has_one_additional_style(context): document = context.document style_count = len(document.styles) @@ -536,14 +537,14 @@ def then_the_document_has_one_additional_style(context): assert style_count == expected_style_count -@then('the document has one fewer latent styles') +@then("the document has one fewer latent styles") def then_the_document_has_one_fewer_latent_styles(context): latent_style_count = len(context.latent_styles) expected_count = context.latent_style_count - 1 assert latent_style_count == expected_count -@then('the document has one fewer styles') +@then("the document has one fewer styles") def then_the_document_has_one_fewer_styles(context): document = context.document style_count = len(document.styles) diff --git a/features/steps/table.py b/features/steps/table.py index dc600194..83751d1f 100644 --- a/features/steps/table.py +++ b/features/steps/table.py @@ -4,17 +4,13 @@ Step implementations for table-related features """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals from behave import given, then, when from docx import Document from docx.enum.table import WD_ALIGN_VERTICAL # noqa -from docx.enum.table import ( - WD_ROW_HEIGHT_RULE, WD_TABLE_ALIGNMENT, WD_TABLE_DIRECTION -) +from docx.enum.table import WD_ROW_HEIGHT_RULE, WD_TABLE_ALIGNMENT, WD_TABLE_DIRECTION from docx.shared import Inches from docx.table import _Column, _Columns, _Row, _Rows @@ -23,269 +19,258 @@ # given =================================================== -@given('a 2 x 2 table') + +@given("a 2 x 2 table") def given_a_2x2_table(context): context.table_ = Document().add_table(rows=2, cols=2) -@given('a 3x3 table having {span_state}') +@given("a 3x3 table having {span_state}") def given_a_3x3_table_having_span_state(context, span_state): table_idx = { - 'only uniform cells': 0, - 'a horizontal span': 1, - 'a vertical span': 2, - 'a combined span': 3, + "only uniform cells": 0, + "a horizontal span": 1, + "a vertical span": 2, + "a combined span": 3, }[span_state] - document = Document(test_docx('tbl-cell-access')) + document = Document(test_docx("tbl-cell-access")) context.table_ = document.tables[table_idx] -@given('a _Cell object with {state} vertical alignment as cell') +@given("a _Cell object with {state} vertical alignment as cell") def given_a_Cell_object_with_vertical_alignment_as_cell(context, state): table_idx = { - 'inherited': 0, - 'bottom': 1, - 'center': 2, - 'top': 3, + "inherited": 0, + "bottom": 1, + "center": 2, + "top": 3, }[state] - document = Document(test_docx('tbl-props')) + document = Document(test_docx("tbl-props")) table = document.tables[table_idx] context.cell = table.cell(0, 0) -@given('a column collection having two columns') +@given("a column collection having two columns") def given_a_column_collection_having_two_columns(context): - docx_path = test_docx('blk-containing-table') + docx_path = test_docx("blk-containing-table") document = Document(docx_path) context.columns = document.tables[0].columns -@given('a row collection having two rows') +@given("a row collection having two rows") def given_a_row_collection_having_two_rows(context): - docx_path = test_docx('blk-containing-table') + docx_path = test_docx("blk-containing-table") document = Document(docx_path) context.rows = document.tables[0].rows -@given('a table') +@given("a table") def given_a_table(context): context.table_ = Document().add_table(rows=2, cols=2) -@given('a table cell having a width of {width}') +@given("a table cell having a width of {width}") def given_a_table_cell_having_a_width_of_width(context, width): - table_idx = {'no explicit setting': 0, '1 inch': 1, '2 inches': 2}[width] - document = Document(test_docx('tbl-props')) + table_idx = {"no explicit setting": 0, "1 inch": 1, "2 inches": 2}[width] + document = Document(test_docx("tbl-props")) table = document.tables[table_idx] cell = table.cell(0, 0) context.cell = cell -@given('a table column having a width of {width_desc}') +@given("a table column having a width of {width_desc}") def given_a_table_having_a_width_of_width_desc(context, width_desc): col_idx = { - 'no explicit setting': 0, - '1440': 1, + "no explicit setting": 0, + "1440": 1, }[width_desc] - docx_path = test_docx('tbl-col-props') + docx_path = test_docx("tbl-col-props") document = Document(docx_path) context.column = document.tables[0].columns[col_idx] -@given('a table having {alignment} alignment') +@given("a table having {alignment} alignment") def given_a_table_having_alignment_alignment(context, alignment): table_idx = { - 'inherited': 3, - 'left': 4, - 'right': 5, - 'center': 6, + "inherited": 3, + "left": 4, + "right": 5, + "center": 6, }[alignment] - docx_path = test_docx('tbl-props') + docx_path = test_docx("tbl-props") document = Document(docx_path) context.table_ = document.tables[table_idx] -@given('a table having an autofit layout of {autofit}') +@given("a table having an autofit layout of {autofit}") def given_a_table_having_an_autofit_layout_of_autofit(context, autofit): tbl_idx = { - 'no explicit setting': 0, - 'autofit': 1, - 'fixed': 2, + "no explicit setting": 0, + "autofit": 1, + "fixed": 2, }[autofit] - document = Document(test_docx('tbl-props')) + document = Document(test_docx("tbl-props")) context.table_ = document.tables[tbl_idx] -@given('a table having {style} style') +@given("a table having {style} style") def given_a_table_having_style(context, style): table_idx = { - 'no explicit': 0, - 'Table Grid': 1, - 'Light Shading - Accent 1': 2, + "no explicit": 0, + "Table Grid": 1, + "Light Shading - Accent 1": 2, }[style] - document = Document(test_docx('tbl-having-applied-style')) + document = Document(test_docx("tbl-having-applied-style")) context.document = document context.table_ = document.tables[table_idx] -@given('a table having table direction set {setting}') +@given("a table having table direction set {setting}") def given_a_table_having_table_direction_setting(context, setting): - table_idx = [ - 'to inherit', - 'right-to-left', - 'left-to-right' - ].index(setting) - document = Document(test_docx('tbl-on-off-props')) + table_idx = ["to inherit", "right-to-left", "left-to-right"].index(setting) + document = Document(test_docx("tbl-on-off-props")) context.table_ = document.tables[table_idx] -@given('a table having two columns') +@given("a table having two columns") def given_a_table_having_two_columns(context): - docx_path = test_docx('blk-containing-table') + docx_path = test_docx("blk-containing-table") document = Document(docx_path) # context.table is used internally by behave, underscore added # to distinguish this one context.table_ = document.tables[0] -@given('a table having two rows') +@given("a table having two rows") def given_a_table_having_two_rows(context): - docx_path = test_docx('blk-containing-table') + docx_path = test_docx("blk-containing-table") document = Document(docx_path) context.table_ = document.tables[0] -@given('a table row having height of {state}') +@given("a table row having height of {state}") def given_a_table_row_having_height_of_state(context, state): - table_idx = { - 'no explicit setting': 0, - '2 inches': 2, - '3 inches': 3 - }[state] - document = Document(test_docx('tbl-props')) + table_idx = {"no explicit setting": 0, "2 inches": 2, "3 inches": 3}[state] + document = Document(test_docx("tbl-props")) table = document.tables[table_idx] context.row = table.rows[0] -@given('a table row having height rule {state}') +@given("a table row having height rule {state}") def given_a_table_row_having_height_rule_state(context, state): - table_idx = { - 'no explicit setting': 0, - 'automatic': 1, - 'at least': 2, - 'exactly': 3 - }[state] - document = Document(test_docx('tbl-props')) + table_idx = {"no explicit setting": 0, "automatic": 1, "at least": 2, "exactly": 3}[ + state + ] + document = Document(test_docx("tbl-props")) table = document.tables[table_idx] context.row = table.rows[0] # when ===================================================== -@when('I add a 1.0 inch column to the table') + +@when("I add a 1.0 inch column to the table") def when_I_add_a_1_inch_column_to_table(context): context.column = context.table_.add_column(Inches(1.0)) -@when('I add a row to the table') +@when("I add a row to the table") def when_add_row_to_table(context): table = context.table_ context.row = table.add_row() -@when('I assign {value} to cell.vertical_alignment') +@when("I assign {value} to cell.vertical_alignment") def when_I_assign_value_to_cell_vertical_alignment(context, value): context.cell.vertical_alignment = eval(value) -@when('I assign {value} to row.height') +@when("I assign {value} to row.height") def when_I_assign_value_to_row_height(context, value): - new_value = None if value == 'None' else int(value) + new_value = None if value == "None" else int(value) context.row.height = new_value -@when('I assign {value} to row.height_rule') +@when("I assign {value} to row.height_rule") def when_I_assign_value_to_row_height_rule(context, value): - new_value = ( - None if value == 'None' else getattr(WD_ROW_HEIGHT_RULE, value) - ) + new_value = None if value == "None" else getattr(WD_ROW_HEIGHT_RULE, value) context.row.height_rule = new_value -@when('I assign {value_str} to table.alignment') +@when("I assign {value_str} to table.alignment") def when_I_assign_value_to_table_alignment(context, value_str): value = { - 'None': None, - 'WD_TABLE_ALIGNMENT.LEFT': WD_TABLE_ALIGNMENT.LEFT, - 'WD_TABLE_ALIGNMENT.RIGHT': WD_TABLE_ALIGNMENT.RIGHT, - 'WD_TABLE_ALIGNMENT.CENTER': WD_TABLE_ALIGNMENT.CENTER, + "None": None, + "WD_TABLE_ALIGNMENT.LEFT": WD_TABLE_ALIGNMENT.LEFT, + "WD_TABLE_ALIGNMENT.RIGHT": WD_TABLE_ALIGNMENT.RIGHT, + "WD_TABLE_ALIGNMENT.CENTER": WD_TABLE_ALIGNMENT.CENTER, }[value_str] table = context.table_ table.alignment = value -@when('I assign {value} to table.style') +@when("I assign {value} to table.style") def when_apply_value_to_table_style(context, value): table, styles = context.table_, context.document.styles - if value == 'None': + if value == "None": new_value = None - elif value.startswith('styles['): - new_value = styles[value.split('\'')[1]] + elif value.startswith("styles["): + new_value = styles[value.split("'")[1]] else: new_value = styles[value] table.style = new_value -@when('I assign {value} to table.table_direction') +@when("I assign {value} to table.table_direction") def when_assign_value_to_table_table_direction(context, value): - new_value = ( - None if value == 'None' else getattr(WD_TABLE_DIRECTION, value) - ) + new_value = None if value == "None" else getattr(WD_TABLE_DIRECTION, value) context.table_.table_direction = new_value -@when('I merge from cell {origin} to cell {other}') +@when("I merge from cell {origin} to cell {other}") def when_I_merge_from_cell_origin_to_cell_other(context, origin, other): def cell(table, idx): row, col = idx // 3, idx % 3 return table.cell(row, col) + a_idx, b_idx = int(origin) - 1, int(other) - 1 table = context.table_ a, b = cell(table, a_idx), cell(table, b_idx) a.merge(b) -@when('I set the cell width to {width}') +@when("I set the cell width to {width}") def when_I_set_the_cell_width_to_width(context, width): - new_value = {'1 inch': Inches(1)}[width] + new_value = {"1 inch": Inches(1)}[width] context.cell.width = new_value -@when('I set the column width to {width_emu}') +@when("I set the column width to {width_emu}") def when_I_set_the_column_width_to_width_emu(context, width_emu): - new_value = None if width_emu == 'None' else int(width_emu) + new_value = None if width_emu == "None" else int(width_emu) context.column.width = new_value -@when('I set the table autofit to {setting}') +@when("I set the table autofit to {setting}") def when_I_set_the_table_autofit_to_setting(context, setting): - new_value = {'autofit': True, 'fixed': False}[setting] + new_value = {"autofit": True, "fixed": False}[setting] table = context.table_ table.autofit = new_value # then ===================================================== -@then('cell.vertical_alignment is {value}') + +@then("cell.vertical_alignment is {value}") def then_cell_vertical_alignment_is_value(context, value): expected_value = eval(value) actual_value = context.cell.vertical_alignment assert actual_value is expected_value, ( - 'cell.vertical_alignment is %s' % actual_value + "cell.vertical_alignment is %s" % actual_value ) -@then('I can access a collection column by index') +@then("I can access a collection column by index") def then_can_access_collection_column_by_index(context): columns = context.columns for idx in range(2): @@ -293,7 +278,7 @@ def then_can_access_collection_column_by_index(context): assert isinstance(column, _Column) -@then('I can access a collection row by index') +@then("I can access a collection row by index") def then_can_access_collection_row_by_index(context): rows = context.rows for idx in range(2): @@ -301,21 +286,21 @@ def then_can_access_collection_row_by_index(context): assert isinstance(row, _Row) -@then('I can access the column collection of the table') +@then("I can access the column collection of the table") def then_can_access_column_collection_of_table(context): table = context.table_ columns = table.columns assert isinstance(columns, _Columns) -@then('I can access the row collection of the table') +@then("I can access the row collection of the table") def then_can_access_row_collection_of_table(context): table = context.table_ rows = table.rows assert isinstance(rows, _Rows) -@then('I can iterate over the column collection') +@then("I can iterate over the column collection") def then_can_iterate_over_column_collection(context): columns = context.columns actual_count = 0 @@ -325,7 +310,7 @@ def then_can_iterate_over_column_collection(context): assert actual_count == 2 -@then('I can iterate over the row collection') +@then("I can iterate over the row collection") def then_can_iterate_over_row_collection(context): rows = context.rows actual_count = 0 @@ -335,163 +320,161 @@ def then_can_iterate_over_row_collection(context): assert actual_count == 2 -@then('row.height is {value}') +@then("row.height is {value}") def then_row_height_is_value(context, value): - expected_height = None if value == 'None' else int(value) + expected_height = None if value == "None" else int(value) actual_height = context.row.height - assert actual_height == expected_height, ( - 'expected %s, got %s' % (expected_height, actual_height) + assert actual_height == expected_height, "expected %s, got %s" % ( + expected_height, + actual_height, ) -@then('row.height_rule is {value}') +@then("row.height_rule is {value}") def then_row_height_rule_is_value(context, value): - expected_rule = ( - None if value == 'None' else getattr(WD_ROW_HEIGHT_RULE, value) - ) + expected_rule = None if value == "None" else getattr(WD_ROW_HEIGHT_RULE, value) actual_rule = context.row.height_rule - assert actual_rule == expected_rule, ( - 'expected %s, got %s' % (expected_rule, actual_rule) + assert actual_rule == expected_rule, "expected %s, got %s" % ( + expected_rule, + actual_rule, ) -@then('table.alignment is {value_str}') +@then("table.alignment is {value_str}") def then_table_alignment_is_value(context, value_str): value = { - 'None': None, - 'WD_TABLE_ALIGNMENT.LEFT': WD_TABLE_ALIGNMENT.LEFT, - 'WD_TABLE_ALIGNMENT.RIGHT': WD_TABLE_ALIGNMENT.RIGHT, - 'WD_TABLE_ALIGNMENT.CENTER': WD_TABLE_ALIGNMENT.CENTER, + "None": None, + "WD_TABLE_ALIGNMENT.LEFT": WD_TABLE_ALIGNMENT.LEFT, + "WD_TABLE_ALIGNMENT.RIGHT": WD_TABLE_ALIGNMENT.RIGHT, + "WD_TABLE_ALIGNMENT.CENTER": WD_TABLE_ALIGNMENT.CENTER, }[value_str] table = context.table_ - assert table.alignment == value, 'got %s' % table.alignment + assert table.alignment == value, "got %s" % table.alignment -@then('table.cell({row}, {col}).text is {expected_text}') +@then("table.cell({row}, {col}).text is {expected_text}") def then_table_cell_row_col_text_is_text(context, row, col, expected_text): table = context.table_ row_idx, col_idx = int(row), int(col) cell_text = table.cell(row_idx, col_idx).text - assert cell_text == expected_text, 'got %s' % cell_text + assert cell_text == expected_text, "got %s" % cell_text -@then('table.style is styles[\'{style_name}\']') +@then("table.style is styles['{style_name}']") def then_table_style_is_styles_style_name(context, style_name): table, styles = context.table_, context.document.styles expected_style = styles[style_name] assert table.style == expected_style, "got '%s'" % table.style -@then('table.table_direction is {value}') +@then("table.table_direction is {value}") def then_table_table_direction_is_value(context, value): - expected_value = ( - None if value == 'None' else getattr(WD_TABLE_DIRECTION, value) - ) + expected_value = None if value == "None" else getattr(WD_TABLE_DIRECTION, value) actual_value = context.table_.table_direction assert actual_value == expected_value, "got '%s'" % actual_value -@then('the column cells text is {expected_text}') +@then("the column cells text is {expected_text}") def then_the_column_cells_text_is_expected_text(context, expected_text): table = context.table_ - cells_text = ' '.join(c.text for col in table.columns for c in col.cells) - assert cells_text == expected_text, 'got %s' % cells_text + cells_text = " ".join(c.text for col in table.columns for c in col.cells) + assert cells_text == expected_text, "got %s" % cells_text -@then('the length of the column collection is 2') +@then("the length of the column collection is 2") def then_len_of_column_collection_is_2(context): columns = context.table_.columns assert len(columns) == 2 -@then('the length of the row collection is 2') +@then("the length of the row collection is 2") def then_len_of_row_collection_is_2(context): rows = context.table_.rows assert len(rows) == 2 -@then('the new column has 2 cells') +@then("the new column has 2 cells") def then_new_column_has_2_cells(context): assert len(context.column.cells) == 2 -@then('the new column is 1.0 inches wide') +@then("the new column is 1.0 inches wide") def then_new_column_is_1_inches_wide(context): assert context.column.width == Inches(1) -@then('the new row has 2 cells') +@then("the new row has 2 cells") def then_new_row_has_2_cells(context): assert len(context.row.cells) == 2 -@then('the reported autofit setting is {autofit}') +@then("the reported autofit setting is {autofit}") def then_the_reported_autofit_setting_is_autofit(context, autofit): - expected_value = {'autofit': True, 'fixed': False}[autofit] + expected_value = {"autofit": True, "fixed": False}[autofit] table = context.table_ assert table.autofit is expected_value -@then('the reported column width is {width_emu}') +@then("the reported column width is {width_emu}") def then_the_reported_column_width_is_width_emu(context, width_emu): - expected_value = None if width_emu == 'None' else int(width_emu) - assert context.column.width == expected_value, ( - 'got %s' % context.column.width - ) + expected_value = None if width_emu == "None" else int(width_emu) + assert context.column.width == expected_value, "got %s" % context.column.width -@then('the reported width of the cell is {width}') +@then("the reported width of the cell is {width}") def then_the_reported_width_of_the_cell_is_width(context, width): - expected_width = {'None': None, '1 inch': Inches(1)}[width] + expected_width = {"None": None, "1 inch": Inches(1)}[width] actual_width = context.cell.width - assert actual_width == expected_width, ( - 'expected %s, got %s' % (expected_width, actual_width) + assert actual_width == expected_width, "expected %s, got %s" % ( + expected_width, + actual_width, ) -@then('the row cells text is {encoded_text}') +@then("the row cells text is {encoded_text}") def then_the_row_cells_text_is_expected_text(context, encoded_text): - expected_text = encoded_text.replace('\\', '\n') + expected_text = encoded_text.replace("\\", "\n") table = context.table_ - cells_text = ' '.join(c.text for row in table.rows for c in row.cells) - assert cells_text == expected_text, 'got %s' % cells_text + cells_text = " ".join(c.text for row in table.rows for c in row.cells) + assert cells_text == expected_text, "got %s" % cells_text -@then('the table has {count} columns') +@then("the table has {count} columns") def then_table_has_count_columns(context, count): column_count = int(count) columns = context.table_.columns assert len(columns) == column_count -@then('the table has {count} rows') +@then("the table has {count} rows") def then_table_has_count_rows(context, count): row_count = int(count) rows = context.table_.rows assert len(rows) == row_count -@then('the width of cell {n_str} is {inches_str} inches') +@then("the width of cell {n_str} is {inches_str} inches") def then_the_width_of_cell_n_is_x_inches(context, n_str, inches_str): def _cell(table, idx): row, col = idx // 3, idx % 3 return table.cell(row, col) + idx, inches = int(n_str) - 1, float(inches_str) cell = _cell(context.table_, idx) - assert cell.width == Inches(inches), 'got %s' % cell.width.inches + assert cell.width == Inches(inches), "got %s" % cell.width.inches -@then('the width of each cell is {inches} inches') +@then("the width of each cell is {inches} inches") def then_the_width_of_each_cell_is_inches(context, inches): table = context.table_ expected_width = Inches(float(inches)) for cell in table._cells: - assert cell.width == expected_width, 'got %s' % cell.width.inches + assert cell.width == expected_width, "got %s" % cell.width.inches -@then('the width of each column is {inches} inches') +@then("the width of each column is {inches} inches") def then_the_width_of_each_column_is_inches(context, inches): table = context.table_ expected_width = Inches(float(inches)) for column in table.columns: - assert column.width == expected_width, 'got %s' % column.width.inches + assert column.width == expected_width, "got %s" % column.width.inches diff --git a/features/steps/tabstops.py b/features/steps/tabstops.py index 4a6b442e..b360d480 100644 --- a/features/steps/tabstops.py +++ b/features/steps/tabstops.py @@ -16,71 +16,73 @@ # given =================================================== -@given('a tab_stops having {count} tab stops') + +@given("a tab_stops having {count} tab stops") def given_a_tab_stops_having_count_tab_stops(context, count): - paragraph_idx = {'0': 0, '3': 1}[count] - document = Document(test_docx('tab-stops')) + paragraph_idx = {"0": 0, "3": 1}[count] + document = Document(test_docx("tab-stops")) paragraph_format = document.paragraphs[paragraph_idx].paragraph_format context.tab_stops = paragraph_format.tab_stops -@given('a tab stop 0.5 inches {in_or_out} from the paragraph left edge') +@given("a tab stop 0.5 inches {in_or_out} from the paragraph left edge") def given_a_tab_stop_inches_from_paragraph_left_edge(context, in_or_out): - tab_idx = {'out': 0, 'in': 1}[in_or_out] - document = Document(test_docx('tab-stops')) + tab_idx = {"out": 0, "in": 1}[in_or_out] + document = Document(test_docx("tab-stops")) paragraph_format = document.paragraphs[2].paragraph_format context.tab_stops = paragraph_format.tab_stops context.tab_stop = paragraph_format.tab_stops[tab_idx] -@given('a tab stop having {alignment} alignment') +@given("a tab stop having {alignment} alignment") def given_a_tab_stop_having_alignment_alignment(context, alignment): - tab_idx = {'LEFT': 0, 'CENTER': 1, 'RIGHT': 2}[alignment] - document = Document(test_docx('tab-stops')) + tab_idx = {"LEFT": 0, "CENTER": 1, "RIGHT": 2}[alignment] + document = Document(test_docx("tab-stops")) paragraph_format = document.paragraphs[1].paragraph_format context.tab_stop = paragraph_format.tab_stops[tab_idx] -@given('a tab stop having {leader} leader') +@given("a tab stop having {leader} leader") def given_a_tab_stop_having_leader_leader(context, leader): - tab_idx = {'no specified': 0, 'a dotted': 2}[leader] - document = Document(test_docx('tab-stops')) + tab_idx = {"no specified": 0, "a dotted": 2}[leader] + document = Document(test_docx("tab-stops")) paragraph_format = document.paragraphs[1].paragraph_format context.tab_stop = paragraph_format.tab_stops[tab_idx] # when ==================================================== -@when('I add a tab stop') + +@when("I add a tab stop") def when_I_add_a_tab_stop(context): tab_stops = context.tab_stops tab_stops.add_tab_stop(Inches(1.75)) -@when('I assign {member} to tab_stop.alignment') +@when("I assign {member} to tab_stop.alignment") def when_I_assign_member_to_tab_stop_alignment(context, member): value = getattr(WD_TAB_ALIGNMENT, member) context.tab_stop.alignment = value -@when('I assign {member} to tab_stop.leader') +@when("I assign {member} to tab_stop.leader") def when_I_assign_member_to_tab_stop_leader(context, member): value = getattr(WD_TAB_LEADER, member) context.tab_stop.leader = value -@when('I assign {value} to tab_stop.position') +@when("I assign {value} to tab_stop.position") def when_I_assign_value_to_tab_stop_value(context, value): context.tab_stop.position = int(value) -@when('I call tab_stops.clear_all()') +@when("I call tab_stops.clear_all()") def when_I_call_tab_stops_clear_all(context): tab_stops = context.tab_stops tab_stops.clear_all() -@when('I remove a tab stop') +@when("I remove a tab stop") def when_I_remove_a_tab_stop(context): tab_stops = context.tab_stops del tab_stops[1] @@ -88,7 +90,8 @@ def when_I_remove_a_tab_stop(context): # then ===================================================== -@then('I can access a tab stop by index') + +@then("I can access a tab stop by index") def then_I_can_access_a_tab_stop_by_index(context): tab_stops = context.tab_stops for idx in range(3): @@ -96,48 +99,48 @@ def then_I_can_access_a_tab_stop_by_index(context): assert isinstance(tab_stop, TabStop) -@then('I can iterate the TabStops object') +@then("I can iterate the TabStops object") def then_I_can_iterate_the_TabStops_object(context): items = [ts for ts in context.tab_stops] assert len(items) == 3 assert all(isinstance(item, TabStop) for item in items) -@then('len(tab_stops) is {count}') +@then("len(tab_stops) is {count}") def then_len_tab_stops_is_count(context, count): tab_stops = context.tab_stops assert len(tab_stops) == int(count) -@then('tab_stop.alignment is {alignment}') +@then("tab_stop.alignment is {alignment}") def then_tab_stop_alignment_is_alignment(context, alignment): expected_value = getattr(WD_TAB_ALIGNMENT, alignment) tab_stop = context.tab_stop assert tab_stop.alignment == expected_value -@then('tab_stop.leader is {leader}') +@then("tab_stop.leader is {leader}") def then_tab_stop_leader_is_leader(context, leader): expected_value = getattr(WD_TAB_LEADER, leader) tab_stop = context.tab_stop assert tab_stop.leader == expected_value -@then('tab_stop.position is {position}') +@then("tab_stop.position is {position}") def then_tab_stop_position_is_position(context, position): tab_stop = context.tab_stop assert tab_stop.position == int(position) -@then('the removed tab stop is no longer present in tab_stops') +@then("the removed tab stop is no longer present in tab_stops") def then_the_removed_tab_stop_is_no_longer_present_in_tab_stops(context): tab_stops = context.tab_stops assert tab_stops[0].position == Inches(1) assert tab_stops[1].position == Inches(3) -@then('the tab stops are sequenced in position order') +@then("the tab stops are sequenced in position order") def then_the_tab_stops_are_sequenced_in_position_order(context): tab_stops = context.tab_stops for idx in range(len(tab_stops) - 1): - assert tab_stops[idx].position < tab_stops[idx+1].position + assert tab_stops[idx].position < tab_stops[idx + 1].position diff --git a/features/steps/text.py b/features/steps/text.py index cc56c930..57451a1b 100644 --- a/features/steps/text.py +++ b/features/steps/text.py @@ -22,7 +22,8 @@ # given =================================================== -@given('a run') + +@given("a run") def given_a_run(context): document = Document() run = document.add_paragraph().add_run() @@ -30,22 +31,22 @@ def given_a_run(context): context.run = run -@given('a run having {bool_prop_name} set on') +@given("a run having {bool_prop_name} set on") def given_a_run_having_bool_prop_set_on(context, bool_prop_name): run = Document().add_paragraph().add_run() setattr(run, bool_prop_name, True) context.run = run -@given('a run having known text and formatting') +@given("a run having known text and formatting") def given_a_run_having_known_text_and_formatting(context): - run = Document().add_paragraph().add_run('foobar') + run = Document().add_paragraph().add_run("foobar") run.bold = True run.italic = True context.run = run -@given('a run having mixed text content') +@given("a run having mixed text content") def given_a_run_having_mixed_text_content(context): """ Mixed here meaning it contains ````, ````, etc. elements. @@ -60,40 +61,40 @@ def given_a_run_having_mixed_text_content(context): jkl - """ % nsdecls('w') + """ % nsdecls( + "w" + ) r = parse_xml(r_xml) context.run = Run(r, None) -@given('a run having {underline_type} underline') +@given("a run having {underline_type} underline") def given_a_run_having_underline_type(context, underline_type): - run_idx = { - 'inherited': 0, 'no': 1, 'single': 2, 'double': 3 - }[underline_type] - document = Document(test_docx('run-enumerated-props')) + run_idx = {"inherited": 0, "no": 1, "single": 2, "double": 3}[underline_type] + document = Document(test_docx("run-enumerated-props")) context.run = document.paragraphs[0].runs[run_idx] -@given('a run having {style} style') +@given("a run having {style} style") def given_a_run_having_style(context, style): run_idx = { - 'no explicit': 0, - 'Emphasis': 1, - 'Strong': 2, + "no explicit": 0, + "Emphasis": 1, + "Strong": 2, }[style] - context.document = document = Document(test_docx('run-char-style')) + context.document = document = Document(test_docx("run-char-style")) context.run = document.paragraphs[0].runs[run_idx] -@given('a run inside a table cell retrieved from {cell_source}') +@given("a run inside a table cell retrieved from {cell_source}") def given_a_run_inside_a_table_cell_from_source(context, cell_source): document = Document() table = document.add_table(rows=2, cols=2) - if cell_source == 'Table.cell': + if cell_source == "Table.cell": cell = table.cell(0, 0) - elif cell_source == 'Table.row.cells': + elif cell_source == "Table.row.cells": cell = table.rows[0].cells[1] - elif cell_source == 'Table.column.cells': + elif cell_source == "Table.column.cells": cell = table.columns[1].cells[0] run = cell.paragraphs[0].add_run() context.document = document @@ -102,202 +103,203 @@ def given_a_run_inside_a_table_cell_from_source(context, cell_source): # when ==================================================== -@when('I add a column break') + +@when("I add a column break") def when_add_column_break(context): run = context.run run.add_break(WD_BREAK.COLUMN) -@when('I add a line break') +@when("I add a line break") def when_add_line_break(context): run = context.run run.add_break() -@when('I add a page break') +@when("I add a page break") def when_add_page_break(context): run = context.run run.add_break(WD_BREAK.PAGE) -@when('I add a picture to the run') +@when("I add a picture to the run") def when_I_add_a_picture_to_the_run(context): run = context.run - run.add_picture(test_file('monty-truth.png')) + run.add_picture(test_file("monty-truth.png")) -@when('I add a run specifying its text') +@when("I add a run specifying its text") def when_I_add_a_run_specifying_its_text(context): context.run = context.paragraph.add_run(test_text) -@when('I add a run specifying the character style Emphasis') +@when("I add a run specifying the character style Emphasis") def when_I_add_a_run_specifying_the_character_style_Emphasis(context): - context.run = context.paragraph.add_run(test_text, 'Emphasis') + context.run = context.paragraph.add_run(test_text, "Emphasis") -@when('I add a tab') +@when("I add a tab") def when_I_add_a_tab(context): context.run.add_tab() -@when('I add text to the run') +@when("I add text to the run") def when_I_add_text_to_the_run(context): context.run.add_text(test_text) -@when('I assign mixed text to the text property') +@when("I assign mixed text to the text property") def when_I_assign_mixed_text_to_the_text_property(context): - context.run.text = 'abc\tdef\nghi\rjkl' + context.run.text = "abc\tdef\nghi\rjkl" -@when('I assign {value_str} to its {bool_prop_name} property') +@when("I assign {value_str} to its {bool_prop_name} property") def when_assign_true_to_bool_run_prop(context, value_str, bool_prop_name): - value = {'True': True, 'False': False, 'None': None}[value_str] + value = {"True": True, "False": False, "None": None}[value_str] run = context.run setattr(run, bool_prop_name, value) -@when('I assign {value} to run.style') +@when("I assign {value} to run.style") def when_I_assign_value_to_run_style(context, value): - if value == 'None': + if value == "None": new_value = None - elif value.startswith('styles['): - new_value = context.document.styles[value.split('\'')[1]] + elif value.startswith("styles["): + new_value = context.document.styles[value.split("'")[1]] else: new_value = context.document.styles[value] context.run.style = new_value -@when('I clear the run') +@when("I clear the run") def when_I_clear_the_run(context): context.run.clear() -@when('I set the run underline to {underline_value}') +@when("I set the run underline to {underline_value}") def when_I_set_the_run_underline_to_value(context, underline_value): new_value = { - 'True': True, 'False': False, 'None': None, - 'WD_UNDERLINE.SINGLE': WD_UNDERLINE.SINGLE, - 'WD_UNDERLINE.DOUBLE': WD_UNDERLINE.DOUBLE, + "True": True, + "False": False, + "None": None, + "WD_UNDERLINE.SINGLE": WD_UNDERLINE.SINGLE, + "WD_UNDERLINE.DOUBLE": WD_UNDERLINE.DOUBLE, }[underline_value] context.run.underline = new_value # then ===================================================== -@then('it is a column break') + +@then("it is a column break") def then_type_is_column_break(context): attrib = context.last_child.attrib - assert attrib == {qn('w:type'): 'column'} + assert attrib == {qn("w:type"): "column"} -@then('it is a line break') +@then("it is a line break") def then_type_is_line_break(context): attrib = context.last_child.attrib assert attrib == {} -@then('it is a page break') +@then("it is a page break") def then_type_is_page_break(context): attrib = context.last_child.attrib - assert attrib == {qn('w:type'): 'page'} + assert attrib == {qn("w:type"): "page"} -@then('run.font is the Font object for the run') +@then("run.font is the Font object for the run") def then_run_font_is_the_Font_object_for_the_run(context): run, font = context.run, context.run.font assert isinstance(font, Font) assert font.element is run.element -@then('run.style is styles[\'{style_name}\']') +@then("run.style is styles['{style_name}']") def then_run_style_is_style(context, style_name): expected_value = context.document.styles[style_name] run = context.run - assert run.style == expected_value, 'got %s' % run.style + assert run.style == expected_value, "got %s" % run.style -@then('the last item in the run is a break') +@then("the last item in the run is a break") def then_last_item_in_run_is_a_break(context): run = context.run context.last_child = run._r[-1] - expected_tag = ( - '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}br' - ) + expected_tag = "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}br" assert context.last_child.tag == expected_tag -@then('the picture appears at the end of the run') +@then("the picture appears at the end of the run") def then_the_picture_appears_at_the_end_of_the_run(context): run = context.run r = run._r blip_rId = r.xpath( - './w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill/' - 'a:blip/@r:embed' + "./w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill/" + "a:blip/@r:embed" )[0] image_part = run.part.related_parts[blip_rId] image_sha1 = hashlib.sha1(image_part.blob).hexdigest() - expected_sha1 = '79769f1e202add2e963158b532e36c2c0f76a70c' - assert image_sha1 == expected_sha1, ( - "image SHA1 doesn't match, expected %s, got %s" % - (expected_sha1, image_sha1) - ) + expected_sha1 = "79769f1e202add2e963158b532e36c2c0f76a70c" + assert ( + image_sha1 == expected_sha1 + ), "image SHA1 doesn't match, expected %s, got %s" % (expected_sha1, image_sha1) -@then('the run appears in {boolean_prop_name} unconditionally') +@then("the run appears in {boolean_prop_name} unconditionally") def then_run_appears_in_boolean_prop_name(context, boolean_prop_name): run = context.run assert getattr(run, boolean_prop_name) is True -@then('the run appears with its inherited {boolean_prop_name} setting') +@then("the run appears with its inherited {boolean_prop_name} setting") def then_run_inherits_bool_prop_value(context, boolean_prop_name): run = context.run assert getattr(run, boolean_prop_name) is None -@then('the run appears without {boolean_prop_name} unconditionally') +@then("the run appears without {boolean_prop_name} unconditionally") def then_run_appears_without_bool_prop(context, boolean_prop_name): run = context.run assert getattr(run, boolean_prop_name) is False -@then('the run contains no text') +@then("the run contains no text") def then_the_run_contains_no_text(context): - assert context.run.text == '' + assert context.run.text == "" -@then('the run contains the text I specified') +@then("the run contains the text I specified") def then_the_run_contains_the_text_I_specified(context): assert context.run.text == test_text -@then('the run formatting is preserved') +@then("the run formatting is preserved") def then_the_run_formatting_is_preserved(context): assert context.run.bold is True assert context.run.italic is True -@then('the run underline property value is {underline_value}') +@then("the run underline property value is {underline_value}") def then_the_run_underline_property_value_is(context, underline_value): expected_value = { - 'None': None, 'False': False, 'True': True, - 'WD_UNDERLINE.DOUBLE': WD_UNDERLINE.DOUBLE + "None": None, + "False": False, + "True": True, + "WD_UNDERLINE.DOUBLE": WD_UNDERLINE.DOUBLE, }[underline_value] assert context.run.underline == expected_value -@then('the tab appears at the end of the run') +@then("the tab appears at the end of the run") def then_the_tab_appears_at_the_end_of_the_run(context): r = context.run._r - tab = r.find(qn('w:tab')) + tab = r.find(qn("w:tab")) assert tab is not None -@then('the text of the run represents the textual run content') +@then("the text of the run represents the textual run content") def then_the_text_of_the_run_represents_the_textual_run_content(context): - assert context.run.text == 'abc\tdef\nghi\njkl', ( - 'got \'%s\'' % context.run.text - ) + assert context.run.text == "abc\tdef\nghi\njkl", "got '%s'" % context.run.text diff --git a/tests/dml/test_color.py b/tests/dml/test_color.py index 32091dab..421f7292 100644 --- a/tests/dml/test_color.py +++ b/tests/dml/test_color.py @@ -4,9 +4,7 @@ Test suite for docx.dml.color module. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals from docx.enum.dml import MSO_COLOR_TYPE, MSO_THEME_COLOR from docx.dml.color import ColorFormat @@ -18,7 +16,6 @@ class DescribeColorFormat(object): - def it_knows_its_color_type(self, type_fixture): color_format, expected_value = type_fixture assert color_format.type == expected_value @@ -43,86 +40,109 @@ def it_can_change_its_theme_color(self, theme_color_set_fixture): # fixtures --------------------------------------------- - @pytest.fixture(params=[ - ('w:r', None), - ('w:r/w:rPr', None), - ('w:r/w:rPr/w:color{w:val=auto}', None), - ('w:r/w:rPr/w:color{w:val=4224FF}', '4224ff'), - ('w:r/w:rPr/w:color{w:val=auto,w:themeColor=accent1}', None), - ('w:r/w:rPr/w:color{w:val=F00BA9,w:themeColor=accent1}', 'f00ba9'), - ]) + @pytest.fixture( + params=[ + ("w:r", None), + ("w:r/w:rPr", None), + ("w:r/w:rPr/w:color{w:val=auto}", None), + ("w:r/w:rPr/w:color{w:val=4224FF}", "4224ff"), + ("w:r/w:rPr/w:color{w:val=auto,w:themeColor=accent1}", None), + ("w:r/w:rPr/w:color{w:val=F00BA9,w:themeColor=accent1}", "f00ba9"), + ] + ) def rgb_get_fixture(self, request): r_cxml, rgb = request.param color_format = ColorFormat(element(r_cxml)) expected_value = None if rgb is None else RGBColor.from_string(rgb) return color_format, expected_value - @pytest.fixture(params=[ - ('w:r', RGBColor(10, 20, 30), 'w:r/w:rPr/w:color{w:val=0A141E}'), - ('w:r/w:rPr', RGBColor(1, 2, 3), 'w:r/w:rPr/w:color{w:val=010203}'), - ('w:r/w:rPr/w:color{w:val=123abc}', RGBColor(42, 24, 99), - 'w:r/w:rPr/w:color{w:val=2A1863}'), - ('w:r/w:rPr/w:color{w:val=auto}', RGBColor(16, 17, 18), - 'w:r/w:rPr/w:color{w:val=101112}'), - ('w:r/w:rPr/w:color{w:val=234bcd,w:themeColor=dark1}', - RGBColor(24, 42, 99), 'w:r/w:rPr/w:color{w:val=182A63}'), - ('w:r/w:rPr/w:color{w:val=234bcd,w:themeColor=dark1}', - None, 'w:r/w:rPr'), - ('w:r', None, 'w:r'), - ]) + @pytest.fixture( + params=[ + ("w:r", RGBColor(10, 20, 30), "w:r/w:rPr/w:color{w:val=0A141E}"), + ("w:r/w:rPr", RGBColor(1, 2, 3), "w:r/w:rPr/w:color{w:val=010203}"), + ( + "w:r/w:rPr/w:color{w:val=123abc}", + RGBColor(42, 24, 99), + "w:r/w:rPr/w:color{w:val=2A1863}", + ), + ( + "w:r/w:rPr/w:color{w:val=auto}", + RGBColor(16, 17, 18), + "w:r/w:rPr/w:color{w:val=101112}", + ), + ( + "w:r/w:rPr/w:color{w:val=234bcd,w:themeColor=dark1}", + RGBColor(24, 42, 99), + "w:r/w:rPr/w:color{w:val=182A63}", + ), + ("w:r/w:rPr/w:color{w:val=234bcd,w:themeColor=dark1}", None, "w:r/w:rPr"), + ("w:r", None, "w:r"), + ] + ) def rgb_set_fixture(self, request): r_cxml, new_value, expected_cxml = request.param color_format = ColorFormat(element(r_cxml)) expected_xml = xml(expected_cxml) return color_format, new_value, expected_xml - @pytest.fixture(params=[ - ('w:r', None), - ('w:r/w:rPr', None), - ('w:r/w:rPr/w:color{w:val=auto}', None), - ('w:r/w:rPr/w:color{w:val=4224FF}', None), - ('w:r/w:rPr/w:color{w:themeColor=accent1}', 'ACCENT_1'), - ('w:r/w:rPr/w:color{w:val=F00BA9,w:themeColor=dark1}', 'DARK_1'), - ]) + @pytest.fixture( + params=[ + ("w:r", None), + ("w:r/w:rPr", None), + ("w:r/w:rPr/w:color{w:val=auto}", None), + ("w:r/w:rPr/w:color{w:val=4224FF}", None), + ("w:r/w:rPr/w:color{w:themeColor=accent1}", "ACCENT_1"), + ("w:r/w:rPr/w:color{w:val=F00BA9,w:themeColor=dark1}", "DARK_1"), + ] + ) def theme_color_get_fixture(self, request): r_cxml, value = request.param color_format = ColorFormat(element(r_cxml)) - expected_value = ( - None if value is None else getattr(MSO_THEME_COLOR, value) - ) + expected_value = None if value is None else getattr(MSO_THEME_COLOR, value) return color_format, expected_value - @pytest.fixture(params=[ - ('w:r', 'ACCENT_1', - 'w:r/w:rPr/w:color{w:val=000000,w:themeColor=accent1}'), - ('w:r/w:rPr', 'ACCENT_2', - 'w:r/w:rPr/w:color{w:val=000000,w:themeColor=accent2}'), - ('w:r/w:rPr/w:color{w:val=101112}', 'ACCENT_3', - 'w:r/w:rPr/w:color{w:val=101112,w:themeColor=accent3}'), - ('w:r/w:rPr/w:color{w:val=234bcd,w:themeColor=dark1}', 'LIGHT_2', - 'w:r/w:rPr/w:color{w:val=234bcd,w:themeColor=light2}'), - ('w:r/w:rPr/w:color{w:val=234bcd,w:themeColor=dark1}', None, - 'w:r/w:rPr'), - ('w:r', None, 'w:r'), - ]) + @pytest.fixture( + params=[ + ("w:r", "ACCENT_1", "w:r/w:rPr/w:color{w:val=000000,w:themeColor=accent1}"), + ( + "w:r/w:rPr", + "ACCENT_2", + "w:r/w:rPr/w:color{w:val=000000,w:themeColor=accent2}", + ), + ( + "w:r/w:rPr/w:color{w:val=101112}", + "ACCENT_3", + "w:r/w:rPr/w:color{w:val=101112,w:themeColor=accent3}", + ), + ( + "w:r/w:rPr/w:color{w:val=234bcd,w:themeColor=dark1}", + "LIGHT_2", + "w:r/w:rPr/w:color{w:val=234bcd,w:themeColor=light2}", + ), + ("w:r/w:rPr/w:color{w:val=234bcd,w:themeColor=dark1}", None, "w:r/w:rPr"), + ("w:r", None, "w:r"), + ] + ) def theme_color_set_fixture(self, request): r_cxml, member, expected_cxml = request.param color_format = ColorFormat(element(r_cxml)) - new_value = ( - None if member is None else getattr(MSO_THEME_COLOR, member) - ) + new_value = None if member is None else getattr(MSO_THEME_COLOR, member) expected_xml = xml(expected_cxml) return color_format, new_value, expected_xml - @pytest.fixture(params=[ - ('w:r', None), - ('w:r/w:rPr', None), - ('w:r/w:rPr/w:color{w:val=auto}', MSO_COLOR_TYPE.AUTO), - ('w:r/w:rPr/w:color{w:val=4224FF}', MSO_COLOR_TYPE.RGB), - ('w:r/w:rPr/w:color{w:themeColor=dark1}', MSO_COLOR_TYPE.THEME), - ('w:r/w:rPr/w:color{w:val=F00BA9,w:themeColor=accent1}', - MSO_COLOR_TYPE.THEME), - ]) + @pytest.fixture( + params=[ + ("w:r", None), + ("w:r/w:rPr", None), + ("w:r/w:rPr/w:color{w:val=auto}", MSO_COLOR_TYPE.AUTO), + ("w:r/w:rPr/w:color{w:val=4224FF}", MSO_COLOR_TYPE.RGB), + ("w:r/w:rPr/w:color{w:themeColor=dark1}", MSO_COLOR_TYPE.THEME), + ( + "w:r/w:rPr/w:color{w:val=F00BA9,w:themeColor=accent1}", + MSO_COLOR_TYPE.THEME, + ), + ] + ) def type_fixture(self, request): r_cxml, expected_value = request.param color_format = ColorFormat(element(r_cxml)) diff --git a/tests/image/test_bmp.py b/tests/image/test_bmp.py index 37961369..9eb37164 100644 --- a/tests/image/test_bmp.py +++ b/tests/image/test_bmp.py @@ -16,12 +16,11 @@ class DescribeBmp(object): - def it_can_construct_from_a_bmp_stream(self, Bmp__init__): cx, cy, horz_dpi, vert_dpi = 26, 43, 200, 96 bytes_ = ( - b'fillerfillerfiller\x1A\x00\x00\x00\x2B\x00\x00\x00' - b'fillerfiller\xB8\x1E\x00\x00\x00\x00\x00\x00' + b"fillerfillerfiller\x1A\x00\x00\x00\x2B\x00\x00\x00" + b"fillerfiller\xB8\x1E\x00\x00\x00\x00\x00\x00" ) stream = BytesIO(bytes_) @@ -36,7 +35,7 @@ def it_knows_its_content_type(self): def it_knows_its_default_ext(self): bmp = Bmp(None, None, None, None) - assert bmp.default_ext == 'bmp' + assert bmp.default_ext == "bmp" # fixtures ------------------------------------------------------- diff --git a/tests/image/test_gif.py b/tests/image/test_gif.py index 707419f5..fc00af69 100644 --- a/tests/image/test_gif.py +++ b/tests/image/test_gif.py @@ -14,10 +14,9 @@ class DescribeGif(object): - def it_can_construct_from_a_gif_stream(self, Gif__init__): cx, cy = 42, 24 - bytes_ = b'filler\x2A\x00\x18\x00' + bytes_ = b"filler\x2A\x00\x18\x00" stream = BytesIO(bytes_) gif = Gif.from_stream(stream) @@ -31,7 +30,7 @@ def it_knows_its_content_type(self): def it_knows_its_default_ext(self): gif = Gif(None, None, None, None) - assert gif.default_ext == 'gif' + assert gif.default_ext == "gif" # fixture components --------------------------------------------- diff --git a/tests/image/test_helpers.py b/tests/image/test_helpers.py index 6091f488..8716257d 100644 --- a/tests/image/test_helpers.py +++ b/tests/image/test_helpers.py @@ -14,12 +14,10 @@ class DescribeStreamReader(object): - - def it_can_read_a_string_of_specified_len_at_offset( - self, read_str_fixture): + def it_can_read_a_string_of_specified_len_at_offset(self, read_str_fixture): stream_rdr, expected_string = read_str_fixture s = stream_rdr.read_str(6, 2) - assert s == 'foobar' + assert s == "foobar" def it_raises_on_unexpected_EOF(self, read_str_fixture): stream_rdr = read_str_fixture[0] @@ -33,10 +31,12 @@ def it_can_read_a_long(self, read_long_fixture): # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - (BIG_ENDIAN, b'\xBE\x00\x00\x00\x2A\xEF', 1, 42), - (LITTLE_ENDIAN, b'\xBE\xEF\x2A\x00\x00\x00', 2, 42), - ]) + @pytest.fixture( + params=[ + (BIG_ENDIAN, b"\xBE\x00\x00\x00\x2A\xEF", 1, 42), + (LITTLE_ENDIAN, b"\xBE\xEF\x2A\x00\x00\x00", 2, 42), + ] + ) def read_long_fixture(self, request): byte_order, bytes_, offset, expected_int = request.param stream = BytesIO(bytes_) @@ -45,7 +45,7 @@ def read_long_fixture(self, request): @pytest.fixture def read_str_fixture(self): - stream = BytesIO(b'\x01\x02foobar\x03\x04') + stream = BytesIO(b"\x01\x02foobar\x03\x04") stream_rdr = StreamReader(stream, BIG_ENDIAN) - expected_string = 'foobar' + expected_string = "foobar" return stream_rdr, expected_string diff --git a/tests/image/test_image.py b/tests/image/test_image.py index d1ea618b..0bb8707f 100644 --- a/tests/image/test_image.py +++ b/tests/image/test_image.py @@ -30,7 +30,6 @@ class DescribeImage(object): - def it_can_construct_from_an_image_blob( self, blob_, BytesIO_, _from_stream_, stream_, image_ ): @@ -41,9 +40,7 @@ def it_can_construct_from_an_image_blob( assert image is image_ def it_can_construct_from_an_image_path(self, from_path_fixture): - image_path, _from_stream_, stream_, blob, filename, image_ = ( - from_path_fixture - ) + image_path, _from_stream_, stream_, blob, filename, image_ = from_path_fixture image = Image.from_file(image_path) _from_stream_.assert_called_once_with(stream_, blob, filename) assert image is image_ @@ -66,7 +63,7 @@ def it_can_construct_from_an_image_stream(self, from_stream_fixture): assert isinstance(image, Image) def it_provides_access_to_the_image_blob(self): - blob = b'foobar' + blob = b"foobar" image = Image(blob, None, None) assert image.blob == blob @@ -103,25 +100,23 @@ def it_can_scale_its_dimensions(self, scale_fixture): assert isinstance(scaled_height, Length) def it_knows_the_image_filename(self): - filename = 'foobar.png' + filename = "foobar.png" image = Image(None, filename, None) assert image.filename == filename def it_knows_the_image_filename_extension(self): - image = Image(None, 'foobar.png', None) - assert image.ext == 'png' + image = Image(None, "foobar.png", None) + assert image.ext == "png" def it_knows_the_sha1_of_its_image(self): - blob = b'fO0Bar' + blob = b"fO0Bar" image = Image(blob, None, None) - assert image.sha1 == '4921e7002ddfba690a937d54bda226a7b8bdeb68' + assert image.sha1 == "4921e7002ddfba690a937d54bda226a7b8bdeb68" def it_correctly_characterizes_known_images(self, known_image_fixture): image_path, characteristics = known_image_fixture - ext, content_type, px_width, px_height, horz_dpi, vert_dpi = ( - characteristics - ) - with open(testfile(image_path), 'rb') as stream: + ext, content_type, px_width, px_height, horz_dpi, vert_dpi = characteristics + with open(testfile(image_path), "rb") as stream: image = Image.from_file(stream) assert image.content_type == content_type assert image.ext == ext @@ -134,7 +129,7 @@ def it_correctly_characterizes_known_images(self, known_image_fixture): @pytest.fixture def content_type_fixture(self, image_header_): - content_type = 'image/foobar' + content_type = "image/foobar" image_header_.content_type = content_type return image_header_, content_type @@ -154,54 +149,61 @@ def dpi_fixture(self, image_header_): @pytest.fixture def from_filelike_fixture(self, _from_stream_, image_): - image_path = testfile('python-icon.png') - with open(image_path, 'rb') as f: + image_path = testfile("python-icon.png") + with open(image_path, "rb") as f: blob = f.read() image_stream = BytesIO(blob) return image_stream, _from_stream_, blob, image_ @pytest.fixture def from_path_fixture(self, _from_stream_, BytesIO_, stream_, image_): - filename = 'python-icon.png' + filename = "python-icon.png" image_path = testfile(filename) - with open(image_path, 'rb') as f: + with open(image_path, "rb") as f: blob = f.read() return image_path, _from_stream_, stream_, blob, filename, image_ - @pytest.fixture(params=['foobar.png', None]) + @pytest.fixture(params=["foobar.png", None]) def from_stream_fixture( - self, request, stream_, blob_, _ImageHeaderFactory_, - image_header_, Image__init_): + self, request, stream_, blob_, _ImageHeaderFactory_, image_header_, Image__init_ + ): filename_in = request.param - filename_out = 'image.png' if filename_in is None else filename_in + filename_out = "image.png" if filename_in is None else filename_in return ( - stream_, blob_, filename_in, _ImageHeaderFactory_, image_header_, - Image__init_, filename_out + stream_, + blob_, + filename_in, + _ImageHeaderFactory_, + image_header_, + Image__init_, + filename_out, ) @pytest.fixture(params=[0, 1, 2, 3, 4, 5, 6, 7, 8]) def known_image_fixture(self, request): cases = ( - ('python.bmp', ('bmp', CT.BMP, 211, 71, 96, 96)), - ('sonic.gif', ('gif', CT.GIF, 290, 360, 72, 72)), - ('python-icon.jpeg', ('jpg', CT.JPEG, 204, 204, 72, 72)), - ('300-dpi.jpg', ('jpg', CT.JPEG, 1504, 1936, 300, 300)), - ('monty-truth.png', ('png', CT.PNG, 150, 214, 72, 72)), - ('150-dpi.png', ('png', CT.PNG, 901, 1350, 150, 150)), - ('300-dpi.png', ('png', CT.PNG, 860, 579, 300, 300)), - ('72-dpi.tiff', ('tiff', CT.TIFF, 48, 48, 72, 72)), - ('300-dpi.TIF', ('tiff', CT.TIFF, 2464, 3248, 300, 300)), + ("python.bmp", ("bmp", CT.BMP, 211, 71, 96, 96)), + ("sonic.gif", ("gif", CT.GIF, 290, 360, 72, 72)), + ("python-icon.jpeg", ("jpg", CT.JPEG, 204, 204, 72, 72)), + ("300-dpi.jpg", ("jpg", CT.JPEG, 1504, 1936, 300, 300)), + ("monty-truth.png", ("png", CT.PNG, 150, 214, 72, 72)), + ("150-dpi.png", ("png", CT.PNG, 901, 1350, 150, 150)), + ("300-dpi.png", ("png", CT.PNG, 860, 579, 300, 300)), + ("72-dpi.tiff", ("tiff", CT.TIFF, 48, 48, 72, 72)), + ("300-dpi.TIF", ("tiff", CT.TIFF, 2464, 3248, 300, 300)), # ('CVS_LOGO.WMF', ('wmf', CT.X_WMF, 149, 59, 72, 72)), ) image_filename, characteristics = cases[request.param] return image_filename, characteristics - @pytest.fixture(params=[ - (None, None, 1000, 2000), - (100, None, 100, 200), - (None, 500, 250, 500), - (1500, 1500, 1500, 1500), - ]) + @pytest.fixture( + params=[ + (None, None, 1000, 2000), + (100, None, 100, 200), + (None, 500, 250, 500), + (1500, 1500, 1500, 1500), + ] + ) def scale_fixture(self, request, width_prop_, height_prop_): width, height, scaled_width, scaled_height = request.param width_prop_.return_value = Emu(1000) @@ -224,9 +226,7 @@ def blob_(self, request): @pytest.fixture def BytesIO_(self, request, stream_): - return class_mock( - request, 'docx.image.image.BytesIO', return_value=stream_ - ) + return class_mock(request, "docx.image.image.BytesIO", return_value=stream_) @pytest.fixture def filename_(self, request): @@ -235,12 +235,12 @@ def filename_(self, request): @pytest.fixture def _from_stream_(self, request, image_): return method_mock( - request, Image, '_from_stream', autospec=False, return_value=image_ + request, Image, "_from_stream", autospec=False, return_value=image_ ) @pytest.fixture def height_prop_(self, request): - return property_mock(request, Image, 'height') + return property_mock(request, Image, "height") @pytest.fixture def image_(self, request): @@ -249,13 +249,12 @@ def image_(self, request): @pytest.fixture def _ImageHeaderFactory_(self, request, image_header_): return function_mock( - request, 'docx.image.image._ImageHeaderFactory', - return_value=image_header_ + request, "docx.image.image._ImageHeaderFactory", return_value=image_header_ ) @pytest.fixture def image_header_(self, request): - return instance_mock(request, BaseImageHeader, default_ext='png') + return instance_mock(request, BaseImageHeader, default_ext="png") @pytest.fixture def Image__init_(self, request): @@ -267,37 +266,37 @@ def stream_(self, request): @pytest.fixture def width_prop_(self, request): - return property_mock(request, Image, 'width') + return property_mock(request, Image, "width") class Describe_ImageHeaderFactory(object): - - def it_constructs_the_right_class_for_a_given_image_stream( - self, call_fixture): + def it_constructs_the_right_class_for_a_given_image_stream(self, call_fixture): stream, expected_class = call_fixture image_header = _ImageHeaderFactory(stream) assert isinstance(image_header, expected_class) def it_raises_on_unrecognized_image_stream(self): - stream = BytesIO(b'foobar 666 not an image stream') + stream = BytesIO(b"foobar 666 not an image stream") with pytest.raises(UnrecognizedImageError): _ImageHeaderFactory(stream) # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - ('python-icon.png', Png), - ('python-icon.jpeg', Jfif), - ('exif-420-dpi.jpg', Exif), - ('sonic.gif', Gif), - ('72-dpi.tiff', Tiff), - ('little-endian.tif', Tiff), - ('python.bmp', Bmp), - ]) + @pytest.fixture( + params=[ + ("python-icon.png", Png), + ("python-icon.jpeg", Jfif), + ("exif-420-dpi.jpg", Exif), + ("sonic.gif", Gif), + ("72-dpi.tiff", Tiff), + ("little-endian.tif", Tiff), + ("python.bmp", Bmp), + ] + ) def call_fixture(self, request): image_filename, expected_class = request.param image_path = testfile(image_filename) - with open(image_path, 'rb') as f: + with open(image_path, "rb") as f: blob = f.read() image_stream = BytesIO(blob) image_stream.seek(666) @@ -305,7 +304,6 @@ def call_fixture(self, request): class DescribeBaseImageHeader(object): - def it_defines_content_type_as_an_abstract_property(self): base_image_header = BaseImageHeader(None, None, None, None) with pytest.raises(NotImplementedError): diff --git a/tests/image/test_jpeg.py b/tests/image/test_jpeg.py index cbbc869b..759bd94c 100644 --- a/tests/image/test_jpeg.py +++ b/tests/image/test_jpeg.py @@ -35,22 +35,18 @@ class DescribeJpeg(object): - def it_knows_its_content_type(self): jpeg = Jpeg(None, None, None, None) assert jpeg.content_type == MIME_TYPE.JPEG def it_knows_its_default_ext(self): jpeg = Jpeg(None, None, None, None) - assert jpeg.default_ext == 'jpg' + assert jpeg.default_ext == "jpg" class DescribeExif(object): - def it_can_construct_from_an_exif_stream(self, from_exif_fixture): # fixture ---------------------- - stream_, _JfifMarkers_, cx, cy, horz_dpi, vert_dpi = ( - from_exif_fixture - ) + stream_, _JfifMarkers_, cx, cy, horz_dpi, vert_dpi = from_exif_fixture # exercise --------------------- exif = Exif.from_stream(stream_) # verify ----------------------- @@ -62,11 +58,8 @@ def it_can_construct_from_an_exif_stream(self, from_exif_fixture): assert exif.vert_dpi == vert_dpi class DescribeJfif(object): - def it_can_construct_from_a_jfif_stream(self, from_jfif_fixture): - stream_, _JfifMarkers_, cx, cy, horz_dpi, vert_dpi = ( - from_jfif_fixture - ) + stream_, _JfifMarkers_, cx, cy, horz_dpi, vert_dpi = from_jfif_fixture jfif = Jfif.from_stream(stream_) _JfifMarkers_.from_stream.assert_called_once_with(stream_) assert isinstance(jfif, Jfif) @@ -85,9 +78,7 @@ def from_exif_fixture(self, stream_, _JfifMarkers_, jfif_markers_): jfif_markers_.sof.px_height = px_height jfif_markers_.app1.horz_dpi = horz_dpi jfif_markers_.app1.vert_dpi = vert_dpi - return ( - stream_, _JfifMarkers_, px_width, px_height, horz_dpi, vert_dpi - ) + return (stream_, _JfifMarkers_, px_width, px_height, horz_dpi, vert_dpi) @pytest.fixture def from_jfif_fixture(self, stream_, _JfifMarkers_, jfif_markers_): @@ -97,13 +88,11 @@ def from_jfif_fixture(self, stream_, _JfifMarkers_, jfif_markers_): jfif_markers_.sof.px_height = px_height jfif_markers_.app0.horz_dpi = horz_dpi jfif_markers_.app0.vert_dpi = vert_dpi - return ( - stream_, _JfifMarkers_, px_width, px_height, horz_dpi, vert_dpi - ) + return (stream_, _JfifMarkers_, px_width, px_height, horz_dpi, vert_dpi) @pytest.fixture def _JfifMarkers_(self, request, jfif_markers_): - _JfifMarkers_ = class_mock(request, 'docx.image.jpeg._JfifMarkers') + _JfifMarkers_ = class_mock(request, "docx.image.jpeg._JfifMarkers") _JfifMarkers_.from_stream.return_value = jfif_markers_ return _JfifMarkers_ @@ -117,9 +106,8 @@ def stream_(self, request): class Describe_JfifMarkers(object): - def it_can_construct_from_a_jfif_stream( - self, stream_, _MarkerParser_, _JfifMarkers__init_, soi_, app0_, sof_, sos_ + self, stream_, _MarkerParser_, _JfifMarkers__init_, soi_, app0_, sof_, sos_ ): marker_lst = [soi_, app0_, sof_, sos_] @@ -163,15 +151,11 @@ def it_raises_if_it_cant_find_the_SOF_marker(self, no_sof_fixture): @pytest.fixture def app0_(self, request): - return instance_mock( - request, _App0Marker, marker_code=JPEG_MARKER_CODE.APP0 - ) + return instance_mock(request, _App0Marker, marker_code=JPEG_MARKER_CODE.APP0) @pytest.fixture def app1_(self, request): - return instance_mock( - request, _App1Marker, marker_code=JPEG_MARKER_CODE.APP1 - ) + return instance_mock(request, _App1Marker, marker_code=JPEG_MARKER_CODE.APP1) @pytest.fixture def app0_fixture(self, soi_, app0_, eoi_): @@ -187,9 +171,7 @@ def app1_fixture(self, soi_, app1_, eoi_): @pytest.fixture def eoi_(self, request): - return instance_mock( - request, _SofMarker, marker_code=JPEG_MARKER_CODE.EOI - ) + return instance_mock(request, _SofMarker, marker_code=JPEG_MARKER_CODE.EOI) @pytest.fixture def _JfifMarkers__init_(self, request): @@ -203,7 +185,7 @@ def marker_parser_(self, request, markers_all_): @pytest.fixture def _MarkerParser_(self, request, marker_parser_): - _MarkerParser_ = class_mock(request, 'docx.image.jpeg._MarkerParser') + _MarkerParser_ = class_mock(request, "docx.image.jpeg._MarkerParser") _MarkerParser_.from_stream.return_value = marker_parser_ return _MarkerParser_ @@ -228,9 +210,7 @@ def no_sof_fixture(self, soi_, eoi_): @pytest.fixture def sof_(self, request): - return instance_mock( - request, _SofMarker, marker_code=JPEG_MARKER_CODE.SOF0 - ) + return instance_mock(request, _SofMarker, marker_code=JPEG_MARKER_CODE.SOF0) @pytest.fixture def sof_fixture(self, soi_, sof_, eoi_): @@ -240,15 +220,11 @@ def sof_fixture(self, soi_, sof_, eoi_): @pytest.fixture def soi_(self, request): - return instance_mock( - request, _Marker, marker_code=JPEG_MARKER_CODE.SOI - ) + return instance_mock(request, _Marker, marker_code=JPEG_MARKER_CODE.SOI) @pytest.fixture def sos_(self, request): - return instance_mock( - request, _Marker, marker_code=JPEG_MARKER_CODE.SOS - ) + return instance_mock(request, _Marker, marker_code=JPEG_MARKER_CODE.SOS) @pytest.fixture def stream_(self, request): @@ -256,7 +232,6 @@ def stream_(self, request): class Describe_Marker(object): - def it_can_construct_from_a_stream_and_offset(self, from_stream_fixture): stream, marker_code, offset, _Marker__init_, length = from_stream_fixture @@ -267,13 +242,15 @@ def it_can_construct_from_a_stream_and_offset(self, from_stream_fixture): # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - (JPEG_MARKER_CODE.SOI, 2, 0), - (JPEG_MARKER_CODE.APP0, 4, 16), - ]) + @pytest.fixture( + params=[ + (JPEG_MARKER_CODE.SOI, 2, 0), + (JPEG_MARKER_CODE.APP0, 4, 16), + ] + ) def from_stream_fixture(self, request, _Marker__init_): marker_code, offset, length = request.param - bytes_ = b'\xFF\xD8\xFF\xE0\x00\x10' + bytes_ = b"\xFF\xD8\xFF\xE0\x00\x10" stream_reader = StreamReader(BytesIO(bytes_), BIG_ENDIAN) return stream_reader, marker_code, offset, _Marker__init_, length @@ -283,9 +260,8 @@ def _Marker__init_(self, request): class Describe_App0Marker(object): - def it_can_construct_from_a_stream_and_offset(self, _App0Marker__init_): - bytes_ = b'\x00\x10JFIF\x00\x01\x01\x01\x00\x2A\x00\x18' + bytes_ = b"\x00\x10JFIF\x00\x01\x01\x01\x00\x2A\x00\x18" marker_code, offset, length = JPEG_MARKER_CODE.APP0, 0, 16 density_units, x_density, y_density = 1, 42, 24 stream = StreamReader(BytesIO(bytes_), BIG_ENDIAN) @@ -299,9 +275,7 @@ def it_can_construct_from_a_stream_and_offset(self, _App0Marker__init_): def it_knows_the_image_dpi(self, dpi_fixture): density_units, x_density, y_density, horz_dpi, vert_dpi = dpi_fixture - app0 = _App0Marker( - None, None, None, density_units, x_density, y_density - ) + app0 = _App0Marker(None, None, None, density_units, x_density, y_density) assert app0.horz_dpi == horz_dpi assert app0.vert_dpi == vert_dpi @@ -311,24 +285,23 @@ def it_knows_the_image_dpi(self, dpi_fixture): def _App0Marker__init_(self, request): return initializer_mock(request, _App0Marker) - @pytest.fixture(params=[ - (0, 100, 200, 72, 72), - (1, 100, 200, 100, 200), - (2, 100, 200, 254, 508), - ]) + @pytest.fixture( + params=[ + (0, 100, 200, 72, 72), + (1, 100, 200, 100, 200), + (2, 100, 200, 254, 508), + ] + ) def dpi_fixture(self, request): - density_units, x_density, y_density, horz_dpi, vert_dpi = ( - request.param - ) + density_units, x_density, y_density, horz_dpi, vert_dpi = request.param return density_units, x_density, y_density, horz_dpi, vert_dpi class Describe_App1Marker(object): - def it_can_construct_from_a_stream_and_offset( self, _App1Marker__init_, _tiff_from_exif_segment_ ): - bytes_ = b'\x00\x42Exif\x00\x00' + bytes_ = b"\x00\x42Exif\x00\x00" marker_code, offset, length = JPEG_MARKER_CODE.APP1, 0, 66 horz_dpi, vert_dpi = 42, 24 stream = StreamReader(BytesIO(bytes_), BIG_ENDIAN) @@ -342,7 +315,7 @@ def it_can_construct_from_a_stream_and_offset( assert isinstance(app1_marker, _App1Marker) def it_can_construct_from_non_Exif_APP1_segment(self, _App1Marker__init_): - bytes_ = b'\x00\x42Foobar' + bytes_ = b"\x00\x42Foobar" marker_code, offset, length = JPEG_MARKER_CODE.APP1, 0, 66 stream = StreamReader(BytesIO(bytes_), BIG_ENDIAN) @@ -353,8 +326,7 @@ def it_can_construct_from_non_Exif_APP1_segment(self, _App1Marker__init_): ) assert isinstance(app1_marker, _App1Marker) - def it_gets_a_tiff_from_its_Exif_segment_to_help_construct( - self, get_tiff_fixture): + def it_gets_a_tiff_from_its_Exif_segment_to_help_construct(self, get_tiff_fixture): stream, offset, length = get_tiff_fixture[:3] BytesIO_, segment_bytes, substream_ = get_tiff_fixture[3:6] Tiff_, tiff_ = get_tiff_fixture[6:] @@ -377,18 +349,22 @@ def _App1Marker__init_(self, request): @pytest.fixture def BytesIO_(self, request, substream_): - return class_mock( - request, 'docx.image.jpeg.BytesIO', return_value=substream_ - ) + return class_mock(request, "docx.image.jpeg.BytesIO", return_value=substream_) @pytest.fixture def get_tiff_fixture(self, request, BytesIO_, substream_, Tiff_, tiff_): - bytes_ = b'xfillerxMM\x00*\x00\x00\x00\x42' + bytes_ = b"xfillerxMM\x00*\x00\x00\x00\x42" stream_reader = StreamReader(BytesIO(bytes_), BIG_ENDIAN) offset, segment_length, segment_bytes = 0, 16, bytes_[8:] return ( - stream_reader, offset, segment_length, BytesIO_, segment_bytes, - substream_, Tiff_, tiff_ + stream_reader, + offset, + segment_length, + BytesIO_, + segment_bytes, + substream_, + Tiff_, + tiff_, ) @pytest.fixture @@ -397,7 +373,7 @@ def substream_(self, request): @pytest.fixture def Tiff_(self, request, tiff_): - Tiff_ = class_mock(request, 'docx.image.jpeg.Tiff') + Tiff_ = class_mock(request, "docx.image.jpeg.Tiff") Tiff_.from_stream.return_value = tiff_ return Tiff_ @@ -408,15 +384,17 @@ def tiff_(self, request): @pytest.fixture def _tiff_from_exif_segment_(self, request, tiff_): return method_mock( - request, _App1Marker, '_tiff_from_exif_segment', autospec=False, - return_value=tiff_ + request, + _App1Marker, + "_tiff_from_exif_segment", + autospec=False, + return_value=tiff_, ) class Describe_SofMarker(object): - def it_can_construct_from_a_stream_and_offset(self, request, _SofMarker__init_): - bytes_ = b'\x00\x11\x00\x00\x2A\x00\x18' + bytes_ = b"\x00\x11\x00\x00\x2A\x00\x18" marker_code, offset, length = JPEG_MARKER_CODE.SOF0, 0, 17 px_width, px_height = 24, 42 stream = StreamReader(BytesIO(bytes_), BIG_ENDIAN) @@ -441,27 +419,33 @@ def _SofMarker__init_(self, request): class Describe_MarkerFactory(object): - def it_constructs_the_appropriate_marker_object(self, call_fixture): marker_code, stream_, offset_, marker_cls_ = call_fixture marker = _MarkerFactory(marker_code, stream_, offset_) - marker_cls_.from_stream.assert_called_once_with( - stream_, marker_code, offset_ - ) + marker_cls_.from_stream.assert_called_once_with(stream_, marker_code, offset_) assert marker is marker_cls_.from_stream.return_value # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - JPEG_MARKER_CODE.APP0, - JPEG_MARKER_CODE.APP1, - JPEG_MARKER_CODE.SOF0, - JPEG_MARKER_CODE.SOF7, - JPEG_MARKER_CODE.SOS, - ]) + @pytest.fixture( + params=[ + JPEG_MARKER_CODE.APP0, + JPEG_MARKER_CODE.APP1, + JPEG_MARKER_CODE.SOF0, + JPEG_MARKER_CODE.SOF7, + JPEG_MARKER_CODE.SOS, + ] + ) def call_fixture( - self, request, stream_, offset_, _App0Marker_, _App1Marker_, - _SofMarker_, _Marker_): + self, + request, + stream_, + offset_, + _App0Marker_, + _App1Marker_, + _SofMarker_, + _Marker_, + ): marker_code = request.param if marker_code == JPEG_MARKER_CODE.APP0: marker_cls_ = _App0Marker_ @@ -475,15 +459,15 @@ def call_fixture( @pytest.fixture def _App0Marker_(self, request): - return class_mock(request, 'docx.image.jpeg._App0Marker') + return class_mock(request, "docx.image.jpeg._App0Marker") @pytest.fixture def _App1Marker_(self, request): - return class_mock(request, 'docx.image.jpeg._App1Marker') + return class_mock(request, "docx.image.jpeg._App1Marker") @pytest.fixture def _Marker_(self, request): - return class_mock(request, 'docx.image.jpeg._Marker') + return class_mock(request, "docx.image.jpeg._Marker") @pytest.fixture def offset_(self, request): @@ -491,7 +475,7 @@ def offset_(self, request): @pytest.fixture def _SofMarker_(self, request): - return class_mock(request, 'docx.image.jpeg._SofMarker') + return class_mock(request, "docx.image.jpeg._SofMarker") @pytest.fixture def stream_(self, request): @@ -499,7 +483,6 @@ def stream_(self, request): class Describe_MarkerFinder(object): - def it_can_construct_from_a_stream(self, stream_, _MarkerFinder__init_): marker_finder = _MarkerFinder.from_stream(stream_) @@ -517,18 +500,20 @@ def it_can_find_the_next_marker_after_a_given_offset(self, next_fixture): def _MarkerFinder__init_(self, request): return initializer_mock(request, _MarkerFinder) - @pytest.fixture(params=[ - (0, JPEG_MARKER_CODE.SOI, 2), - (1, JPEG_MARKER_CODE.APP0, 4), - (2, JPEG_MARKER_CODE.APP0, 4), - (3, JPEG_MARKER_CODE.EOI, 12), - (4, JPEG_MARKER_CODE.EOI, 12), - (6, JPEG_MARKER_CODE.EOI, 12), - (8, JPEG_MARKER_CODE.EOI, 12), - ]) + @pytest.fixture( + params=[ + (0, JPEG_MARKER_CODE.SOI, 2), + (1, JPEG_MARKER_CODE.APP0, 4), + (2, JPEG_MARKER_CODE.APP0, 4), + (3, JPEG_MARKER_CODE.EOI, 12), + (4, JPEG_MARKER_CODE.EOI, 12), + (6, JPEG_MARKER_CODE.EOI, 12), + (8, JPEG_MARKER_CODE.EOI, 12), + ] + ) def next_fixture(self, request): start, marker_code, segment_offset = request.param - bytes_ = b'\xFF\xD8\xFF\xE0\x00\x01\xFF\x00\xFF\xFF\xFF\xD9' + bytes_ = b"\xFF\xD8\xFF\xE0\x00\x01\xFF\x00\xFF\xFF\xFF\xD9" stream_reader = StreamReader(BytesIO(bytes_), BIG_ENDIAN) marker_finder = _MarkerFinder(stream_reader) expected_code_and_offset = (marker_code, segment_offset) @@ -540,7 +525,6 @@ def stream_(self, request): class Describe_MarkerParser(object): - def it_can_construct_from_a_jfif_stream( self, stream_, StreamReader_, _MarkerParser__init_, stream_reader_ ): @@ -550,16 +534,20 @@ def it_can_construct_from_a_jfif_stream( _MarkerParser__init_.assert_called_once_with(ANY, stream_reader_) assert isinstance(marker_parser, _MarkerParser) - def it_can_iterate_over_the_jfif_markers_in_its_stream( - self, iter_markers_fixture): - (marker_parser, stream_, _MarkerFinder_, marker_finder_, - _MarkerFactory_, marker_codes, offsets, - marker_lst) = iter_markers_fixture + def it_can_iterate_over_the_jfif_markers_in_its_stream(self, iter_markers_fixture): + ( + marker_parser, + stream_, + _MarkerFinder_, + marker_finder_, + _MarkerFactory_, + marker_codes, + offsets, + marker_lst, + ) = iter_markers_fixture markers = [marker for marker in marker_parser.iter_markers()] _MarkerFinder_.from_stream.assert_called_once_with(stream_) - assert marker_finder_.next.call_args_list == [ - call(0), call(2), call(20) - ] + assert marker_finder_.next.call_args_list == [call(0), call(2), call(20)] assert _MarkerFactory_.call_args_list == [ call(marker_codes[0], stream_, offsets[0]), call(marker_codes[1], stream_, offsets[1]), @@ -579,34 +567,48 @@ def eoi_(self, request): @pytest.fixture def iter_markers_fixture( - self, stream_reader_, _MarkerFinder_, marker_finder_, - _MarkerFactory_, soi_, app0_, eoi_): + self, + stream_reader_, + _MarkerFinder_, + marker_finder_, + _MarkerFactory_, + soi_, + app0_, + eoi_, + ): marker_parser = _MarkerParser(stream_reader_) offsets = [2, 4, 22] marker_lst = [soi_, app0_, eoi_] marker_finder_.next.side_effect = [ - (JPEG_MARKER_CODE.SOI, offsets[0]), + (JPEG_MARKER_CODE.SOI, offsets[0]), (JPEG_MARKER_CODE.APP0, offsets[1]), - (JPEG_MARKER_CODE.EOI, offsets[2]), + (JPEG_MARKER_CODE.EOI, offsets[2]), ] marker_codes = [ - JPEG_MARKER_CODE.SOI, JPEG_MARKER_CODE.APP0, JPEG_MARKER_CODE.EOI + JPEG_MARKER_CODE.SOI, + JPEG_MARKER_CODE.APP0, + JPEG_MARKER_CODE.EOI, ] return ( - marker_parser, stream_reader_, _MarkerFinder_, marker_finder_, - _MarkerFactory_, marker_codes, offsets, marker_lst + marker_parser, + stream_reader_, + _MarkerFinder_, + marker_finder_, + _MarkerFactory_, + marker_codes, + offsets, + marker_lst, ) @pytest.fixture def _MarkerFactory_(self, request, soi_, app0_, eoi_): return class_mock( - request, 'docx.image.jpeg._MarkerFactory', - side_effect=[soi_, app0_, eoi_] + request, "docx.image.jpeg._MarkerFactory", side_effect=[soi_, app0_, eoi_] ) @pytest.fixture def _MarkerFinder_(self, request, marker_finder_): - _MarkerFinder_ = class_mock(request, 'docx.image.jpeg._MarkerFinder') + _MarkerFinder_ = class_mock(request, "docx.image.jpeg._MarkerFinder") _MarkerFinder_.from_stream.return_value = marker_finder_ return _MarkerFinder_ @@ -629,8 +631,7 @@ def stream_(self, request): @pytest.fixture def StreamReader_(self, request, stream_reader_): return class_mock( - request, 'docx.image.jpeg.StreamReader', - return_value=stream_reader_ + request, "docx.image.jpeg.StreamReader", return_value=stream_reader_ ) @pytest.fixture diff --git a/tests/image/test_png.py b/tests/image/test_png.py index 21ed66fa..71b2c7e1 100644 --- a/tests/image/test_png.py +++ b/tests/image/test_png.py @@ -11,8 +11,14 @@ from docx.image.exceptions import InvalidImageStreamError from docx.image.helpers import BIG_ENDIAN, StreamReader from docx.image.png import ( - _Chunk, _Chunks, _ChunkFactory, _ChunkParser, _IHDRChunk, _pHYsChunk, - Png, _PngParser + _Chunk, + _Chunks, + _ChunkFactory, + _ChunkParser, + _IHDRChunk, + _pHYsChunk, + Png, + _PngParser, ) from ..unitutil.mock import ( @@ -27,9 +33,8 @@ class DescribePng(object): - def it_can_construct_from_a_png_stream( - self, stream_, _PngParser_, png_parser_, Png__init__ + self, stream_, _PngParser_, png_parser_, Png__init__ ): px_width, px_height, horz_dpi, vert_dpi = 42, 24, 36, 63 png_parser_.px_width = px_width @@ -51,7 +56,7 @@ def it_knows_its_content_type(self): def it_knows_its_default_ext(self): png = Png(None, None, None, None) - assert png.default_ext == 'png' + assert png.default_ext == "png" # fixtures ------------------------------------------------------- @@ -61,7 +66,7 @@ def Png__init__(self, request): @pytest.fixture def _PngParser_(self, request, png_parser_): - _PngParser_ = class_mock(request, 'docx.image.png._PngParser') + _PngParser_ = class_mock(request, "docx.image.png._PngParser") _PngParser_.parse.return_value = png_parser_ return _PngParser_ @@ -75,7 +80,6 @@ def stream_(self, request): class Describe_PngParser(object): - def it_can_parse_the_headers_of_a_PNG_stream( self, stream_, _Chunks_, _PngParser__init_, chunks_ ): @@ -104,7 +108,7 @@ def it_defaults_image_dpi_to_72(self, no_dpi_fixture): @pytest.fixture def _Chunks_(self, request, chunks_): - _Chunks_ = class_mock(request, 'docx.image.png._Chunks') + _Chunks_ = class_mock(request, "docx.image.png._Chunks") _Chunks_.from_stream.return_value = chunks_ return _Chunks_ @@ -130,9 +134,7 @@ def dpi_fixture(self, chunks_): png_parser = _PngParser(chunks_) return png_parser, horz_dpi, vert_dpi - @pytest.fixture(params=[ - (-1, -1), (0, 1000), (None, 1000), (1, 0), (1, None) - ]) + @pytest.fixture(params=[(-1, -1), (0, 1000), (None, 1000), (1, 0), (1, None)]) def no_dpi_fixture(self, request, chunks_): """ Scenarios are: 1) no pHYs chunk in PNG stream, 2) units specifier @@ -158,7 +160,6 @@ def stream_(self, request): class Describe_Chunks(object): - def it_can_construct_from_a_stream( self, stream_, _ChunkParser_, chunk_parser_, _Chunks__init_ ): @@ -189,7 +190,7 @@ def it_raises_if_theres_no_IHDR_chunk(self, no_IHDR_fixture): @pytest.fixture def _ChunkParser_(self, request, chunk_parser_): - _ChunkParser_ = class_mock(request, 'docx.image.png._ChunkParser') + _ChunkParser_ = class_mock(request, "docx.image.png._ChunkParser") _ChunkParser_.from_stream.return_value = chunk_parser_ return _ChunkParser_ @@ -209,9 +210,7 @@ def IHDR_fixture(self, IHDR_chunk_, pHYs_chunk_): @pytest.fixture def IHDR_chunk_(self, request): - return instance_mock( - request, _IHDRChunk, type_name=PNG_CHUNK_TYPE.IHDR - ) + return instance_mock(request, _IHDRChunk, type_name=PNG_CHUNK_TYPE.IHDR) @pytest.fixture def no_IHDR_fixture(self, pHYs_chunk_): @@ -221,9 +220,7 @@ def no_IHDR_fixture(self, pHYs_chunk_): @pytest.fixture def pHYs_chunk_(self, request): - return instance_mock( - request, _pHYsChunk, type_name=PNG_CHUNK_TYPE.pHYs - ) + return instance_mock(request, _pHYsChunk, type_name=PNG_CHUNK_TYPE.pHYs) @pytest.fixture(params=[True, False]) def pHYs_fixture(self, request, IHDR_chunk_, pHYs_chunk_): @@ -241,7 +238,6 @@ def stream_(self, request): class Describe_ChunkParser(object): - def it_can_construct_from_a_stream( self, stream_, StreamReader_, stream_rdr_, _ChunkParser__init_ ): @@ -267,8 +263,7 @@ def it_can_iterate_over_the_chunks_in_its_png_stream( ] assert chunks == chunk_lst - def it_iterates_over_the_chunk_offsets_to_help_parse( - self, iter_offsets_fixture): + def it_iterates_over_the_chunk_offsets_to_help_parse(self, iter_offsets_fixture): chunk_parser, expected_chunk_offsets = iter_offsets_fixture chunk_offsets = [co for co in chunk_parser._iter_chunk_offsets()] assert chunk_offsets == expected_chunk_offsets @@ -286,8 +281,7 @@ def chunk_2_(self, request): @pytest.fixture def _ChunkFactory_(self, request, chunk_lst_): return function_mock( - request, 'docx.image.png._ChunkFactory', - side_effect=chunk_lst_ + request, "docx.image.png._ChunkFactory", side_effect=chunk_lst_ ) @pytest.fixture @@ -305,13 +299,15 @@ def _iter_chunk_offsets_(self, request): (PNG_CHUNK_TYPE.pHYs, 4), ) return method_mock( - request, _ChunkParser, '_iter_chunk_offsets', - return_value=iter(chunk_offsets) + request, + _ChunkParser, + "_iter_chunk_offsets", + return_value=iter(chunk_offsets), ) @pytest.fixture def iter_offsets_fixture(self): - bytes_ = b'-filler-\x00\x00\x00\x00IHDRxxxx\x00\x00\x00\x00IEND' + bytes_ = b"-filler-\x00\x00\x00\x00IHDRxxxx\x00\x00\x00\x00IEND" stream_rdr = StreamReader(BytesIO(bytes_), BIG_ENDIAN) chunk_parser = _ChunkParser(stream_rdr) expected_chunk_offsets = [ @@ -323,7 +319,7 @@ def iter_offsets_fixture(self): @pytest.fixture def StreamReader_(self, request, stream_rdr_): return class_mock( - request, 'docx.image.png.StreamReader', return_value=stream_rdr_ + request, "docx.image.png.StreamReader", return_value=stream_rdr_ ) @pytest.fixture @@ -336,24 +332,22 @@ def stream_rdr_(self, request): class Describe_ChunkFactory(object): - def it_constructs_the_appropriate_Chunk_subclass(self, call_fixture): chunk_type, stream_rdr_, offset, chunk_cls_ = call_fixture chunk = _ChunkFactory(chunk_type, stream_rdr_, offset) - chunk_cls_.from_offset.assert_called_once_with( - chunk_type, stream_rdr_, offset - ) + chunk_cls_.from_offset.assert_called_once_with(chunk_type, stream_rdr_, offset) assert isinstance(chunk, _Chunk) # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - PNG_CHUNK_TYPE.IHDR, - PNG_CHUNK_TYPE.pHYs, - PNG_CHUNK_TYPE.IEND, - ]) - def call_fixture( - self, request, _IHDRChunk_, _pHYsChunk_, _Chunk_, stream_rdr_): + @pytest.fixture( + params=[ + PNG_CHUNK_TYPE.IHDR, + PNG_CHUNK_TYPE.pHYs, + PNG_CHUNK_TYPE.IEND, + ] + ) + def call_fixture(self, request, _IHDRChunk_, _pHYsChunk_, _Chunk_, stream_rdr_): chunk_type = request.param chunk_cls_ = { PNG_CHUNK_TYPE.IHDR: _IHDRChunk_, @@ -365,7 +359,7 @@ def call_fixture( @pytest.fixture def _Chunk_(self, request, chunk_): - _Chunk_ = class_mock(request, 'docx.image.png._Chunk') + _Chunk_ = class_mock(request, "docx.image.png._Chunk") _Chunk_.from_offset.return_value = chunk_ return _Chunk_ @@ -375,7 +369,7 @@ def chunk_(self, request): @pytest.fixture def _IHDRChunk_(self, request, ihdr_chunk_): - _IHDRChunk_ = class_mock(request, 'docx.image.png._IHDRChunk') + _IHDRChunk_ = class_mock(request, "docx.image.png._IHDRChunk") _IHDRChunk_.from_offset.return_value = ihdr_chunk_ return _IHDRChunk_ @@ -385,7 +379,7 @@ def ihdr_chunk_(self, request): @pytest.fixture def _pHYsChunk_(self, request, phys_chunk_): - _pHYsChunk_ = class_mock(request, 'docx.image.png._pHYsChunk') + _pHYsChunk_ = class_mock(request, "docx.image.png._pHYsChunk") _pHYsChunk_.from_offset.return_value = phys_chunk_ return _pHYsChunk_ @@ -399,16 +393,14 @@ def stream_rdr_(self, request): class Describe_Chunk(object): - def it_can_construct_from_a_stream_and_offset(self): - chunk_type = 'fOOB' + chunk_type = "fOOB" chunk = _Chunk.from_offset(chunk_type, None, None) assert isinstance(chunk, _Chunk) assert chunk.type_name == chunk_type class Describe_IHDRChunk(object): - def it_can_construct_from_a_stream_and_offset(self, from_offset_fixture): stream_rdr, offset, px_width, px_height = from_offset_fixture ihdr_chunk = _IHDRChunk.from_offset(None, stream_rdr, offset) @@ -420,14 +412,13 @@ def it_can_construct_from_a_stream_and_offset(self, from_offset_fixture): @pytest.fixture def from_offset_fixture(self): - bytes_ = b'\x00\x00\x00\x2A\x00\x00\x00\x18' + bytes_ = b"\x00\x00\x00\x2A\x00\x00\x00\x18" stream_rdr = StreamReader(BytesIO(bytes_), BIG_ENDIAN) offset, px_width, px_height = 0, 42, 24 return stream_rdr, offset, px_width, px_height class Describe_pHYsChunk(object): - def it_can_construct_from_a_stream_and_offset(self, from_offset_fixture): stream_rdr, offset = from_offset_fixture[:2] horz_px_per_unit, vert_px_per_unit = from_offset_fixture[2:4] @@ -442,12 +433,7 @@ def it_can_construct_from_a_stream_and_offset(self, from_offset_fixture): @pytest.fixture def from_offset_fixture(self): - bytes_ = b'\x00\x00\x00\x2A\x00\x00\x00\x18\x01' + bytes_ = b"\x00\x00\x00\x2A\x00\x00\x00\x18\x01" stream_rdr = StreamReader(BytesIO(bytes_), BIG_ENDIAN) - offset, horz_px_per_unit, vert_px_per_unit, units_specifier = ( - 0, 42, 24, 1 - ) - return ( - stream_rdr, offset, horz_px_per_unit, vert_px_per_unit, - units_specifier - ) + offset, horz_px_per_unit, vert_px_per_unit, units_specifier = (0, 42, 24, 1) + return (stream_rdr, offset, horz_px_per_unit, vert_px_per_unit, units_specifier) diff --git a/tests/image/test_tiff.py b/tests/image/test_tiff.py index 277df5f2..a5f07acd 100644 --- a/tests/image/test_tiff.py +++ b/tests/image/test_tiff.py @@ -35,7 +35,6 @@ class DescribeTiff(object): - def it_can_construct_from_a_tiff_stream( self, stream_, _TiffParser_, tiff_parser_, Tiff__init_ ): @@ -60,7 +59,7 @@ def it_knows_its_content_type(self): def it_knows_its_default_ext(self): tiff = Tiff(None, None, None, None) - assert tiff.default_ext == 'tiff' + assert tiff.default_ext == "tiff" # fixtures ------------------------------------------------------- @@ -70,7 +69,7 @@ def Tiff__init_(self, request): @pytest.fixture def _TiffParser_(self, request, tiff_parser_): - _TiffParser_ = class_mock(request, 'docx.image.tiff._TiffParser') + _TiffParser_ = class_mock(request, "docx.image.tiff._TiffParser") _TiffParser_.parse.return_value = tiff_parser_ return _TiffParser_ @@ -84,7 +83,6 @@ def stream_(self, request): class Describe_TiffParser(object): - def it_can_parse_the_properties_from_a_tiff_stream( self, stream_, @@ -98,9 +96,7 @@ def it_can_parse_the_properties_from_a_tiff_stream( tiff_parser = _TiffParser.parse(stream_) _make_stream_reader_.assert_called_once_with(stream_) - _IfdEntries_.from_stream.assert_called_once_with( - stream_rdr_, ifd0_offset_ - ) + _IfdEntries_.from_stream.assert_called_once_with(stream_rdr_, ifd0_offset_) _TiffParser__init_.assert_called_once_with(ANY, ifd_entries_) assert isinstance(tiff_parser, _TiffParser) @@ -113,7 +109,7 @@ def it_makes_a_stream_reader_to_help_parse(self, mk_stream_rdr_fixture): def it_knows_image_width_and_height_after_parsing(self): px_width, px_height = 42, 24 entries = { - TIFF_TAG.IMAGE_WIDTH: px_width, + TIFF_TAG.IMAGE_WIDTH: px_width, TIFF_TAG.IMAGE_LENGTH: px_height, } ifd_entries = _IfdEntries(entries) @@ -128,13 +124,15 @@ def it_knows_the_horz_and_vert_dpi_after_parsing(self, dpi_fixture): # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - (1, 150, 240, 72, 72), - (2, 42, 24, 42, 24), - (3, 100, 200, 254, 508), - (2, None, None, 72, 72), - (None, 96, 100, 96, 100), - ]) + @pytest.fixture( + params=[ + (1, 150, 240, 72, 72), + (2, 42, 24, 42, 24), + (3, 100, 200, 254, 508), + (2, None, None, 72, 72), + (None, 96, 100, 96, 100), + ] + ) def dpi_fixture(self, request): resolution_unit, x_resolution, y_resolution = request.param[:3] expected_horz_dpi, expected_vert_dpi = request.param[3:] @@ -152,7 +150,7 @@ def dpi_fixture(self, request): @pytest.fixture def _IfdEntries_(self, request, ifd_entries_): - _IfdEntries_ = class_mock(request, 'docx.image.tiff._IfdEntries') + _IfdEntries_ = class_mock(request, "docx.image.tiff._IfdEntries") _IfdEntries_.from_stream.return_value = ifd_entries_ return _IfdEntries_ @@ -169,15 +167,17 @@ def _make_stream_reader_(self, request, stream_rdr_): return method_mock( request, _TiffParser, - '_make_stream_reader', + "_make_stream_reader", autospec=False, - return_value=stream_rdr_ + return_value=stream_rdr_, ) - @pytest.fixture(params=[ - (b'MM\x00*', BIG_ENDIAN), - (b'II*\x00', LITTLE_ENDIAN), - ]) + @pytest.fixture( + params=[ + (b"MM\x00*", BIG_ENDIAN), + (b"II*\x00", LITTLE_ENDIAN), + ] + ) def mk_stream_rdr_fixture(self, request, StreamReader_, stream_rdr_): bytes_, endian = request.param stream = BytesIO(bytes_) @@ -190,7 +190,7 @@ def stream_(self, request): @pytest.fixture def StreamReader_(self, request, stream_rdr_): return class_mock( - request, 'docx.image.tiff.StreamReader', return_value=stream_rdr_ + request, "docx.image.tiff.StreamReader", return_value=stream_rdr_ ) @pytest.fixture @@ -205,7 +205,6 @@ def _TiffParser__init_(self, request): class Describe_IfdEntries(object): - def it_can_construct_from_a_stream_and_offset( self, stream_, @@ -226,7 +225,7 @@ def it_can_construct_from_a_stream_and_offset( assert isinstance(ifd_entries, _IfdEntries) def it_has_basic_mapping_semantics(self): - key, value = 1, 'foobar' + key, value = 1, "foobar" entries = {key: value} ifd_entries = _IfdEntries(entries) assert key in ifd_entries @@ -249,7 +248,7 @@ def _IfdEntries__init_(self, request): @pytest.fixture def _IfdParser_(self, request, ifd_parser_): return class_mock( - request, 'docx.image.tiff._IfdParser', return_value=ifd_parser_ + request, "docx.image.tiff._IfdParser", return_value=ifd_parser_ ) @pytest.fixture @@ -266,11 +265,14 @@ def stream_(self, request): class Describe_IfdParser(object): - - def it_can_iterate_through_the_directory_entries_in_an_IFD( - self, iter_fixture): - (ifd_parser, _IfdEntryFactory_, stream_rdr, offsets, - expected_entries) = iter_fixture + def it_can_iterate_through_the_directory_entries_in_an_IFD(self, iter_fixture): + ( + ifd_parser, + _IfdEntryFactory_, + stream_rdr, + offsets, + expected_entries, + ) = iter_fixture entries = [e for e in ifd_parser.iter_entries()] assert _IfdEntryFactory_.call_args_list == [ call(stream_rdr, offsets[0]), @@ -291,24 +293,21 @@ def ifd_entry_2_(self, request): @pytest.fixture def _IfdEntryFactory_(self, request, ifd_entry_, ifd_entry_2_): return function_mock( - request, 'docx.image.tiff._IfdEntryFactory', - side_effect=[ifd_entry_, ifd_entry_2_] + request, + "docx.image.tiff._IfdEntryFactory", + side_effect=[ifd_entry_, ifd_entry_2_], ) @pytest.fixture def iter_fixture(self, _IfdEntryFactory_, ifd_entry_, ifd_entry_2_): - stream_rdr = StreamReader(BytesIO(b'\x00\x02'), BIG_ENDIAN) + stream_rdr = StreamReader(BytesIO(b"\x00\x02"), BIG_ENDIAN) offsets = [2, 14] ifd_parser = _IfdParser(stream_rdr, offset=0) expected_entries = [ifd_entry_, ifd_entry_2_] - return ( - ifd_parser, _IfdEntryFactory_, stream_rdr, offsets, - expected_entries - ) + return (ifd_parser, _IfdEntryFactory_, stream_rdr, offsets, expected_entries) class Describe_IfdEntryFactory(object): - def it_constructs_the_right_class_for_a_given_ifd_entry(self, fixture): stream_rdr, offset, entry_cls_, ifd_entry_ = fixture ifd_entry = _IfdEntryFactory(stream_rdr, offset) @@ -317,25 +316,34 @@ def it_constructs_the_right_class_for_a_given_ifd_entry(self, fixture): # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - (b'\x66\x66\x00\x01', 'BYTE'), - (b'\x66\x66\x00\x02', 'ASCII'), - (b'\x66\x66\x00\x03', 'SHORT'), - (b'\x66\x66\x00\x04', 'LONG'), - (b'\x66\x66\x00\x05', 'RATIONAL'), - (b'\x66\x66\x00\x06', 'CUSTOM'), - ]) + @pytest.fixture( + params=[ + (b"\x66\x66\x00\x01", "BYTE"), + (b"\x66\x66\x00\x02", "ASCII"), + (b"\x66\x66\x00\x03", "SHORT"), + (b"\x66\x66\x00\x04", "LONG"), + (b"\x66\x66\x00\x05", "RATIONAL"), + (b"\x66\x66\x00\x06", "CUSTOM"), + ] + ) def fixture( - self, request, ifd_entry_, _IfdEntry_, _AsciiIfdEntry_, - _ShortIfdEntry_, _LongIfdEntry_, _RationalIfdEntry_): + self, + request, + ifd_entry_, + _IfdEntry_, + _AsciiIfdEntry_, + _ShortIfdEntry_, + _LongIfdEntry_, + _RationalIfdEntry_, + ): bytes_, entry_type = request.param entry_cls_ = { - 'BYTE': _IfdEntry_, - 'ASCII': _AsciiIfdEntry_, - 'SHORT': _ShortIfdEntry_, - 'LONG': _LongIfdEntry_, - 'RATIONAL': _RationalIfdEntry_, - 'CUSTOM': _IfdEntry_, + "BYTE": _IfdEntry_, + "ASCII": _AsciiIfdEntry_, + "SHORT": _ShortIfdEntry_, + "LONG": _LongIfdEntry_, + "RATIONAL": _RationalIfdEntry_, + "CUSTOM": _IfdEntry_, }[entry_type] stream_rdr = StreamReader(BytesIO(bytes_), BIG_ENDIAN) offset = 0 @@ -347,35 +355,31 @@ def ifd_entry_(self, request): @pytest.fixture def _IfdEntry_(self, request, ifd_entry_): - _IfdEntry_ = class_mock(request, 'docx.image.tiff._IfdEntry') + _IfdEntry_ = class_mock(request, "docx.image.tiff._IfdEntry") _IfdEntry_.from_stream.return_value = ifd_entry_ return _IfdEntry_ @pytest.fixture def _AsciiIfdEntry_(self, request, ifd_entry_): - _AsciiIfdEntry_ = class_mock( - request, 'docx.image.tiff._AsciiIfdEntry') + _AsciiIfdEntry_ = class_mock(request, "docx.image.tiff._AsciiIfdEntry") _AsciiIfdEntry_.from_stream.return_value = ifd_entry_ return _AsciiIfdEntry_ @pytest.fixture def _ShortIfdEntry_(self, request, ifd_entry_): - _ShortIfdEntry_ = class_mock( - request, 'docx.image.tiff._ShortIfdEntry') + _ShortIfdEntry_ = class_mock(request, "docx.image.tiff._ShortIfdEntry") _ShortIfdEntry_.from_stream.return_value = ifd_entry_ return _ShortIfdEntry_ @pytest.fixture def _LongIfdEntry_(self, request, ifd_entry_): - _LongIfdEntry_ = class_mock( - request, 'docx.image.tiff._LongIfdEntry') + _LongIfdEntry_ = class_mock(request, "docx.image.tiff._LongIfdEntry") _LongIfdEntry_.from_stream.return_value = ifd_entry_ return _LongIfdEntry_ @pytest.fixture def _RationalIfdEntry_(self, request, ifd_entry_): - _RationalIfdEntry_ = class_mock( - request, 'docx.image.tiff._RationalIfdEntry') + _RationalIfdEntry_ = class_mock(request, "docx.image.tiff._RationalIfdEntry") _RationalIfdEntry_.from_stream.return_value = ifd_entry_ return _RationalIfdEntry_ @@ -385,11 +389,10 @@ def offset_(self, request): class Describe_IfdEntry(object): - def it_can_construct_from_a_stream_and_offset( self, _parse_value_, _IfdEntry__init_, value_ ): - bytes_ = b'\x00\x01\x66\x66\x00\x00\x00\x02\x00\x00\x00\x03' + bytes_ = b"\x00\x01\x66\x66\x00\x00\x00\x02\x00\x00\x00\x03" stream_rdr = StreamReader(BytesIO(bytes_), BIG_ENDIAN) offset, tag_code, value_count, value_offset = 0, 1, 2, 3 _parse_value_.return_value = value_ @@ -415,7 +418,7 @@ def _IfdEntry__init_(self, request): @pytest.fixture def _parse_value_(self, request): - return method_mock(request, _IfdEntry, '_parse_value', autospec=False) + return method_mock(request, _IfdEntry, "_parse_value", autospec=False) @pytest.fixture def value_(self, request): @@ -423,36 +426,32 @@ def value_(self, request): class Describe_AsciiIfdEntry(object): - def it_can_parse_an_ascii_string_IFD_entry(self): - bytes_ = b'foobar\x00' + bytes_ = b"foobar\x00" stream_rdr = StreamReader(BytesIO(bytes_), BIG_ENDIAN) val = _AsciiIfdEntry._parse_value(stream_rdr, None, 7, 0) - assert val == 'foobar' + assert val == "foobar" class Describe_ShortIfdEntry(object): - def it_can_parse_a_short_int_IFD_entry(self): - bytes_ = b'foobaroo\x00\x2A' + bytes_ = b"foobaroo\x00\x2A" stream_rdr = StreamReader(BytesIO(bytes_), BIG_ENDIAN) val = _ShortIfdEntry._parse_value(stream_rdr, 0, 1, None) assert val == 42 class Describe_LongIfdEntry(object): - def it_can_parse_a_long_int_IFD_entry(self): - bytes_ = b'foobaroo\x00\x00\x00\x2A' + bytes_ = b"foobaroo\x00\x00\x00\x2A" stream_rdr = StreamReader(BytesIO(bytes_), BIG_ENDIAN) val = _LongIfdEntry._parse_value(stream_rdr, 0, 1, None) assert val == 42 class Describe_RationalIfdEntry(object): - def it_can_parse_a_rational_IFD_entry(self): - bytes_ = b'\x00\x00\x00\x2A\x00\x00\x00\x54' + bytes_ = b"\x00\x00\x00\x2A\x00\x00\x00\x54" stream_rdr = StreamReader(BytesIO(bytes_), BIG_ENDIAN) val = _RationalIfdEntry._parse_value(stream_rdr, None, 1, 0) assert val == 0.5 diff --git a/tests/opc/parts/test_coreprops.py b/tests/opc/parts/test_coreprops.py index 921a885d..66222cef 100644 --- a/tests/opc/parts/test_coreprops.py +++ b/tests/opc/parts/test_coreprops.py @@ -4,9 +4,7 @@ Unit test suite for the docx.opc.parts.coreprops module """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals from datetime import datetime, timedelta @@ -20,7 +18,6 @@ class DescribeCorePropertiesPart(object): - def it_provides_access_to_its_core_props_object(self, coreprops_fixture): core_properties_part, CoreProperties_ = coreprops_fixture core_properties = core_properties_part.core_properties @@ -31,8 +28,8 @@ def it_can_create_a_default_core_properties_part(self): core_properties_part = CorePropertiesPart.default(None) assert isinstance(core_properties_part, CorePropertiesPart) core_properties = core_properties_part.core_properties - assert core_properties.title == 'Word Document' - assert core_properties.last_modified_by == 'python-docx' + assert core_properties.title == "Word Document" + assert core_properties.last_modified_by == "python-docx" assert core_properties.revision == 1 delta = datetime.utcnow() - core_properties.modified max_expected_delta = timedelta(seconds=2) @@ -49,7 +46,7 @@ def coreprops_fixture(self, element_, CoreProperties_): @pytest.fixture def CoreProperties_(self, request): - return class_mock(request, 'docx.opc.parts.coreprops.CoreProperties') + return class_mock(request, "docx.opc.parts.coreprops.CoreProperties") @pytest.fixture def element_(self, request): diff --git a/tests/opc/parts/test_customprops.py b/tests/opc/parts/test_customprops.py index bfd42ecc..cf83e95b 100644 --- a/tests/opc/parts/test_customprops.py +++ b/tests/opc/parts/test_customprops.py @@ -4,9 +4,7 @@ Unit test suite for the docx.opc.parts.customprops module """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals from datetime import datetime, timedelta @@ -20,7 +18,6 @@ class DescribeCustomPropertiesPart(object): - def it_provides_access_to_its_custom_props_object(self, customprops_fixture): custom_properties_part, CustomProperties_ = customprops_fixture custom_properties = custom_properties_part.custom_properties @@ -44,7 +41,7 @@ def customprops_fixture(self, element_, CustomProperties_): @pytest.fixture def CustomProperties_(self, request): - return class_mock(request, 'docx.opc.parts.customprops.CustomProperties') + return class_mock(request, "docx.opc.parts.customprops.CustomProperties") @pytest.fixture def element_(self, request): diff --git a/tests/opc/test_coreprops.py b/tests/opc/test_coreprops.py index 47195f59..97da5dea 100644 --- a/tests/opc/test_coreprops.py +++ b/tests/opc/test_coreprops.py @@ -4,9 +4,7 @@ Unit test suite for the docx.opc.coreprops module """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals import pytest @@ -17,7 +15,6 @@ class DescribeCoreProperties(object): - def it_knows_the_string_property_values(self, text_prop_get_fixture): core_properties, prop_name, expected_value = text_prop_get_fixture actual_value = getattr(core_properties, prop_name) @@ -34,9 +31,7 @@ def it_knows_the_date_property_values(self, date_prop_get_fixture): assert actual_datetime == expected_datetime def it_can_change_the_date_property_values(self, date_prop_set_fixture): - core_properties, prop_name, value, expected_xml = ( - date_prop_set_fixture - ) + core_properties, prop_name, value, expected_xml = date_prop_set_fixture setattr(core_properties, prop_name, value) assert core_properties._element.xml == expected_xml @@ -51,23 +46,42 @@ def it_can_change_the_revision_number(self, revision_set_fixture): # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - ('created', datetime(2012, 11, 17, 16, 37, 40)), - ('last_printed', datetime(2014, 6, 4, 4, 28)), - ('modified', None), - ]) + @pytest.fixture( + params=[ + ("created", datetime(2012, 11, 17, 16, 37, 40)), + ("last_printed", datetime(2014, 6, 4, 4, 28)), + ("modified", None), + ] + ) def date_prop_get_fixture(self, request, core_properties): prop_name, expected_datetime = request.param return core_properties, prop_name, expected_datetime - @pytest.fixture(params=[ - ('created', 'dcterms:created', datetime(2001, 2, 3, 4, 5), - '2001-02-03T04:05:00Z', ' xsi:type="dcterms:W3CDTF"'), - ('last_printed', 'cp:lastPrinted', datetime(2014, 6, 4, 4), - '2014-06-04T04:00:00Z', ''), - ('modified', 'dcterms:modified', datetime(2005, 4, 3, 2, 1), - '2005-04-03T02:01:00Z', ' xsi:type="dcterms:W3CDTF"'), - ]) + @pytest.fixture( + params=[ + ( + "created", + "dcterms:created", + datetime(2001, 2, 3, 4, 5), + "2001-02-03T04:05:00Z", + ' xsi:type="dcterms:W3CDTF"', + ), + ( + "last_printed", + "cp:lastPrinted", + datetime(2014, 6, 4, 4), + "2014-06-04T04:00:00Z", + "", + ), + ( + "modified", + "dcterms:modified", + datetime(2005, 4, 3, 2, 1), + "2005-04-03T02:01:00Z", + ' xsi:type="dcterms:W3CDTF"', + ), + ] + ) def date_prop_set_fixture(self, request): prop_name, tagname, value, str_val, attrs = request.param coreProperties = self.coreProperties(None, None) @@ -75,56 +89,62 @@ def date_prop_set_fixture(self, request): expected_xml = self.coreProperties(tagname, str_val, attrs) return core_properties, prop_name, value, expected_xml - @pytest.fixture(params=[ - ('42', 42), (None, 0), ('foobar', 0), ('-17', 0), ('32.7', 0) - ]) + @pytest.fixture( + params=[("42", 42), (None, 0), ("foobar", 0), ("-17", 0), ("32.7", 0)] + ) def revision_get_fixture(self, request): str_val, expected_revision = request.param - tagname = '' if str_val is None else 'cp:revision' + tagname = "" if str_val is None else "cp:revision" coreProperties = self.coreProperties(tagname, str_val) core_properties = CoreProperties(parse_xml(coreProperties)) return core_properties, expected_revision - @pytest.fixture(params=[ - (42, '42'), - ]) + @pytest.fixture( + params=[ + (42, "42"), + ] + ) def revision_set_fixture(self, request): value, str_val = request.param coreProperties = self.coreProperties(None, None) core_properties = CoreProperties(parse_xml(coreProperties)) - expected_xml = self.coreProperties('cp:revision', str_val) + expected_xml = self.coreProperties("cp:revision", str_val) return core_properties, value, expected_xml - @pytest.fixture(params=[ - ('author', 'python-docx'), - ('category', ''), - ('comments', ''), - ('content_status', 'DRAFT'), - ('identifier', 'GXS 10.2.1ab'), - ('keywords', 'foo bar baz'), - ('language', 'US-EN'), - ('last_modified_by', 'Steve Canny'), - ('subject', 'Spam'), - ('title', 'Word Document'), - ('version', '1.2.88'), - ]) + @pytest.fixture( + params=[ + ("author", "python-docx"), + ("category", ""), + ("comments", ""), + ("content_status", "DRAFT"), + ("identifier", "GXS 10.2.1ab"), + ("keywords", "foo bar baz"), + ("language", "US-EN"), + ("last_modified_by", "Steve Canny"), + ("subject", "Spam"), + ("title", "Word Document"), + ("version", "1.2.88"), + ] + ) def text_prop_get_fixture(self, request, core_properties): prop_name, expected_value = request.param return core_properties, prop_name, expected_value - @pytest.fixture(params=[ - ('author', 'dc:creator', 'scanny'), - ('category', 'cp:category', 'silly stories'), - ('comments', 'dc:description', 'Bar foo to you'), - ('content_status', 'cp:contentStatus', 'FINAL'), - ('identifier', 'dc:identifier', 'GT 5.2.xab'), - ('keywords', 'cp:keywords', 'dog cat moo'), - ('language', 'dc:language', 'GB-EN'), - ('last_modified_by', 'cp:lastModifiedBy', 'Billy Bob'), - ('subject', 'dc:subject', 'Eggs'), - ('title', 'dc:title', 'Dissertation'), - ('version', 'cp:version', '81.2.8'), - ]) + @pytest.fixture( + params=[ + ("author", "dc:creator", "scanny"), + ("category", "cp:category", "silly stories"), + ("comments", "dc:description", "Bar foo to you"), + ("content_status", "cp:contentStatus", "FINAL"), + ("identifier", "dc:identifier", "GT 5.2.xab"), + ("keywords", "cp:keywords", "dog cat moo"), + ("language", "dc:language", "GB-EN"), + ("last_modified_by", "cp:lastModifiedBy", "Billy Bob"), + ("subject", "dc:subject", "Eggs"), + ("title", "dc:title", "Dissertation"), + ("version", "cp:version", "81.2.8"), + ] + ) def text_prop_set_fixture(self, request): prop_name, tagname, value = request.param coreProperties = self.coreProperties(None, None) @@ -134,7 +154,7 @@ def text_prop_set_fixture(self, request): # fixture components --------------------------------------------- - def coreProperties(self, tagname, str_val, attrs=''): + def coreProperties(self, tagname, str_val, attrs=""): tmpl = ( '%s\n' ) if not tagname: - child_element = '' + child_element = "" elif not str_val: - child_element = '\n <%s%s/>\n' % (tagname, attrs) + child_element = "\n <%s%s/>\n" % (tagname, attrs) else: - child_element = ( - '\n <%s%s>%s\n' % (tagname, attrs, str_val, tagname) - ) + child_element = "\n <%s%s>%s\n" % (tagname, attrs, str_val, tagname) return tmpl % child_element @pytest.fixture def core_properties(self): element = parse_xml( - b'' + b"" b'\n\n' - b' DRAFT\n' - b' python-docx\n' + b" DRAFT\n" + b" python-docx\n" b' 2012-11-17T11:07:' - b'40-05:30\n' - b' \n' - b' GXS 10.2.1ab\n' - b' US-EN\n' - b' 2014-06-04T04:28:00Z\n' - b' foo bar baz\n' - b' Steve Canny\n' - b' 4\n' - b' Spam\n' - b' Word Document\n' - b' 1.2.88\n' - b'\n' + b"40-05:30\n" + b" \n" + b" GXS 10.2.1ab\n" + b" US-EN\n" + b" 2014-06-04T04:28:00Z\n" + b" foo bar baz\n" + b" Steve Canny\n" + b" 4\n" + b" Spam\n" + b" Word Document\n" + b" 1.2.88\n" + b"\n" ) return CoreProperties(element) diff --git a/tests/opc/test_customprops.py b/tests/opc/test_customprops.py index 8f3482d0..1efae96e 100644 --- a/tests/opc/test_customprops.py +++ b/tests/opc/test_customprops.py @@ -4,9 +4,7 @@ Unit test suite for the docx.opc.customprops module """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals import pytest @@ -17,8 +15,8 @@ from docx.oxml import parse_xml from lxml import etree -class DescribeCustomProperties(object): +class DescribeCustomProperties(object): def it_can_read_existing_prop_values(self, prop_get_fixture): custom_properties, prop_name, exp_value = prop_get_fixture actual_value = custom_properties[prop_name] @@ -34,21 +32,25 @@ def it_can_set_new_prop_values(self, prop_set_fixture): # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - ('CustomPropString', 'Test String'), - ('CustomPropBool', True), - ('CustomPropInt', 13), - ('CustomPropFoo', None), - ]) + @pytest.fixture( + params=[ + ("CustomPropString", "Test String"), + ("CustomPropBool", True), + ("CustomPropInt", 13), + ("CustomPropFoo", None), + ] + ) def prop_get_fixture(self, request, custom_properties_default): prop_name, expected_value = request.param return custom_properties_default, prop_name, expected_value - @pytest.fixture(params=[ - ('CustomPropString', 'lpwstr', 'Hi there!', 'Hi there!'), - ('CustomPropBool', 'bool', '0', False), - ('CustomPropInt', 'i4', '5', 5), - ]) + @pytest.fixture( + params=[ + ("CustomPropString", "lpwstr", "Hi there!", "Hi there!"), + ("CustomPropBool", "bool", "0", False), + ("CustomPropInt", "i4", "5", 5), + ] + ) def prop_set_fixture(self, request, custom_properties_blank): prop_name, str_type, str_value, value = request.param expected_xml = self.customProperties(prop_name, str_type, str_value) @@ -61,18 +63,18 @@ def customProperties(self, prop_name, str_type, str_value): '\n' ' \n' - ' %s\n' - ' \n' - '' + " %s\n" + " \n" + "" ) - return tmpl %(prop_name, str_type, str_value, str_type) + return tmpl % (prop_name, str_type, str_value, str_type) @pytest.fixture def custom_properties_blank(self): element = parse_xml( '' - '\n' + "\n" ) return CustomProperties(element) @@ -85,6 +87,6 @@ def custom_properties_default(self): b' 1\n' b' 13\n' b' Test String\n' - b'\n' + b"\n" ) return CustomProperties(element) diff --git a/tests/opc/test_oxml.py b/tests/opc/test_oxml.py index 79e77c88..c269bde3 100644 --- a/tests/opc/test_oxml.py +++ b/tests/opc/test_oxml.py @@ -6,55 +6,60 @@ from docx.opc.constants import RELATIONSHIP_TARGET_MODE as RTM from docx.opc.oxml import ( - CT_Default, CT_Override, CT_Relationship, CT_Relationships, CT_Types + CT_Default, + CT_Override, + CT_Relationship, + CT_Relationships, + CT_Types, ) from docx.oxml.xmlchemy import serialize_for_reading from .unitdata.rels import ( - a_Default, an_Override, a_Relationship, a_Relationships, a_Types + a_Default, + an_Override, + a_Relationship, + a_Relationships, + a_Types, ) class DescribeCT_Default(object): - def it_provides_read_access_to_xml_values(self): default = a_Default().element - assert default.extension == 'xml' - assert default.content_type == 'application/xml' + assert default.extension == "xml" + assert default.content_type == "application/xml" def it_can_construct_a_new_default_element(self): - default = CT_Default.new('xml', 'application/xml') + default = CT_Default.new("xml", "application/xml") expected_xml = a_Default().xml assert default.xml == expected_xml class DescribeCT_Override(object): - def it_provides_read_access_to_xml_values(self): override = an_Override().element - assert override.partname == '/part/name.xml' - assert override.content_type == 'app/vnd.type' + assert override.partname == "/part/name.xml" + assert override.content_type == "app/vnd.type" def it_can_construct_a_new_override_element(self): - override = CT_Override.new('/part/name.xml', 'app/vnd.type') + override = CT_Override.new("/part/name.xml", "app/vnd.type") expected_xml = an_Override().xml assert override.xml == expected_xml class DescribeCT_Relationship(object): - def it_provides_read_access_to_xml_values(self): rel = a_Relationship().element - assert rel.rId == 'rId9' - assert rel.reltype == 'ReLtYpE' - assert rel.target_ref == 'docProps/core.xml' + assert rel.rId == "rId9" + assert rel.reltype == "ReLtYpE" + assert rel.target_ref == "docProps/core.xml" assert rel.target_mode == RTM.INTERNAL def it_can_construct_from_attribute_values(self): cases = ( - ('rId9', 'ReLtYpE', 'foo/bar.xml', None), - ('rId9', 'ReLtYpE', 'bar/foo.xml', RTM.INTERNAL), - ('rId9', 'ReLtYpE', 'http://some/link', RTM.EXTERNAL), + ("rId9", "ReLtYpE", "foo/bar.xml", None), + ("rId9", "ReLtYpE", "bar/foo.xml", RTM.INTERNAL), + ("rId9", "ReLtYpE", "http://some/link", RTM.EXTERNAL), ) for rId, reltype, target, target_mode in cases: if target_mode is None: @@ -69,7 +74,6 @@ def it_can_construct_from_attribute_values(self): class DescribeCT_Relationships(object): - def it_can_construct_a_new_relationships_element(self): rels = CT_Relationships.new() expected_xml = ( @@ -82,24 +86,23 @@ def it_can_build_rels_element_incrementally(self): # setup ------------------------ rels = CT_Relationships.new() # exercise --------------------- - rels.add_rel('rId1', 'http://reltype1', 'docProps/core.xml') - rels.add_rel('rId2', 'http://linktype', 'http://some/link', True) - rels.add_rel('rId3', 'http://reltype2', '../slides/slide1.xml') + rels.add_rel("rId1", "http://reltype1", "docProps/core.xml") + rels.add_rel("rId2", "http://linktype", "http://some/link", True) + rels.add_rel("rId3", "http://reltype2", "../slides/slide1.xml") # verify ----------------------- expected_rels_xml = a_Relationships().xml assert serialize_for_reading(rels) == expected_rels_xml def it_can_generate_rels_file_xml(self): expected_xml = ( - '\n' + "\n" ''.encode('utf-8') + '/2006/relationships"/>'.encode("utf-8") ) assert CT_Relationships.new().xml == expected_xml class DescribeCT_Types(object): - def it_provides_access_to_default_child_elements(self): types = a_Types().element assert len(types.defaults) == 2 @@ -124,10 +127,10 @@ def it_can_construct_a_new_types_element(self): def it_can_build_types_element_incrementally(self): types = CT_Types.new() - types.add_default('xml', 'application/xml') - types.add_default('jpeg', 'image/jpeg') - types.add_override('/docProps/core.xml', 'app/vnd.type1') - types.add_override('/ppt/presentation.xml', 'app/vnd.type2') - types.add_override('/docProps/thumbnail.jpeg', 'image/jpeg') + types.add_default("xml", "application/xml") + types.add_default("jpeg", "image/jpeg") + types.add_override("/docProps/core.xml", "app/vnd.type1") + types.add_override("/ppt/presentation.xml", "app/vnd.type2") + types.add_override("/docProps/thumbnail.jpeg", "image/jpeg") expected_types_xml = a_Types().xml assert types.xml == expected_types_xml diff --git a/tests/opc/test_package.py b/tests/opc/test_package.py index 8b2de572..e2edb3ae 100644 --- a/tests/opc/test_package.py +++ b/tests/opc/test_package.py @@ -29,22 +29,18 @@ class DescribeOpcPackage(object): - - def it_can_open_a_pkg_file(self, PackageReader_, PartFactory_, - Unmarshaller_): + def it_can_open_a_pkg_file(self, PackageReader_, PartFactory_, Unmarshaller_): # mockery ---------------------- - pkg_file = Mock(name='pkg_file') + pkg_file = Mock(name="pkg_file") pkg_reader = PackageReader_.from_file.return_value # exercise --------------------- pkg = OpcPackage.open(pkg_file) # verify ----------------------- PackageReader_.from_file.assert_called_once_with(pkg_file) - Unmarshaller_.unmarshal.assert_called_once_with(pkg_reader, pkg, - PartFactory_) + Unmarshaller_.unmarshal.assert_called_once_with(pkg_reader, pkg, PartFactory_) assert isinstance(pkg, OpcPackage) - def it_initializes_its_rels_collection_on_first_reference( - self, Relationships_): + def it_initializes_its_rels_collection_on_first_reference(self, Relationships_): pkg = OpcPackage() rels = pkg.rels Relationships_.assert_called_once_with(PACKAGE_URI.baseURI) @@ -56,12 +52,9 @@ def it_can_add_a_relationship_to_a_part(self, pkg_with_rels_, rel_attrs_): # exercise --------------------- pkg.load_rel(reltype, target, rId) # verify ----------------------- - pkg._rels.add_relationship.assert_called_once_with( - reltype, target, rId, False - ) + pkg._rels.add_relationship.assert_called_once_with(reltype, target, rId, False) - def it_can_establish_a_relationship_to_another_part( - self, relate_to_part_fixture_): + def it_can_establish_a_relationship_to_another_part(self, relate_to_part_fixture_): pkg, part_, reltype, rId = relate_to_part_fixture_ _rId = pkg.relate_to(part_, reltype) pkg.rels.get_or_add.assert_called_once_with(reltype, part_) @@ -69,10 +62,10 @@ def it_can_establish_a_relationship_to_another_part( def it_can_provide_a_list_of_the_parts_it_contains(self): # mockery ---------------------- - parts = [Mock(name='part1'), Mock(name='part2')] + parts = [Mock(name="part1"), Mock(name="part2")] pkg = OpcPackage() # verify ----------------------- - with patch.object(OpcPackage, 'iter_parts', return_value=parts): + with patch.object(OpcPackage, "iter_parts", return_value=parts): assert pkg.parts == [parts[0], parts[1]] def it_can_iterate_over_parts_by_walking_rels_graph(self): @@ -84,17 +77,13 @@ def it_can_iterate_over_parts_by_walking_rels_graph(self): # external +--------+ # | part_2 | # +--------+ - part1, part2 = (Mock(name='part1'), Mock(name='part2')) - part1.rels = { - 1: Mock(name='rel1', is_external=False, target_part=part2) - } - part2.rels = { - 1: Mock(name='rel2', is_external=False, target_part=part1) - } + part1, part2 = (Mock(name="part1"), Mock(name="part2")) + part1.rels = {1: Mock(name="rel1", is_external=False, target_part=part2)} + part2.rels = {1: Mock(name="rel2", is_external=False, target_part=part1)} pkg = OpcPackage() pkg._rels = { - 1: Mock(name='rel3', is_external=False, target_part=part1), - 2: Mock(name='rel4', is_external=True), + 1: Mock(name="rel3", is_external=False, target_part=part1), + 2: Mock(name="rel4", is_external=True), } # verify ----------------------- assert part1 in pkg.iter_parts() @@ -121,15 +110,12 @@ def it_can_find_a_part_related_by_reltype(self, related_part_fixture_): pkg.rels.part_with_reltype.assert_called_once_with(reltype) assert related_part is related_part_ - def it_can_save_to_a_pkg_file( - self, pkg_file_, PackageWriter_, parts, parts_): + def it_can_save_to_a_pkg_file(self, pkg_file_, PackageWriter_, parts, parts_): pkg = OpcPackage() pkg.save(pkg_file_) for part in parts_: part.before_marshal.assert_called_once_with() - PackageWriter_.write.assert_called_once_with( - pkg_file_, pkg._rels, parts_ - ) + PackageWriter_.write.assert_called_once_with(pkg_file_, pkg._rels, parts_) def it_provides_access_to_the_core_properties(self, core_props_fixture): opc_package, core_properties_ = core_props_fixture @@ -137,7 +123,8 @@ def it_provides_access_to_the_core_properties(self, core_props_fixture): assert core_properties is core_properties_ def it_provides_access_to_the_core_properties_part_to_help( - self, core_props_part_fixture): + self, core_props_part_fixture + ): opc_package, core_properties_part_ = core_props_part_fixture core_properties_part = opc_package._core_properties_part assert core_properties_part is core_properties_part_ @@ -161,23 +148,20 @@ def it_creates_a_default_core_props_part_if_none_present( @pytest.fixture def core_props_fixture( - self, _core_properties_part_prop_, core_properties_part_, - core_properties_): + self, _core_properties_part_prop_, core_properties_part_, core_properties_ + ): opc_package = OpcPackage() _core_properties_part_prop_.return_value = core_properties_part_ core_properties_part_.core_properties = core_properties_ return opc_package, core_properties_ @pytest.fixture - def core_props_part_fixture( - self, part_related_by_, core_properties_part_): + def core_props_part_fixture(self, part_related_by_, core_properties_part_): opc_package = OpcPackage() part_related_by_.return_value = core_properties_part_ return opc_package, core_properties_part_ - @pytest.fixture( - params=[((), 1), ((1,), 2), ((1, 2), 3), ((2, 3), 1), ((1, 3), 2)] - ) + @pytest.fixture(params=[((), 1), ((1,), 2), ((1, 2), 3), ((2, 3), 1), ((1, 3), 2)]) def next_partname_fixture(self, request, iter_parts_): existing_partname_ns, next_partname_n = request.param parts_ = [ @@ -191,16 +175,16 @@ def next_partname_fixture(self, request, iter_parts_): @pytest.fixture def relate_to_part_fixture_(self, request, pkg, rels_, reltype): - rId = 'rId99' - rel_ = instance_mock(request, _Relationship, name='rel_', rId=rId) + rId = "rId99" + rel_ = instance_mock(request, _Relationship, name="rel_", rId=rId) rels_.get_or_add.return_value = rel_ pkg._rels = rels_ - part_ = instance_mock(request, Part, name='part_') + part_ = instance_mock(request, Part, name="part_") return pkg, part_, reltype, rId @pytest.fixture def related_part_fixture_(self, request, rels_, reltype): - related_part_ = instance_mock(request, Part, name='related_part_') + related_part_ = instance_mock(request, Part, name="related_part_") rels_.part_with_reltype.return_value = related_part_ pkg = OpcPackage() pkg._rels = rels_ @@ -210,7 +194,7 @@ def related_part_fixture_(self, request, rels_, reltype): @pytest.fixture def CorePropertiesPart_(self, request): - return class_mock(request, 'docx.opc.package.CorePropertiesPart') + return class_mock(request, "docx.opc.package.CorePropertiesPart") @pytest.fixture def core_properties_(self, request): @@ -222,7 +206,7 @@ def core_properties_part_(self, request): @pytest.fixture def _core_properties_part_prop_(self, request): - return property_mock(request, OpcPackage, '_core_properties_part') + return property_mock(request, OpcPackage, "_core_properties_part") @pytest.fixture def iter_parts_(self, request): @@ -230,7 +214,7 @@ def iter_parts_(self, request): @pytest.fixture def PackageReader_(self, request): - return class_mock(request, 'docx.opc.package.PackageReader') + return class_mock(request, "docx.opc.package.PackageReader") @pytest.fixture def PackURI_(self, request): @@ -242,15 +226,15 @@ def packuri_(self, request): @pytest.fixture def PackageWriter_(self, request): - return class_mock(request, 'docx.opc.package.PackageWriter') + return class_mock(request, "docx.opc.package.PackageWriter") @pytest.fixture def PartFactory_(self, request): - return class_mock(request, 'docx.opc.package.PartFactory') + return class_mock(request, "docx.opc.package.PartFactory") @pytest.fixture def part_related_by_(self, request): - return method_mock(request, OpcPackage, 'part_related_by') + return method_mock(request, OpcPackage, "part_related_by") @pytest.fixture def parts(self, request, parts_): @@ -259,16 +243,15 @@ def parts(self, request, parts_): patch after each use. """ _patch = patch.object( - OpcPackage, 'parts', new_callable=PropertyMock, - return_value=parts_ + OpcPackage, "parts", new_callable=PropertyMock, return_value=parts_ ) request.addfinalizer(_patch.stop) return _patch.start() @pytest.fixture def parts_(self, request): - part_ = instance_mock(request, Part, name='part_') - part_2_ = instance_mock(request, Part, name='part_2_') + part_ = instance_mock(request, Part, name="part_") + part_2_ = instance_mock(request, Part, name="part_2_") return [part_, part_2_] @pytest.fixture @@ -287,18 +270,18 @@ def pkg_with_rels_(self, request, rels_): @pytest.fixture def Relationships_(self, request): - return class_mock(request, 'docx.opc.package.Relationships') + return class_mock(request, "docx.opc.package.Relationships") @pytest.fixture def rel_attrs_(self, request): - reltype = 'http://rel/type' - target_ = instance_mock(request, Part, name='target_') - rId = 'rId99' + reltype = "http://rel/type" + target_ = instance_mock(request, Part, name="target_") + rId = "rId99" return reltype, target_, rId @pytest.fixture def relate_to_(self, request): - return method_mock(request, OpcPackage, 'relate_to') + return method_mock(request, OpcPackage, "relate_to") @pytest.fixture def rels_(self, request): @@ -306,15 +289,14 @@ def rels_(self, request): @pytest.fixture def reltype(self, request): - return 'http://rel/type' + return "http://rel/type" @pytest.fixture def Unmarshaller_(self, request): - return class_mock(request, 'docx.opc.package.Unmarshaller') + return class_mock(request, "docx.opc.package.Unmarshaller") class DescribeUnmarshaller(object): - def it_can_unmarshal_from_a_pkg_reader( self, pkg_reader_, @@ -336,56 +318,92 @@ def it_can_unmarshal_from_a_pkg_reader( pkg_.after_unmarshal.assert_called_once_with() def it_can_unmarshal_parts( - self, pkg_reader_, pkg_, part_factory_, parts_dict_, partnames_, - content_types_, reltypes_, blobs_): + self, + pkg_reader_, + pkg_, + part_factory_, + parts_dict_, + partnames_, + content_types_, + reltypes_, + blobs_, + ): # fixture ---------------------- partname_, partname_2_ = partnames_ content_type_, content_type_2_ = content_types_ reltype_, reltype_2_ = reltypes_ blob_, blob_2_ = blobs_ # exercise --------------------- - parts = Unmarshaller._unmarshal_parts( - pkg_reader_, pkg_, part_factory_ - ) + parts = Unmarshaller._unmarshal_parts(pkg_reader_, pkg_, part_factory_) # verify ----------------------- - assert ( - part_factory_.call_args_list == [ - call(partname_, content_type_, reltype_, blob_, pkg_), - call(partname_2_, content_type_2_, reltype_2_, blob_2_, pkg_) - ] - ) + assert part_factory_.call_args_list == [ + call(partname_, content_type_, reltype_, blob_, pkg_), + call(partname_2_, content_type_2_, reltype_2_, blob_2_, pkg_), + ] assert parts == parts_dict_ def it_can_unmarshal_relationships(self): # test data -------------------- - reltype = 'http://reltype' + reltype = "http://reltype" # mockery ---------------------- - pkg_reader = Mock(name='pkg_reader') + pkg_reader = Mock(name="pkg_reader") pkg_reader.iter_srels.return_value = ( - ('/', Mock(name='srel1', rId='rId1', reltype=reltype, - target_partname='partname1', is_external=False)), - ('/', Mock(name='srel2', rId='rId2', reltype=reltype, - target_ref='target_ref_1', is_external=True)), - ('partname1', Mock(name='srel3', rId='rId3', reltype=reltype, - target_partname='partname2', is_external=False)), - ('partname2', Mock(name='srel4', rId='rId4', reltype=reltype, - target_ref='target_ref_2', is_external=True)), + ( + "/", + Mock( + name="srel1", + rId="rId1", + reltype=reltype, + target_partname="partname1", + is_external=False, + ), + ), + ( + "/", + Mock( + name="srel2", + rId="rId2", + reltype=reltype, + target_ref="target_ref_1", + is_external=True, + ), + ), + ( + "partname1", + Mock( + name="srel3", + rId="rId3", + reltype=reltype, + target_partname="partname2", + is_external=False, + ), + ), + ( + "partname2", + Mock( + name="srel4", + rId="rId4", + reltype=reltype, + target_ref="target_ref_2", + is_external=True, + ), + ), ) - pkg = Mock(name='pkg') + pkg = Mock(name="pkg") parts = {} for num in range(1, 3): - name = 'part%d' % num + name = "part%d" % num part = Mock(name=name) - parts['partname%d' % num] = part + parts["partname%d" % num] = part pkg.attach_mock(part, name) # exercise --------------------- Unmarshaller._unmarshal_relationships(pkg_reader, pkg, parts) # verify ----------------------- expected_pkg_calls = [ - call.load_rel(reltype, parts['partname1'], 'rId1', False), - call.load_rel(reltype, 'target_ref_1', 'rId2', True), - call.part1.load_rel(reltype, parts['partname2'], 'rId3', False), - call.part2.load_rel(reltype, 'target_ref_2', 'rId4', True), + call.load_rel(reltype, parts["partname1"], "rId1", False), + call.load_rel(reltype, "target_ref_1", "rId2", True), + call.part1.load_rel(reltype, parts["partname2"], "rId3", False), + call.part2.load_rel(reltype, "target_ref_2", "rId4", True), ] assert pkg.mock_calls == expected_pkg_calls @@ -393,14 +411,14 @@ def it_can_unmarshal_relationships(self): @pytest.fixture def blobs_(self, request): - blob_ = loose_mock(request, spec=str, name='blob_') - blob_2_ = loose_mock(request, spec=str, name='blob_2_') + blob_ = loose_mock(request, spec=str, name="blob_") + blob_2_ = loose_mock(request, spec=str, name="blob_2_") return blob_, blob_2_ @pytest.fixture def content_types_(self, request): - content_type_ = loose_mock(request, spec=str, name='content_type_') - content_type_2_ = loose_mock(request, spec=str, name='content_type_2_') + content_type_ = loose_mock(request, spec=str, name="content_type_") + content_type_2_ = loose_mock(request, spec=str, name="content_type_2_") return content_type_, content_type_2_ @pytest.fixture @@ -411,14 +429,14 @@ def part_factory_(self, request, parts_): @pytest.fixture def partnames_(self, request): - partname_ = loose_mock(request, spec=str, name='partname_') - partname_2_ = loose_mock(request, spec=str, name='partname_2_') + partname_ = loose_mock(request, spec=str, name="partname_") + partname_2_ = loose_mock(request, spec=str, name="partname_2_") return partname_, partname_2_ @pytest.fixture def parts_(self, request): - part_ = instance_mock(request, Part, name='part_') - part_2_ = instance_mock(request, Part, name='part_2') + part_ = instance_mock(request, Part, name="part_") + part_2_ = instance_mock(request, Part, name="part_2") return part_, part_2_ @pytest.fixture @@ -432,8 +450,7 @@ def pkg_(self, request): return instance_mock(request, OpcPackage) @pytest.fixture - def pkg_reader_( - self, request, partnames_, content_types_, reltypes_, blobs_): + def pkg_reader_(self, request, partnames_, content_types_, reltypes_, blobs_): partname_, partname_2_ = partnames_ content_type_, content_type_2_ = content_types_ reltype_, reltype_2_ = reltypes_ @@ -448,16 +465,16 @@ def pkg_reader_( @pytest.fixture def reltypes_(self, request): - reltype_ = instance_mock(request, str, name='reltype_') - reltype_2_ = instance_mock(request, str, name='reltype_2') + reltype_ = instance_mock(request, str, name="reltype_") + reltype_2_ = instance_mock(request, str, name="reltype_2") return reltype_, reltype_2_ @pytest.fixture def _unmarshal_parts_(self, request): - return method_mock(request, Unmarshaller, '_unmarshal_parts', autospec=False) + return method_mock(request, Unmarshaller, "_unmarshal_parts", autospec=False) @pytest.fixture def _unmarshal_relationships_(self, request): return method_mock( - request, Unmarshaller, '_unmarshal_relationships', autospec=False + request, Unmarshaller, "_unmarshal_relationships", autospec=False ) diff --git a/tests/opc/test_packuri.py b/tests/opc/test_packuri.py index f2527eba..a56badcd 100644 --- a/tests/opc/test_packuri.py +++ b/tests/opc/test_packuri.py @@ -10,16 +10,15 @@ class DescribePackURI(object): - def cases(self, expected_values): """ Return list of tuples zipped from uri_str cases and *expected_values*. Raise if lengths don't match. """ uri_str_cases = [ - '/', - '/ppt/presentation.xml', - '/ppt/slides/slide1.xml', + "/", + "/ppt/presentation.xml", + "/ppt/slides/slide1.xml", ] if len(expected_values) != len(uri_str_cases): msg = "len(expected_values) differs from len(uri_str_cases)" @@ -28,27 +27,27 @@ def cases(self, expected_values): return zip(pack_uris, expected_values) def it_can_construct_from_relative_ref(self): - baseURI = '/ppt/slides' - relative_ref = '../slideLayouts/slideLayout1.xml' + baseURI = "/ppt/slides" + relative_ref = "../slideLayouts/slideLayout1.xml" pack_uri = PackURI.from_rel_ref(baseURI, relative_ref) - assert pack_uri == '/ppt/slideLayouts/slideLayout1.xml' + assert pack_uri == "/ppt/slideLayouts/slideLayout1.xml" def it_should_raise_on_construct_with_bad_pack_uri_str(self): with pytest.raises(ValueError): - PackURI('foobar') + PackURI("foobar") def it_can_calculate_baseURI(self): - expected_values = ('/', '/ppt', '/ppt/slides') + expected_values = ("/", "/ppt", "/ppt/slides") for pack_uri, expected_baseURI in self.cases(expected_values): assert pack_uri.baseURI == expected_baseURI def it_can_calculate_extension(self): - expected_values = ('', 'xml', 'xml') + expected_values = ("", "xml", "xml") for pack_uri, expected_ext in self.cases(expected_values): assert pack_uri.ext == expected_ext def it_can_calculate_filename(self): - expected_values = ('', 'presentation.xml', 'slide1.xml') + expected_values = ("", "presentation.xml", "slide1.xml") for pack_uri, expected_filename in self.cases(expected_values): assert pack_uri.filename == expected_filename @@ -59,20 +58,26 @@ def it_knows_the_filename_index(self): def it_can_calculate_membername(self): expected_values = ( - '', - 'ppt/presentation.xml', - 'ppt/slides/slide1.xml', + "", + "ppt/presentation.xml", + "ppt/slides/slide1.xml", ) for pack_uri, expected_membername in self.cases(expected_values): assert pack_uri.membername == expected_membername def it_can_calculate_relative_ref_value(self): cases = ( - ('/', '/ppt/presentation.xml', 'ppt/presentation.xml'), - ('/ppt', '/ppt/slideMasters/slideMaster1.xml', - 'slideMasters/slideMaster1.xml'), - ('/ppt/slides', '/ppt/slideLayouts/slideLayout1.xml', - '../slideLayouts/slideLayout1.xml'), + ("/", "/ppt/presentation.xml", "ppt/presentation.xml"), + ( + "/ppt", + "/ppt/slideMasters/slideMaster1.xml", + "slideMasters/slideMaster1.xml", + ), + ( + "/ppt/slides", + "/ppt/slideLayouts/slideLayout1.xml", + "../slideLayouts/slideLayout1.xml", + ), ) for baseURI, uri_str, expected_relative_ref in cases: pack_uri = PackURI(uri_str) @@ -80,9 +85,9 @@ def it_can_calculate_relative_ref_value(self): def it_can_calculate_rels_uri(self): expected_values = ( - '/_rels/.rels', - '/ppt/_rels/presentation.xml.rels', - '/ppt/slides/_rels/slide1.xml.rels', + "/_rels/.rels", + "/ppt/_rels/presentation.xml.rels", + "/ppt/slides/_rels/slide1.xml.rels", ) for pack_uri, expected_rels_uri in self.cases(expected_values): assert pack_uri.rels_uri == expected_rels_uri diff --git a/tests/opc/test_part.py b/tests/opc/test_part.py index 854b8ee6..6de08c95 100644 --- a/tests/opc/test_part.py +++ b/tests/opc/test_part.py @@ -2,8 +2,7 @@ """Unit test suite for docx.opc.part module""" -from __future__ import (absolute_import, division, print_function, - unicode_literals) +from __future__ import absolute_import, division, print_function, unicode_literals import pytest @@ -14,9 +13,16 @@ from docx.oxml.xmlchemy import BaseOxmlElement from ..unitutil.cxml import element -from ..unitutil.mock import (ANY, Mock, class_mock, cls_attr_mock, - function_mock, initializer_mock, instance_mock, - loose_mock) +from ..unitutil.mock import ( + ANY, + Mock, + class_mock, + cls_attr_mock, + function_mock, + initializer_mock, + instance_mock, + loose_mock, +) class DescribePart(object): diff --git a/tests/opc/test_pkgreader.py b/tests/opc/test_pkgreader.py index 96885efc..ac75e836 100644 --- a/tests/opc/test_pkgreader.py +++ b/tests/opc/test_pkgreader.py @@ -33,7 +33,6 @@ class DescribePackageReader(object): - def it_can_construct_from_pkg_file( self, _init_, PhysPkgReader_, from_xml, _srels_for, _load_serialized_parts ): @@ -41,13 +40,13 @@ def it_can_construct_from_pkg_file( content_types = from_xml.return_value pkg_srels = _srels_for.return_value sparts = _load_serialized_parts.return_value - pkg_file = Mock(name='pkg_file') + pkg_file = Mock(name="pkg_file") pkg_reader = PackageReader.from_file(pkg_file) PhysPkgReader_.assert_called_once_with(pkg_file) from_xml.assert_called_once_with(phys_reader.content_types_xml) - _srels_for.assert_called_once_with(phys_reader, '/') + _srels_for.assert_called_once_with(phys_reader, "/") _load_serialized_parts.assert_called_once_with( phys_reader, pkg_srels, content_types ) @@ -62,41 +61,40 @@ def it_can_iterate_over_the_serialized_parts(self, iter_sparts_fixture): def it_can_iterate_over_all_the_srels(self): # mockery ---------------------- - pkg_srels = ['srel1', 'srel2'] + pkg_srels = ["srel1", "srel2"] sparts = [ - Mock(name='spart1', partname='pn1', srels=['srel3', 'srel4']), - Mock(name='spart2', partname='pn2', srels=['srel5', 'srel6']), + Mock(name="spart1", partname="pn1", srels=["srel3", "srel4"]), + Mock(name="spart2", partname="pn2", srels=["srel5", "srel6"]), ] pkg_reader = PackageReader(None, pkg_srels, sparts) # exercise --------------------- generated_tuples = [t for t in pkg_reader.iter_srels()] # verify ----------------------- expected_tuples = [ - ('/', 'srel1'), - ('/', 'srel2'), - ('pn1', 'srel3'), - ('pn1', 'srel4'), - ('pn2', 'srel5'), - ('pn2', 'srel6'), + ("/", "srel1"), + ("/", "srel2"), + ("pn1", "srel3"), + ("pn1", "srel4"), + ("pn2", "srel5"), + ("pn2", "srel6"), ] assert generated_tuples == expected_tuples def it_can_load_serialized_parts(self, _SerializedPart_, _walk_phys_parts): # test data -------------------- test_data = ( - ('/part/name1.xml', 'app/vnd.type_1', 'reltype1', '', - 'srels_1'), - ('/part/name2.xml', 'app/vnd.type_2', 'reltype2', '', - 'srels_2'), + ("/part/name1.xml", "app/vnd.type_1", "reltype1", "", "srels_1"), + ("/part/name2.xml", "app/vnd.type_2", "reltype2", "", "srels_2"), ) iter_vals = [(t[0], t[2], t[3], t[4]) for t in test_data] content_types = dict((t[0], t[1]) for t in test_data) # mockery ---------------------- - phys_reader = Mock(name='phys_reader') - pkg_srels = Mock(name='pkg_srels') + phys_reader = Mock(name="phys_reader") + pkg_srels = Mock(name="pkg_srels") _walk_phys_parts.return_value = iter_vals _SerializedPart_.side_effect = expected_sparts = ( - Mock(name='spart_1'), Mock(name='spart_2') + Mock(name="spart_1"), + Mock(name="spart_2"), ) # exercise --------------------- retval = PackageReader._load_serialized_parts( @@ -104,10 +102,12 @@ def it_can_load_serialized_parts(self, _SerializedPart_, _walk_phys_parts): ) # verify ----------------------- expected_calls = [ - call('/part/name1.xml', 'app/vnd.type_1', '', - 'reltype1', 'srels_1'), - call('/part/name2.xml', 'app/vnd.type_2', '', - 'reltype2', 'srels_2'), + call( + "/part/name1.xml", "app/vnd.type_1", "", "reltype1", "srels_1" + ), + call( + "/part/name2.xml", "app/vnd.type_2", "", "reltype2", "srels_2" + ), ] assert _SerializedPart_.call_args_list == expected_calls assert retval == expected_sparts @@ -123,37 +123,49 @@ def it_can_walk_phys_pkg_parts(self, _srels_for): # | part_2 |---> | part_3 | # +--------+ +--------+ partname_1, partname_2, partname_3 = ( - '/part/name1.xml', '/part/name2.xml', '/part/name3.xml' - ) - part_1_blob, part_2_blob, part_3_blob = ( - '', '', '' + "/part/name1.xml", + "/part/name2.xml", + "/part/name3.xml", ) - reltype1, reltype2, reltype3 = ('reltype1', 'reltype2', 'reltype3') + part_1_blob, part_2_blob, part_3_blob = ("", "", "") + reltype1, reltype2, reltype3 = ("reltype1", "reltype2", "reltype3") srels = [ - Mock(name='rId1', is_external=True), - Mock(name='rId2', is_external=False, reltype=reltype1, - target_partname=partname_1), - Mock(name='rId3', is_external=False, reltype=reltype2, - target_partname=partname_2), - Mock(name='rId4', is_external=False, reltype=reltype1, - target_partname=partname_1), - Mock(name='rId5', is_external=False, reltype=reltype3, - target_partname=partname_3), + Mock(name="rId1", is_external=True), + Mock( + name="rId2", + is_external=False, + reltype=reltype1, + target_partname=partname_1, + ), + Mock( + name="rId3", + is_external=False, + reltype=reltype2, + target_partname=partname_2, + ), + Mock( + name="rId4", + is_external=False, + reltype=reltype1, + target_partname=partname_1, + ), + Mock( + name="rId5", + is_external=False, + reltype=reltype3, + target_partname=partname_3, + ), ] pkg_srels = srels[:2] part_1_srels = srels[2:3] part_2_srels = srels[3:5] part_3_srels = [] # mockery ---------------------- - phys_reader = Mock(name='phys_reader') + phys_reader = Mock(name="phys_reader") _srels_for.side_effect = [part_1_srels, part_2_srels, part_3_srels] - phys_reader.blob_for.side_effect = [ - part_1_blob, part_2_blob, part_3_blob - ] + phys_reader.blob_for.side_effect = [part_1_blob, part_2_blob, part_3_blob] # exercise --------------------- - generated_tuples = list( - PackageReader._walk_phys_parts(phys_reader, pkg_srels) - ) + generated_tuples = list(PackageReader._walk_phys_parts(phys_reader, pkg_srels)) # verify ----------------------- expected_tuples = [ (partname_1, part_1_blob, reltype1, part_1_srels), @@ -162,11 +174,10 @@ def it_can_walk_phys_pkg_parts(self, _srels_for): ] assert generated_tuples == expected_tuples - def it_can_retrieve_srels_for_a_source_uri( - self, _SerializedRelationships_): + def it_can_retrieve_srels_for_a_source_uri(self, _SerializedRelationships_): # mockery ---------------------- - phys_reader = Mock(name='phys_reader') - source_uri = Mock(name='source_uri') + phys_reader = Mock(name="phys_reader") + source_uri = Mock(name="source_uri") rels_xml = phys_reader.rels_xml_for.return_value load_from_xml = _SerializedRelationships_.load_from_xml srels = load_from_xml.return_value @@ -181,19 +192,19 @@ def it_can_retrieve_srels_for_a_source_uri( @pytest.fixture def blobs_(self, request): - blob_ = loose_mock(request, spec=str, name='blob_') - blob_2_ = loose_mock(request, spec=str, name='blob_2_') + blob_ = loose_mock(request, spec=str, name="blob_") + blob_2_ = loose_mock(request, spec=str, name="blob_2_") return blob_, blob_2_ @pytest.fixture def content_types_(self, request): - content_type_ = loose_mock(request, spec=str, name='content_type_') - content_type_2_ = loose_mock(request, spec=str, name='content_type_2_') + content_type_ = loose_mock(request, spec=str, name="content_type_") + content_type_2_ = loose_mock(request, spec=str, name="content_type_2_") return content_type_, content_type_2_ @pytest.fixture def from_xml(self, request): - return method_mock(request, _ContentTypeMap, 'from_xml', autospec=False) + return method_mock(request, _ContentTypeMap, "from_xml", autospec=False) @pytest.fixture def _init_(self, request): @@ -201,7 +212,8 @@ def _init_(self, request): @pytest.fixture def iter_sparts_fixture( - self, sparts_, partnames_, content_types_, reltypes_, blobs_): + self, sparts_, partnames_, content_types_, reltypes_, blobs_ + ): pkg_reader = PackageReader(None, None, sparts_) expected_iter_spart_items = [ (partnames_[0], content_types_[0], reltypes_[0], blobs_[0]), @@ -212,138 +224,140 @@ def iter_sparts_fixture( @pytest.fixture def _load_serialized_parts(self, request): return method_mock( - request, PackageReader, '_load_serialized_parts', autospec=False + request, PackageReader, "_load_serialized_parts", autospec=False ) @pytest.fixture def partnames_(self, request): - partname_ = loose_mock(request, spec=str, name='partname_') - partname_2_ = loose_mock(request, spec=str, name='partname_2_') + partname_ = loose_mock(request, spec=str, name="partname_") + partname_2_ = loose_mock(request, spec=str, name="partname_2_") return partname_, partname_2_ @pytest.fixture def PhysPkgReader_(self, request): - _patch = patch( - 'docx.opc.pkgreader.PhysPkgReader', spec_set=_ZipPkgReader - ) + _patch = patch("docx.opc.pkgreader.PhysPkgReader", spec_set=_ZipPkgReader) request.addfinalizer(_patch.stop) return _patch.start() @pytest.fixture def reltypes_(self, request): - reltype_ = instance_mock(request, str, name='reltype_') - reltype_2_ = instance_mock(request, str, name='reltype_2') + reltype_ = instance_mock(request, str, name="reltype_") + reltype_2_ = instance_mock(request, str, name="reltype_2") return reltype_, reltype_2_ @pytest.fixture def _SerializedPart_(self, request): - return class_mock(request, 'docx.opc.pkgreader._SerializedPart') + return class_mock(request, "docx.opc.pkgreader._SerializedPart") @pytest.fixture def _SerializedRelationships_(self, request): - return class_mock( - request, 'docx.opc.pkgreader._SerializedRelationships' - ) + return class_mock(request, "docx.opc.pkgreader._SerializedRelationships") @pytest.fixture - def sparts_( - self, request, partnames_, content_types_, reltypes_, blobs_): + def sparts_(self, request, partnames_, content_types_, reltypes_, blobs_): sparts_ = [] for idx in range(2): - name = 'spart_%s' % (('%d_' % (idx+1)) if idx else '') + name = "spart_%s" % (("%d_" % (idx + 1)) if idx else "") spart_ = instance_mock( - request, _SerializedPart, name=name, - partname=partnames_[idx], content_type=content_types_[idx], - reltype=reltypes_[idx], blob=blobs_[idx] + request, + _SerializedPart, + name=name, + partname=partnames_[idx], + content_type=content_types_[idx], + reltype=reltypes_[idx], + blob=blobs_[idx], ) sparts_.append(spart_) return sparts_ @pytest.fixture def _srels_for(self, request): - return method_mock(request, PackageReader, '_srels_for', autospec=False) + return method_mock(request, PackageReader, "_srels_for", autospec=False) @pytest.fixture def _walk_phys_parts(self, request): - return method_mock(request, PackageReader, '_walk_phys_parts', autospec=False) + return method_mock(request, PackageReader, "_walk_phys_parts", autospec=False) class Describe_ContentTypeMap(object): - def it_can_construct_from_ct_item_xml(self, from_xml_fixture): - content_types_xml, expected_defaults, expected_overrides = ( - from_xml_fixture - ) + content_types_xml, expected_defaults, expected_overrides = from_xml_fixture ct_map = _ContentTypeMap.from_xml(content_types_xml) assert ct_map._defaults == expected_defaults assert ct_map._overrides == expected_overrides def it_matches_an_override_on_case_insensitive_partname( - self, match_override_fixture): + self, match_override_fixture + ): ct_map, partname, content_type = match_override_fixture assert ct_map[partname] == content_type def it_falls_back_to_case_insensitive_extension_default_match( - self, match_default_fixture): + self, match_default_fixture + ): ct_map, partname, content_type = match_default_fixture assert ct_map[partname] == content_type def it_should_raise_on_partname_not_found(self): ct_map = _ContentTypeMap() with pytest.raises(KeyError): - ct_map[PackURI('/!blat/rhumba.1x&')] + ct_map[PackURI("/!blat/rhumba.1x&")] def it_should_raise_on_key_not_instance_of_PackURI(self): ct_map = _ContentTypeMap() - ct_map._overrides = {PackURI('/part/name1.xml'): 'app/vnd.type1'} + ct_map._overrides = {PackURI("/part/name1.xml"): "app/vnd.type1"} with pytest.raises(KeyError): - ct_map['/part/name1.xml'] + ct_map["/part/name1.xml"] # fixtures --------------------------------------------- @pytest.fixture def from_xml_fixture(self): entries = ( - ('Default', 'xml', CT.XML), - ('Default', 'PNG', CT.PNG), - ('Override', '/ppt/presentation.xml', CT.PML_PRESENTATION_MAIN), + ("Default", "xml", CT.XML), + ("Default", "PNG", CT.PNG), + ("Override", "/ppt/presentation.xml", CT.PML_PRESENTATION_MAIN), ) content_types_xml = self._xml_from(entries) expected_defaults = {} expected_overrides = {} for entry in entries: - if entry[0] == 'Default': + if entry[0] == "Default": ext = entry[1].lower() content_type = entry[2] expected_defaults[ext] = content_type - elif entry[0] == 'Override': + elif entry[0] == "Override": partname, content_type = entry[1:] expected_overrides[partname] = content_type return content_types_xml, expected_defaults, expected_overrides - @pytest.fixture(params=[ - ('/foo/bar.xml', 'xml', 'application/xml'), - ('/foo/bar.PNG', 'png', 'image/png'), - ('/foo/bar.jpg', 'JPG', 'image/jpeg'), - ]) + @pytest.fixture( + params=[ + ("/foo/bar.xml", "xml", "application/xml"), + ("/foo/bar.PNG", "png", "image/png"), + ("/foo/bar.jpg", "JPG", "image/jpeg"), + ] + ) def match_default_fixture(self, request): partname_str, ext, content_type = request.param partname = PackURI(partname_str) ct_map = _ContentTypeMap() - ct_map._add_override(PackURI('/bar/foo.xyz'), 'application/xyz') + ct_map._add_override(PackURI("/bar/foo.xyz"), "application/xyz") ct_map._add_default(ext, content_type) return ct_map, partname, content_type - @pytest.fixture(params=[ - ('/foo/bar.xml', '/foo/bar.xml'), - ('/foo/bar.xml', '/FOO/Bar.XML'), - ('/FoO/bAr.XmL', '/foo/bar.xml'), - ]) + @pytest.fixture( + params=[ + ("/foo/bar.xml", "/foo/bar.xml"), + ("/foo/bar.xml", "/FOO/Bar.XML"), + ("/FoO/bAr.XmL", "/foo/bar.xml"), + ] + ) def match_override_fixture(self, request): partname_str, should_match_partname_str = request.param partname = PackURI(partname_str) should_match_partname = PackURI(should_match_partname_str) - content_type = 'appl/vnd-foobar' + content_type = "appl/vnd-foobar" ct_map = _ContentTypeMap() ct_map._add_override(partname, content_type) return ct_map, should_match_partname, content_type @@ -354,13 +368,13 @@ def _xml_from(self, entries): """ types_bldr = a_Types().with_nsdecls() for entry in entries: - if entry[0] == 'Default': + if entry[0] == "Default": ext, content_type = entry[1:] default_bldr = a_Default() default_bldr.with_Extension(ext) default_bldr.with_ContentType(content_type) types_bldr.with_child(default_bldr) - elif entry[0] == 'Override': + elif entry[0] == "Override": partname, content_type = entry[1:] override_bldr = an_Override() override_bldr.with_PartName(partname) @@ -370,14 +384,13 @@ def _xml_from(self, entries): class Describe_SerializedPart(object): - def it_remembers_construction_values(self): # test data -------------------- - partname = '/part/name.xml' - content_type = 'app/vnd.type' - reltype = 'http://rel/type' - blob = '' - srels = 'srels proxy' + partname = "/part/name.xml" + content_type = "app/vnd.type" + reltype = "http://rel/type" + blob = "" + srels = "srels proxy" # exercise --------------------- spart = _SerializedPart(partname, content_type, reltype, blob, srels) # verify ----------------------- @@ -389,42 +402,57 @@ def it_remembers_construction_values(self): class Describe_SerializedRelationship(object): - def it_remembers_construction_values(self): # test data -------------------- rel_elm = Mock( - name='rel_elm', rId='rId9', reltype='ReLtYpE', - target_ref='docProps/core.xml', target_mode=RTM.INTERNAL + name="rel_elm", + rId="rId9", + reltype="ReLtYpE", + target_ref="docProps/core.xml", + target_mode=RTM.INTERNAL, ) # exercise --------------------- - srel = _SerializedRelationship('/', rel_elm) + srel = _SerializedRelationship("/", rel_elm) # verify ----------------------- - assert srel.rId == 'rId9' - assert srel.reltype == 'ReLtYpE' - assert srel.target_ref == 'docProps/core.xml' + assert srel.rId == "rId9" + assert srel.reltype == "ReLtYpE" + assert srel.target_ref == "docProps/core.xml" assert srel.target_mode == RTM.INTERNAL def it_knows_when_it_is_external(self): - cases = (RTM.INTERNAL, RTM.EXTERNAL, 'FOOBAR') + cases = (RTM.INTERNAL, RTM.EXTERNAL, "FOOBAR") expected_values = (False, True, False) for target_mode, expected_value in zip(cases, expected_values): - rel_elm = Mock(name='rel_elm', rId=None, reltype=None, - target_ref=None, target_mode=target_mode) + rel_elm = Mock( + name="rel_elm", + rId=None, + reltype=None, + target_ref=None, + target_mode=target_mode, + ) srel = _SerializedRelationship(None, rel_elm) assert srel.is_external is expected_value def it_can_calculate_its_target_partname(self): # test data -------------------- cases = ( - ('/', 'docProps/core.xml', '/docProps/core.xml'), - ('/ppt', 'viewProps.xml', '/ppt/viewProps.xml'), - ('/ppt/slides', '../slideLayouts/slideLayout1.xml', - '/ppt/slideLayouts/slideLayout1.xml'), + ("/", "docProps/core.xml", "/docProps/core.xml"), + ("/ppt", "viewProps.xml", "/ppt/viewProps.xml"), + ( + "/ppt/slides", + "../slideLayouts/slideLayout1.xml", + "/ppt/slideLayouts/slideLayout1.xml", + ), ) for baseURI, target_ref, expected_partname in cases: # setup -------------------- - rel_elm = Mock(name='rel_elm', rId=None, reltype=None, - target_ref=target_ref, target_mode=RTM.INTERNAL) + rel_elm = Mock( + name="rel_elm", + rId=None, + reltype=None, + target_ref=target_ref, + target_mode=RTM.INTERNAL, + ) # exercise ----------------- srel = _SerializedRelationship(baseURI, rel_elm) # verify ------------------- @@ -432,29 +460,30 @@ def it_can_calculate_its_target_partname(self): def it_raises_on_target_partname_when_external(self): rel_elm = Mock( - name='rel_elm', rId='rId9', reltype='ReLtYpE', - target_ref='docProps/core.xml', target_mode=RTM.EXTERNAL + name="rel_elm", + rId="rId9", + reltype="ReLtYpE", + target_ref="docProps/core.xml", + target_mode=RTM.EXTERNAL, ) - srel = _SerializedRelationship('/', rel_elm) + srel = _SerializedRelationship("/", rel_elm) with pytest.raises(ValueError): srel.target_partname class Describe_SerializedRelationships(object): - def it_can_load_from_xml(self, parse_xml_, _SerializedRelationship_): # mockery ---------------------- baseURI, rels_item_xml, rel_elm_1, rel_elm_2 = ( - Mock(name='baseURI'), Mock(name='rels_item_xml'), - Mock(name='rel_elm_1'), Mock(name='rel_elm_2'), - ) - rels_elm = Mock( - name='rels_elm', Relationship_lst=[rel_elm_1, rel_elm_2] + Mock(name="baseURI"), + Mock(name="rels_item_xml"), + Mock(name="rel_elm_1"), + Mock(name="rel_elm_2"), ) + rels_elm = Mock(name="rels_elm", Relationship_lst=[rel_elm_1, rel_elm_2]) parse_xml_.return_value = rels_elm # exercise --------------------- - srels = _SerializedRelationships.load_from_xml( - baseURI, rels_item_xml) + srels = _SerializedRelationships.load_from_xml(baseURI, rels_item_xml) # verify ----------------------- expected_calls = [ call(baseURI, rel_elm_1), @@ -477,10 +506,8 @@ def it_should_be_iterable(self): @pytest.fixture def parse_xml_(self, request): - return function_mock(request, 'docx.opc.pkgreader.parse_xml') + return function_mock(request, "docx.opc.pkgreader.parse_xml") @pytest.fixture def _SerializedRelationship_(self, request): - return class_mock( - request, 'docx.opc.pkgreader._SerializedRelationship' - ) + return class_mock(request, "docx.opc.pkgreader._SerializedRelationship") diff --git a/tests/opc/test_pkgwriter.py b/tests/opc/test_pkgwriter.py index d119748d..25bcadb4 100644 --- a/tests/opc/test_pkgwriter.py +++ b/tests/opc/test_pkgwriter.py @@ -14,17 +14,22 @@ from .unitdata.types import a_Default, a_Types, an_Override from ..unitutil.mock import ( - call, class_mock, instance_mock, MagicMock, method_mock, Mock, patch + call, + class_mock, + instance_mock, + MagicMock, + method_mock, + Mock, + patch, ) class DescribePackageWriter(object): - def it_can_write_a_package(self, PhysPkgWriter_, _write_methods): # mockery ---------------------- - pkg_file = Mock(name='pkg_file') - pkg_rels = Mock(name='pkg_rels') - parts = Mock(name='parts') + pkg_file = Mock(name="pkg_file") + pkg_rels = Mock(name="pkg_rels") + parts = Mock(name="parts") phys_writer = PhysPkgWriter_.return_value # exercise --------------------- PackageWriter.write(pkg_file, pkg_rels, parts) @@ -39,32 +44,27 @@ def it_can_write_a_package(self, PhysPkgWriter_, _write_methods): phys_writer.close.assert_called_once_with() def it_can_write_a_content_types_stream(self, write_cti_fixture): - _ContentTypesItem_, parts_, phys_pkg_writer_, blob_ = ( - write_cti_fixture - ) + _ContentTypesItem_, parts_, phys_pkg_writer_, blob_ = write_cti_fixture PackageWriter._write_content_types_stream(phys_pkg_writer_, parts_) _ContentTypesItem_.from_parts.assert_called_once_with(parts_) - phys_pkg_writer_.write.assert_called_once_with( - '/[Content_Types].xml', blob_ - ) + phys_pkg_writer_.write.assert_called_once_with("/[Content_Types].xml", blob_) def it_can_write_a_pkg_rels_item(self): # mockery ---------------------- - phys_writer = Mock(name='phys_writer') - pkg_rels = Mock(name='pkg_rels') + phys_writer = Mock(name="phys_writer") + pkg_rels = Mock(name="pkg_rels") # exercise --------------------- PackageWriter._write_pkg_rels(phys_writer, pkg_rels) # verify ----------------------- - phys_writer.write.assert_called_once_with('/_rels/.rels', - pkg_rels.xml) + phys_writer.write.assert_called_once_with("/_rels/.rels", pkg_rels.xml) def it_can_write_a_list_of_parts(self): # mockery ---------------------- - phys_writer = Mock(name='phys_writer') - rels = MagicMock(name='rels') + phys_writer = Mock(name="phys_writer") + rels = MagicMock(name="rels") rels.__len__.return_value = 1 - part1 = Mock(name='part1', _rels=rels) - part2 = Mock(name='part2', _rels=[]) + part1 = Mock(name="part1", _rels=rels) + part2 = Mock(name="part2", _rels=[]) # exercise --------------------- PackageWriter._write_parts(phys_writer, [part1, part2]) # verify ----------------------- @@ -87,9 +87,7 @@ def cti_(self, request, blob_): @pytest.fixture def _ContentTypesItem_(self, request, cti_): - _ContentTypesItem_ = class_mock( - request, 'docx.opc.pkgwriter._ContentTypesItem' - ) + _ContentTypesItem_ = class_mock(request, "docx.opc.pkgwriter._ContentTypesItem") _ContentTypesItem_.from_parts.return_value = cti_ return _ContentTypesItem_ @@ -99,7 +97,7 @@ def parts_(self, request): @pytest.fixture def PhysPkgWriter_(self, request): - _patch = patch('docx.opc.pkgwriter.PhysPkgWriter') + _patch = patch("docx.opc.pkgwriter.PhysPkgWriter") request.addfinalizer(_patch.stop) return _patch.start() @@ -108,20 +106,19 @@ def phys_pkg_writer_(self, request): return instance_mock(request, _ZipPkgWriter) @pytest.fixture - def write_cti_fixture( - self, _ContentTypesItem_, parts_, phys_pkg_writer_, blob_): + def write_cti_fixture(self, _ContentTypesItem_, parts_, phys_pkg_writer_, blob_): return _ContentTypesItem_, parts_, phys_pkg_writer_, blob_ @pytest.fixture def _write_methods(self, request): """Mock that patches all the _write_* methods of PackageWriter""" - root_mock = Mock(name='PackageWriter') - patch1 = patch.object(PackageWriter, '_write_content_types_stream') - patch2 = patch.object(PackageWriter, '_write_pkg_rels') - patch3 = patch.object(PackageWriter, '_write_parts') - root_mock.attach_mock(patch1.start(), '_write_content_types_stream') - root_mock.attach_mock(patch2.start(), '_write_pkg_rels') - root_mock.attach_mock(patch3.start(), '_write_parts') + root_mock = Mock(name="PackageWriter") + patch1 = patch.object(PackageWriter, "_write_content_types_stream") + patch2 = patch.object(PackageWriter, "_write_pkg_rels") + patch3 = patch.object(PackageWriter, "_write_parts") + root_mock.attach_mock(patch1.start(), "_write_content_types_stream") + root_mock.attach_mock(patch2.start(), "_write_pkg_rels") + root_mock.attach_mock(patch3.start(), "_write_parts") def fin(): patch1.stop() @@ -133,11 +130,10 @@ def fin(): @pytest.fixture def xml_for_(self, request): - return method_mock(request, _ContentTypesItem, 'xml_for') + return method_mock(request, _ContentTypesItem, "xml_for") class Describe_ContentTypesItem(object): - def it_can_compose_content_types_element(self, xml_for_fixture): cti, expected_xml = xml_for_fixture types_elm = cti._element @@ -148,41 +144,41 @@ def it_can_compose_content_types_element(self, xml_for_fixture): def _mock_part(self, request, name, partname_str, content_type): partname = PackURI(partname_str) return instance_mock( - request, Part, name=name, partname=partname, - content_type=content_type + request, Part, name=name, partname=partname, content_type=content_type ) - @pytest.fixture(params=[ - ('Default', '/ppt/MEDIA/image.PNG', CT.PNG), - ('Default', '/ppt/media/image.xml', CT.XML), - ('Default', '/ppt/media/image.rels', CT.OPC_RELATIONSHIPS), - ('Default', '/ppt/media/image.jpeg', CT.JPEG), - ('Override', '/docProps/core.xml', 'app/vnd.core'), - ('Override', '/ppt/slides/slide1.xml', 'app/vnd.ct_sld'), - ('Override', '/zebra/foo.bar', 'app/vnd.foobar'), - ]) + @pytest.fixture( + params=[ + ("Default", "/ppt/MEDIA/image.PNG", CT.PNG), + ("Default", "/ppt/media/image.xml", CT.XML), + ("Default", "/ppt/media/image.rels", CT.OPC_RELATIONSHIPS), + ("Default", "/ppt/media/image.jpeg", CT.JPEG), + ("Override", "/docProps/core.xml", "app/vnd.core"), + ("Override", "/ppt/slides/slide1.xml", "app/vnd.ct_sld"), + ("Override", "/zebra/foo.bar", "app/vnd.foobar"), + ] + ) def xml_for_fixture(self, request): elm_type, partname_str, content_type = request.param - part_ = self._mock_part(request, 'part_', partname_str, content_type) + part_ = self._mock_part(request, "part_", partname_str, content_type) cti = _ContentTypesItem.from_parts([part_]) # expected_xml ----------------- types_bldr = a_Types().with_nsdecls() - ext = partname_str.split('.')[-1].lower() - if elm_type == 'Default' and ext not in ('rels', 'xml'): + ext = partname_str.split(".")[-1].lower() + if elm_type == "Default" and ext not in ("rels", "xml"): default_bldr = a_Default() default_bldr.with_Extension(ext) default_bldr.with_ContentType(content_type) types_bldr.with_child(default_bldr) types_bldr.with_child( - a_Default().with_Extension('rels') - .with_ContentType(CT.OPC_RELATIONSHIPS) + a_Default().with_Extension("rels").with_ContentType(CT.OPC_RELATIONSHIPS) ) types_bldr.with_child( - a_Default().with_Extension('xml').with_ContentType(CT.XML) + a_Default().with_Extension("xml").with_ContentType(CT.XML) ) - if elm_type == 'Override': + if elm_type == "Override": override_bldr = an_Override() override_bldr.with_PartName(partname_str) override_bldr.with_ContentType(content_type) diff --git a/tests/opc/test_rel.py b/tests/opc/test_rel.py index db9b52b5..f6d040a4 100644 --- a/tests/opc/test_rel.py +++ b/tests/opc/test_rel.py @@ -4,9 +4,7 @@ Unit test suite for the docx.opc.rel module """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals import pytest @@ -15,18 +13,15 @@ from docx.opc.part import Part from docx.opc.rel import _Relationship, Relationships -from ..unitutil.mock import ( - call, class_mock, instance_mock, Mock, patch, PropertyMock -) +from ..unitutil.mock import call, class_mock, instance_mock, Mock, patch, PropertyMock class Describe_Relationship(object): - def it_remembers_construction_values(self): # test data -------------------- - rId = 'rId9' - reltype = 'reltype' - target = Mock(name='target_part') + rId = "rId9" + reltype = "reltype" + target = Mock(name="target_part") external = False # exercise --------------------- rel = _Relationship(rId, reltype, target, None, external) @@ -42,8 +37,8 @@ def it_should_raise_on_target_part_access_on_external_rel(self): rel.target_part def it_should_have_target_ref_for_external_rel(self): - rel = _Relationship(None, None, 'target', None, external=True) - assert rel.target_ref == 'target' + rel = _Relationship(None, None, "target", None, external=True) + assert rel.target_ref == "target" def it_should_have_relative_ref_for_internal_rel(self): """ @@ -51,23 +46,24 @@ def it_should_have_relative_ref_for_internal_rel(self): have a relative ref, e.g. '../slideLayouts/slideLayout1.xml', for the target_ref attribute. """ - part = Mock(name='part', partname=PackURI('/ppt/media/image1.png')) - baseURI = '/ppt/slides' + part = Mock(name="part", partname=PackURI("/ppt/media/image1.png")) + baseURI = "/ppt/slides" rel = _Relationship(None, None, part, baseURI) # external=False - assert rel.target_ref == '../media/image1.png' + assert rel.target_ref == "../media/image1.png" class DescribeRelationships(object): - def it_can_add_a_relationship(self, _Relationship_): baseURI, rId, reltype, target, external = ( - 'baseURI', 'rId9', 'reltype', 'target', False + "baseURI", + "rId9", + "reltype", + "target", + False, ) rels = Relationships(baseURI) rel = rels.add_relationship(reltype, target, rId, external) - _Relationship_.assert_called_once_with( - rId, reltype, target, baseURI, external - ) + _Relationship_.assert_called_once_with(rId, reltype, target, baseURI, external) assert rels[rId] == rel assert rel == _Relationship_.return_value @@ -80,13 +76,14 @@ def it_can_add_an_external_relationship(self, add_ext_rel_fixture_): assert rel.reltype == reltype def it_can_find_a_relationship_by_rId(self): - rel = Mock(name='rel', rId='foobar') + rel = Mock(name="rel", rId="foobar") rels = Relationships(None) - rels['foobar'] = rel - assert rels['foobar'] == rel + rels["foobar"] = rel + assert rels["foobar"] == rel def it_can_find_or_add_a_relationship( - self, rels_with_matching_rel_, rels_with_missing_rel_): + self, rels_with_matching_rel_, rels_with_missing_rel_ + ): rels, reltype, part, matching_rel = rels_with_matching_rel_ assert rels.get_or_add(reltype, part) == matching_rel @@ -95,7 +92,8 @@ def it_can_find_or_add_a_relationship( assert rels.get_or_add(reltype, part) == new_rel def it_can_find_or_add_an_external_relationship( - self, add_matching_ext_rel_fixture_): + self, add_matching_ext_rel_fixture_ + ): rels, reltype, url, rId = add_matching_ext_rel_fixture_ _rId = rels.get_or_add_ext_rel(reltype, url) assert _rId == rId @@ -108,10 +106,9 @@ def it_can_find_a_related_part_by_rId(self, rels_with_known_target_part): def it_raises_on_related_part_not_found(self, rels): with pytest.raises(KeyError): - rels.related_parts['rId666'] + rels.related_parts["rId666"] - def it_can_find_a_related_part_by_reltype( - self, rels_with_target_known_by_reltype): + def it_can_find_a_related_part_by_reltype(self, rels_with_target_known_by_reltype): rels, reltype, known_target_part = rels_with_target_known_by_reltype part = rels.part_with_reltype(reltype) assert part is known_target_part @@ -122,15 +119,11 @@ def it_can_compose_rels_xml(self, rels, rels_elm): # verify ----------------------- rels_elm.assert_has_calls( [ - call.add_rel( - 'rId1', 'http://rt-hyperlink', 'http://some/link', True - ), - call.add_rel( - 'rId2', 'http://rt-image', '../media/image1.png', False - ), - call.xml() + call.add_rel("rId1", "http://rt-hyperlink", "http://some/link", True), + call.add_rel("rId2", "http://rt-image", "../media/image1.png", False), + call.xml(), ], - any_order=True + any_order=True, ) def it_knows_the_next_available_rId_to_help(self, rels_with_rId_gap): @@ -147,7 +140,7 @@ def add_ext_rel_fixture_(self, reltype, url): @pytest.fixture def add_matching_ext_rel_fixture_(self, request, reltype, url): - rId = 'rId369' + rId = "rId369" rels = Relationships(None) rels.add_relationship(reltype, url, rId, is_external=True) return rels, reltype, url, rId @@ -156,15 +149,14 @@ def add_matching_ext_rel_fixture_(self, request, reltype, url): @pytest.fixture def _baseURI(self): - return '/baseURI' + return "/baseURI" @pytest.fixture def _Relationship_(self, request): - return class_mock(request, 'docx.opc.rel._Relationship') + return class_mock(request, "docx.opc.rel._Relationship") @pytest.fixture - def _rel_with_target_known_by_reltype( - self, _rId, reltype, _target_part, _baseURI): + def _rel_with_target_known_by_reltype(self, _rId, reltype, _target_part, _baseURI): rel = _Relationship(_rId, reltype, _target_part, _baseURI) return rel, reltype, _target_part @@ -174,15 +166,16 @@ def rels(self): Populated Relationships instance that will exercise the rels.xml property. """ - rels = Relationships('/baseURI') + rels = Relationships("/baseURI") rels.add_relationship( - reltype='http://rt-hyperlink', target='http://some/link', - rId='rId1', is_external=True + reltype="http://rt-hyperlink", + target="http://some/link", + rId="rId1", + is_external=True, ) - part = Mock(name='part') - part.partname.relative_ref.return_value = '../media/image1.png' - rels.add_relationship(reltype='http://rt-image', target=part, - rId='rId2') + part = Mock(name="part") + part.partname.relative_ref.return_value = "../media/image1.png" + rels.add_relationship(reltype="http://rt-image", target=part, rId="rId2") return rels @pytest.fixture @@ -192,20 +185,19 @@ def rels_elm(self, request): CT_Relationships.new() """ # create rels_elm mock with a .xml property - rels_elm = Mock(name='rels_elm') - xml = PropertyMock(name='xml') + rels_elm = Mock(name="rels_elm") + xml = PropertyMock(name="xml") type(rels_elm).xml = xml - rels_elm.attach_mock(xml, 'xml') + rels_elm.attach_mock(xml, "xml") rels_elm.reset_mock() # to clear attach_mock call # patch CT_Relationships to return that rels_elm - patch_ = patch.object(CT_Relationships, 'new', return_value=rels_elm) + patch_ = patch.object(CT_Relationships, "new", return_value=rels_elm) patch_.start() request.addfinalizer(patch_.stop) return rels_elm @pytest.fixture - def _rel_with_known_target_part( - self, _rId, reltype, _target_part, _baseURI): + def _rel_with_known_target_part(self, _rId, reltype, _target_part, _baseURI): rel = _Relationship(_rId, reltype, _target_part, _baseURI) return rel, _rId, _target_part @@ -217,32 +209,30 @@ def rels_with_known_target_part(self, rels, _rel_with_known_target_part): @pytest.fixture def rels_with_matching_rel_(self, request, rels): - matching_reltype_ = instance_mock( - request, str, name='matching_reltype_' - ) - matching_part_ = instance_mock( - request, Part, name='matching_part_' - ) + matching_reltype_ = instance_mock(request, str, name="matching_reltype_") + matching_part_ = instance_mock(request, Part, name="matching_part_") matching_rel_ = instance_mock( - request, _Relationship, name='matching_rel_', - reltype=matching_reltype_, target_part=matching_part_, - is_external=False + request, + _Relationship, + name="matching_rel_", + reltype=matching_reltype_, + target_part=matching_part_, + is_external=False, ) rels[1] = matching_rel_ return rels, matching_reltype_, matching_part_, matching_rel_ @pytest.fixture def rels_with_missing_rel_(self, request, rels, _Relationship_): - missing_reltype_ = instance_mock( - request, str, name='missing_reltype_' - ) - missing_part_ = instance_mock( - request, Part, name='missing_part_' - ) + missing_reltype_ = instance_mock(request, str, name="missing_reltype_") + missing_part_ = instance_mock(request, Part, name="missing_part_") new_rel_ = instance_mock( - request, _Relationship, name='new_rel_', - reltype=missing_reltype_, target_part=missing_part_, - is_external=False + request, + _Relationship, + name="new_rel_", + reltype=missing_reltype_, + target_part=missing_part_, + is_external=False, ) _Relationship_.return_value = new_rel_ return rels, missing_reltype_, missing_part_, new_rel_ @@ -251,29 +241,30 @@ def rels_with_missing_rel_(self, request, rels, _Relationship_): def rels_with_rId_gap(self, request): rels = Relationships(None) rel_with_rId1 = instance_mock( - request, _Relationship, name='rel_with_rId1', rId='rId1' + request, _Relationship, name="rel_with_rId1", rId="rId1" ) rel_with_rId3 = instance_mock( - request, _Relationship, name='rel_with_rId3', rId='rId3' + request, _Relationship, name="rel_with_rId3", rId="rId3" ) - rels['rId1'] = rel_with_rId1 - rels['rId3'] = rel_with_rId3 - return rels, 'rId2' + rels["rId1"] = rel_with_rId1 + rels["rId3"] = rel_with_rId3 + return rels, "rId2" @pytest.fixture def rels_with_target_known_by_reltype( - self, rels, _rel_with_target_known_by_reltype): + self, rels, _rel_with_target_known_by_reltype + ): rel, reltype, target_part = _rel_with_target_known_by_reltype rels[1] = rel return rels, reltype, target_part @pytest.fixture def reltype(self): - return 'http://rel/type' + return "http://rel/type" @pytest.fixture def _rId(self): - return 'rId6' + return "rId6" @pytest.fixture def _target_part(self, request): @@ -281,4 +272,4 @@ def _target_part(self, request): @pytest.fixture def url(self): - return 'https://github.com/scanny/python-docx' + return "https://github.com/scanny/python-docx" diff --git a/tests/opc/unitdata/rels.py b/tests/opc/unitdata/rels.py index 94e45167..73663d18 100644 --- a/tests/opc/unitdata/rels.py +++ b/tests/opc/unitdata/rels.py @@ -17,6 +17,7 @@ class BaseBuilder(object): """ Provides common behavior for all data builders. """ + @property def element(self): """Return element based on XML generated by builder""" @@ -30,9 +31,10 @@ def with_indent(self, indent): class RelationshipsBuilder(object): """Builder class for test Relationships""" + partname_tmpls = { - RT.SLIDE_MASTER: '/ppt/slideMasters/slideMaster%d.xml', - RT.SLIDE: '/ppt/slides/slide%d.xml', + RT.SLIDE_MASTER: "/ppt/slideMasters/slideMaster%d.xml", + RT.SLIDE: "/ppt/slides/slide%d.xml", } def __init__(self): @@ -49,7 +51,7 @@ def _next_partnum(self, reltype): @property def next_rId(self): - rId = 'rId%d' % self.next_rel_num + rId = "rId%d" % self.next_rel_num self.next_rel_num += 1 return rId @@ -70,10 +72,11 @@ class CT_DefaultBuilder(BaseBuilder): Test data builder for CT_Default (Default) XML element that appears in `[Content_Types].xml`. """ + def __init__(self): """Establish instance variables with default values""" - self._content_type = 'application/xml' - self._extension = 'xml' + self._content_type = "application/xml" + self._extension = "xml" self._indent = 0 self._namespace = ' xmlns="%s"' % NS.OPC_CONTENT_TYPES @@ -89,16 +92,15 @@ def with_extension(self, extension): def without_namespace(self): """Don't include an 'xmlns=' attribute""" - self._namespace = '' + self._namespace = "" return self @property def xml(self): """Return Default element""" tmpl = '%s\n' - indent = ' ' * self._indent - return tmpl % (indent, self._namespace, self._extension, - self._content_type) + indent = " " * self._indent + return tmpl % (indent, self._namespace, self._extension, self._content_type) class CT_OverrideBuilder(BaseBuilder): @@ -106,12 +108,13 @@ class CT_OverrideBuilder(BaseBuilder): Test data builder for CT_Override (Override) XML element that appears in `[Content_Types].xml`. """ + def __init__(self): """Establish instance variables with default values""" - self._content_type = 'app/vnd.type' + self._content_type = "app/vnd.type" self._indent = 0 self._namespace = ' xmlns="%s"' % NS.OPC_CONTENT_TYPES - self._partname = '/part/name.xml' + self._partname = "/part/name.xml" def with_content_type(self, content_type): """Set ContentType attribute to *content_type*""" @@ -125,16 +128,15 @@ def with_partname(self, partname): def without_namespace(self): """Don't include an 'xmlns=' attribute""" - self._namespace = '' + self._namespace = "" return self @property def xml(self): """Return Override element""" tmpl = '%s\n' - indent = ' ' * self._indent - return tmpl % (indent, self._namespace, self._partname, - self._content_type) + indent = " " * self._indent + return tmpl % (indent, self._namespace, self._partname, self._content_type) class CT_RelationshipBuilder(BaseBuilder): @@ -142,11 +144,12 @@ class CT_RelationshipBuilder(BaseBuilder): Test data builder for CT_Relationship (Relationship) XML element that appears in .rels files """ + def __init__(self): """Establish instance variables with default values""" - self._rId = 'rId9' - self._reltype = 'ReLtYpE' - self._target = 'docProps/core.xml' + self._rId = "rId9" + self._reltype = "ReLtYpE" + self._target = "docProps/core.xml" self._target_mode = None self._indent = 0 self._namespace = ' xmlns="%s"' % NS.OPC_RELATIONSHIPS @@ -168,27 +171,33 @@ def with_target(self, target): def with_target_mode(self, target_mode): """Set TargetMode attribute to *target_mode*""" - self._target_mode = None if target_mode == 'Internal' else target_mode + self._target_mode = None if target_mode == "Internal" else target_mode return self def without_namespace(self): """Don't include an 'xmlns=' attribute""" - self._namespace = '' + self._namespace = "" return self @property def target_mode(self): if self._target_mode is None: - return '' + return "" return ' TargetMode="%s"' % self._target_mode @property def xml(self): """Return Relationship element""" tmpl = '%s\n' - indent = ' ' * self._indent - return tmpl % (indent, self._namespace, self._rId, self._reltype, - self._target, self.target_mode) + indent = " " * self._indent + return tmpl % ( + indent, + self._namespace, + self._rId, + self._reltype, + self._target, + self.target_mode, + ) class CT_RelationshipsBuilder(BaseBuilder): @@ -196,12 +205,13 @@ class CT_RelationshipsBuilder(BaseBuilder): Test data builder for CT_Relationships (Relationships) XML element, the root element in .rels files. """ + def __init__(self): """Establish instance variables with default values""" self._rels = ( - ('rId1', 'http://reltype1', 'docProps/core.xml', 'Internal'), - ('rId2', 'http://linktype', 'http://some/link', 'External'), - ('rId3', 'http://reltype2', '../slides/slide1.xml', 'Internal'), + ("rId1", "http://reltype1", "docProps/core.xml", "Internal"), + ("rId2", "http://linktype", "http://some/link", "External"), + ("rId3", "http://reltype2", "../slides/slide1.xml", "Internal"), ) @property @@ -211,14 +221,17 @@ def xml(self): """ xml = '\n' % NS.OPC_RELATIONSHIPS for rId, reltype, target, target_mode in self._rels: - xml += (a_Relationship().with_rId(rId) - .with_reltype(reltype) - .with_target(target) - .with_target_mode(target_mode) - .with_indent(2) - .without_namespace() - .xml) - xml += '\n' + xml += ( + a_Relationship() + .with_rId(rId) + .with_reltype(reltype) + .with_target(target) + .with_target_mode(target_mode) + .with_indent(2) + .without_namespace() + .xml + ) + xml += "\n" return xml @@ -227,17 +240,18 @@ class CT_TypesBuilder(BaseBuilder): Test data builder for CT_Types () XML element, the root element in [Content_Types].xml files """ + def __init__(self): """Establish instance variables with default values""" self._defaults = ( - ('xml', 'application/xml'), - ('jpeg', 'image/jpeg'), + ("xml", "application/xml"), + ("jpeg", "image/jpeg"), ) self._empty = False self._overrides = ( - ('/docProps/core.xml', 'app/vnd.type1'), - ('/ppt/presentation.xml', 'app/vnd.type2'), - ('/docProps/thumbnail.jpeg', 'image/jpeg'), + ("/docProps/core.xml", "app/vnd.type1"), + ("/ppt/presentation.xml", "app/vnd.type2"), + ("/docProps/thumbnail.jpeg", "image/jpeg"), ) def empty(self): @@ -254,18 +268,24 @@ def xml(self): xml = '\n' % NS.OPC_CONTENT_TYPES for extension, content_type in self._defaults: - xml += (a_Default().with_extension(extension) - .with_content_type(content_type) - .with_indent(2) - .without_namespace() - .xml) + xml += ( + a_Default() + .with_extension(extension) + .with_content_type(content_type) + .with_indent(2) + .without_namespace() + .xml + ) for partname, content_type in self._overrides: - xml += (an_Override().with_partname(partname) - .with_content_type(content_type) - .with_indent(2) - .without_namespace() - .xml) - xml += '\n' + xml += ( + an_Override() + .with_partname(partname) + .with_content_type(content_type) + .with_indent(2) + .without_namespace() + .xml + ) + xml += "\n" return xml diff --git a/tests/opc/unitdata/types.py b/tests/opc/unitdata/types.py index 82864a96..d5b742b1 100644 --- a/tests/opc/unitdata/types.py +++ b/tests/opc/unitdata/types.py @@ -12,24 +12,24 @@ class CT_DefaultBuilder(BaseBuilder): - __tag__ = 'Default' - __nspfxs__ = ('ct',) - __attrs__ = ('Extension', 'ContentType') + __tag__ = "Default" + __nspfxs__ = ("ct",) + __attrs__ = ("Extension", "ContentType") class CT_OverrideBuilder(BaseBuilder): - __tag__ = 'Override' - __nspfxs__ = ('ct',) - __attrs__ = ('PartName', 'ContentType') + __tag__ = "Override" + __nspfxs__ = ("ct",) + __attrs__ = ("PartName", "ContentType") class CT_TypesBuilder(BaseBuilder): - __tag__ = 'Types' - __nspfxs__ = ('ct',) + __tag__ = "Types" + __nspfxs__ = ("ct",) __attrs__ = () def with_nsdecls(self, *nspfxs): - self._nsdecls = ' xmlns="%s"' % nsmap['ct'] + self._nsdecls = ' xmlns="%s"' % nsmap["ct"] return self diff --git a/tests/oxml/parts/test_document.py b/tests/oxml/parts/test_document.py index aa1bc5b0..707a0dd7 100644 --- a/tests/oxml/parts/test_document.py +++ b/tests/oxml/parts/test_document.py @@ -12,7 +12,6 @@ class DescribeCT_Body(object): - def it_can_clear_all_its_content(self, clear_fixture): body, expected_xml = clear_fixture body.clear_content() @@ -26,13 +25,15 @@ def it_can_add_a_section_break(self, section_break_fixture): # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - ('w:body', 'w:body'), - ('w:body/w:p', 'w:body'), - ('w:body/w:tbl', 'w:body'), - ('w:body/w:sectPr', 'w:body/w:sectPr'), - ('w:body/(w:p, w:sectPr)', 'w:body/w:sectPr'), - ]) + @pytest.fixture( + params=[ + ("w:body", "w:body"), + ("w:body/w:p", "w:body"), + ("w:body/w:tbl", "w:body"), + ("w:body/w:sectPr", "w:body/w:sectPr"), + ("w:body/(w:p, w:sectPr)", "w:body/w:sectPr"), + ] + ) def clear_fixture(self, request): before_cxml, after_cxml = request.param body = element(before_cxml) @@ -41,11 +42,11 @@ def clear_fixture(self, request): @pytest.fixture def section_break_fixture(self): - body = element('w:body/w:sectPr/w:type{w:val=foobar}') + body = element("w:body/w:sectPr/w:type{w:val=foobar}") expected_xml = xml( - 'w:body/(' - ' w:p/w:pPr/w:sectPr/w:type{w:val=foobar},' - ' w:sectPr/w:type{w:val=foobar}' - ')' + "w:body/(" + " w:p/w:pPr/w:sectPr/w:type{w:val=foobar}," + " w:sectPr/w:type{w:val=foobar}" + ")" ) return body, expected_xml diff --git a/tests/oxml/parts/unitdata/document.py b/tests/oxml/parts/unitdata/document.py index 27c6ed40..6dd8efe7 100644 --- a/tests/oxml/parts/unitdata/document.py +++ b/tests/oxml/parts/unitdata/document.py @@ -8,14 +8,14 @@ class CT_BodyBuilder(BaseBuilder): - __tag__ = 'w:body' - __nspfxs__ = ('w',) + __tag__ = "w:body" + __nspfxs__ = ("w",) __attrs__ = () class CT_DocumentBuilder(BaseBuilder): - __tag__ = 'w:document' - __nspfxs__ = ('w',) + __tag__ = "w:document" + __nspfxs__ = ("w",) __attrs__ = () diff --git a/tests/oxml/test__init__.py b/tests/oxml/test__init__.py index 4a4aab6b..85302d64 100644 --- a/tests/oxml/test__init__.py +++ b/tests/oxml/test__init__.py @@ -10,80 +10,71 @@ from lxml import etree -from docx.oxml import ( - OxmlElement, oxml_parser, parse_xml, register_element_cls -) +from docx.oxml import OxmlElement, oxml_parser, parse_xml, register_element_cls from docx.oxml.ns import qn from docx.oxml.shared import BaseOxmlElement class DescribeOxmlElement(object): - def it_returns_an_lxml_element_with_matching_tag_name(self): - element = OxmlElement('a:foo') + element = OxmlElement("a:foo") assert isinstance(element, etree._Element) assert element.tag == ( - '{http://schemas.openxmlformats.org/drawingml/2006/main}foo' + "{http://schemas.openxmlformats.org/drawingml/2006/main}foo" ) def it_adds_supplied_attributes(self): - element = OxmlElement('a:foo', {'a': 'b', 'c': 'd'}) + element = OxmlElement("a:foo", {"a": "b", "c": "d"}) assert etree.tostring(element) == ( '' - ).encode('utf-8') + ).encode("utf-8") def it_adds_additional_namespace_declarations_when_supplied(self): - ns1 = 'http://schemas.openxmlformats.org/drawingml/2006/main' - ns2 = 'other' - element = OxmlElement('a:foo', nsdecls={'a': ns1, 'x': ns2}) + ns1 = "http://schemas.openxmlformats.org/drawingml/2006/main" + ns2 = "other" + element = OxmlElement("a:foo", nsdecls={"a": ns1, "x": ns2}) assert len(element.nsmap.items()) == 2 - assert element.nsmap['a'] == ns1 - assert element.nsmap['x'] == ns2 + assert element.nsmap["a"] == ns1 + assert element.nsmap["x"] == ns2 class DescribeOxmlParser(object): - def it_strips_whitespace_between_elements(self, whitespace_fixture): pretty_xml_text, stripped_xml_text = whitespace_fixture element = etree.fromstring(pretty_xml_text, oxml_parser) - xml_text = etree.tostring(element, encoding='unicode') + xml_text = etree.tostring(element, encoding="unicode") assert xml_text == stripped_xml_text # fixtures ------------------------------------------------------- @pytest.fixture def whitespace_fixture(self): - pretty_xml_text = ( - '\n' - ' text\n' - '\n' - ) - stripped_xml_text = 'text' + pretty_xml_text = "\n" " text\n" "\n" + stripped_xml_text = "text" return pretty_xml_text, stripped_xml_text class DescribeParseXml(object): - def it_accepts_bytes_and_assumes_utf8_encoding(self, xml_bytes): parse_xml(xml_bytes) def it_accepts_unicode_providing_there_is_no_encoding_declaration(self): non_enc_decl = '' enc_decl = '' - xml_body = 'føøbår' + xml_body = "føøbår" # unicode body by itself doesn't raise parse_xml(xml_body) # adding XML decl without encoding attr doesn't raise either - xml_text = '%s\n%s' % (non_enc_decl, xml_body) + xml_text = "%s\n%s" % (non_enc_decl, xml_body) parse_xml(xml_text) # but adding encoding in the declaration raises ValueError - xml_text = '%s\n%s' % (enc_decl, xml_body) + xml_text = "%s\n%s" % (enc_decl, xml_body) with pytest.raises(ValueError): parse_xml(xml_text) def it_uses_registered_element_classes(self, xml_bytes): - register_element_cls('a:foo', CustElmCls) + register_element_cls("a:foo", CustElmCls) element = parse_xml(xml_bytes) assert isinstance(element, CustElmCls) @@ -94,19 +85,17 @@ def xml_bytes(self): return ( '\n' - ' foøbår\n' - '\n' - ).encode('utf-8') + " foøbår\n" + "\n" + ).encode("utf-8") class DescribeRegisterElementCls(object): - - def it_determines_class_used_for_elements_with_matching_tagname( - self, xml_text): - register_element_cls('a:foo', CustElmCls) + def it_determines_class_used_for_elements_with_matching_tagname(self, xml_text): + register_element_cls("a:foo", CustElmCls) foo = parse_xml(xml_text) assert type(foo) is CustElmCls - assert type(foo.find(qn('a:bar'))) is etree._Element + assert type(foo.find(qn("a:bar"))) is etree._Element # fixture components --------------------------------------------- @@ -115,8 +104,8 @@ def xml_text(self): return ( '\n' - ' foøbår\n' - '\n' + " foøbår\n" + "\n" ) @@ -124,5 +113,6 @@ def xml_text(self): # static fixture # =========================================================================== + class CustElmCls(BaseOxmlElement): pass diff --git a/tests/oxml/test_ns.py b/tests/oxml/test_ns.py index d17d9834..413d10bd 100644 --- a/tests/oxml/test_ns.py +++ b/tests/oxml/test_ns.py @@ -12,10 +12,9 @@ class DescribeNamespacePrefixedTag(object): - def it_behaves_like_a_string_when_you_want_it_to(self, nsptag): - s = '- %s -' % nsptag - assert s == '- a:foobar -' + s = "- %s -" % nsptag + assert s == "- a:foobar -" def it_knows_its_clark_name(self, nsptag, clark_name): assert nsptag.clark_name == clark_name @@ -27,13 +26,12 @@ def it_can_construct_from_a_clark_name(self, clark_name, nsptag): def it_knows_its_local_part(self, nsptag, local_part): assert nsptag.local_part == local_part - def it_can_compose_a_single_entry_nsmap_for_itself( - self, nsptag, namespace_uri_a): - expected_nsmap = {'a': namespace_uri_a} + def it_can_compose_a_single_entry_nsmap_for_itself(self, nsptag, namespace_uri_a): + expected_nsmap = {"a": namespace_uri_a} assert nsptag.nsmap == expected_nsmap def it_knows_its_namespace_prefix(self, nsptag): - assert nsptag.nspfx == 'a' + assert nsptag.nspfx == "a" def it_knows_its_namespace_uri(self, nsptag, namespace_uri_a): assert nsptag.nsuri == namespace_uri_a @@ -42,15 +40,15 @@ def it_knows_its_namespace_uri(self, nsptag, namespace_uri_a): @pytest.fixture def clark_name(self, namespace_uri_a, local_part): - return '{%s}%s' % (namespace_uri_a, local_part) + return "{%s}%s" % (namespace_uri_a, local_part) @pytest.fixture def local_part(self): - return 'foobar' + return "foobar" @pytest.fixture def namespace_uri_a(self): - return 'http://schemas.openxmlformats.org/drawingml/2006/main' + return "http://schemas.openxmlformats.org/drawingml/2006/main" @pytest.fixture def nsptag(self, nsptag_str): @@ -58,4 +56,4 @@ def nsptag(self, nsptag_str): @pytest.fixture def nsptag_str(self, local_part): - return 'a:%s' % local_part + return "a:%s" % local_part diff --git a/tests/oxml/test_styles.py b/tests/oxml/test_styles.py index a342323c..0c34f663 100644 --- a/tests/oxml/test_styles.py +++ b/tests/oxml/test_styles.py @@ -4,9 +4,7 @@ Test suite for the docx.oxml.styles module. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals import pytest @@ -16,7 +14,6 @@ class DescribeCT_Styles(object): - def it_can_add_a_style_of_type(self, add_fixture): styles, name, style_type, builtin, expected_xml = add_fixture style = styles.add_style_of_type(name, style_type, builtin) @@ -25,14 +22,26 @@ def it_can_add_a_style_of_type(self, add_fixture): # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - ('w:styles', 'Foo Bar', WD_STYLE_TYPE.LIST, False, - 'w:styles/w:style{w:type=numbering,w:customStyle=1,w:styleId=FooBar' - '}/w:name{w:val=Foo Bar}'), - ('w:styles', 'heading 1', WD_STYLE_TYPE.PARAGRAPH, True, - 'w:styles/w:style{w:type=paragraph,w:styleId=Heading1}/w:name{w:val' - '=heading 1}'), - ]) + @pytest.fixture( + params=[ + ( + "w:styles", + "Foo Bar", + WD_STYLE_TYPE.LIST, + False, + "w:styles/w:style{w:type=numbering,w:customStyle=1,w:styleId=FooBar" + "}/w:name{w:val=Foo Bar}", + ), + ( + "w:styles", + "heading 1", + WD_STYLE_TYPE.PARAGRAPH, + True, + "w:styles/w:style{w:type=paragraph,w:styleId=Heading1}/w:name{w:val" + "=heading 1}", + ), + ] + ) def add_fixture(self, request): styles_cxml, name, style_type, builtin, expected_cxml = request.param styles = element(styles_cxml) diff --git a/tests/oxml/test_table.py b/tests/oxml/test_table.py index 61d8ba1d..bc40b5fb 100644 --- a/tests/oxml/test_table.py +++ b/tests/oxml/test_table.py @@ -16,7 +16,6 @@ class DescribeCT_Row(object): - def it_can_add_a_trPr(self, add_trPr_fixture): tr, expected_xml = add_trPr_fixture tr._add_trPr() @@ -29,12 +28,14 @@ def it_raises_on_tc_at_grid_col(self, tc_raise_fixture): # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - ('w:tr', 'w:tr/w:trPr'), - ('w:tr/w:tblPrEx', 'w:tr/(w:tblPrEx,w:trPr)'), - ('w:tr/w:tc', 'w:tr/(w:trPr,w:tc)'), - ('w:tr/(w:sdt,w:del,w:tc)', 'w:tr/(w:trPr,w:sdt,w:del,w:tc)'), - ]) + @pytest.fixture( + params=[ + ("w:tr", "w:tr/w:trPr"), + ("w:tr/w:tblPrEx", "w:tr/(w:tblPrEx,w:trPr)"), + ("w:tr/w:tc", "w:tr/(w:trPr,w:tc)"), + ("w:tr/(w:sdt,w:del,w:tc)", "w:tr/(w:trPr,w:sdt,w:del,w:tc)"), + ] + ) def add_trPr_fixture(self, request): tr_cxml, expected_cxml = request.param tr = element(tr_cxml) @@ -44,18 +45,17 @@ def add_trPr_fixture(self, request): @pytest.fixture(params=[(0, 0, 3), (1, 0, 1)]) def tc_raise_fixture(self, request): snippet_idx, row_idx, col_idx = request.param - tbl = parse_xml(snippet_seq('tbl-cells')[snippet_idx]) + tbl = parse_xml(snippet_seq("tbl-cells")[snippet_idx]) tr = tbl.tr_lst[row_idx] return tr, col_idx class DescribeCT_Tc(object): - def it_can_merge_to_another_tc( self, tr_, _span_dimensions_, _tbl_, _grow_to_, top_tc_ ): top_tr_ = tr_ - tc, other_tc = element('w:tc'), element('w:tc') + tc, other_tc = element("w:tc"), element("w:tc") top, left, height, width = 0, 1, 2, 3 _span_dimensions_.return_value = top, left, height, width _tbl_.return_value.tr_lst = [tr_] @@ -92,14 +92,15 @@ def it_can_extend_its_horz_span_to_help_merge( self, top_tc_, grid_span_, _move_content_to_, _swallow_next_tc_ ): grid_span_.side_effect = [1, 3, 4] - grid_width, vMerge = 4, 'continue' - tc = element('w:tc') + grid_width, vMerge = 4, "continue" + tc = element("w:tc") tc._span_to_width(grid_width, top_tc_, vMerge) _move_content_to_.assert_called_once_with(tc, top_tc_) assert _swallow_next_tc_.call_args_list == [ - call(tc, grid_width, top_tc_), call(tc, grid_width, top_tc_) + call(tc, grid_width, top_tc_), + call(tc, grid_width, top_tc_), ] assert tc.vMerge == vMerge @@ -131,25 +132,41 @@ def it_raises_on_tr_above(self, tr_above_raise_fixture): # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - # both cells have a width - ('w:tr/(w:tc/(w:tcPr/w:tcW{w:w=1440,w:type=dxa},w:p),' - 'w:tc/(w:tcPr/w:tcW{w:w=1440,w:type=dxa},w:p))', 0, 2, - 'w:tr/(w:tc/(w:tcPr/(w:tcW{w:w=2880,w:type=dxa},' - 'w:gridSpan{w:val=2}),w:p))'), - # neither have a width - ('w:tr/(w:tc/w:p,w:tc/w:p)', 0, 2, - 'w:tr/(w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p))'), - # only second one has a width - ('w:tr/(w:tc/w:p,' - 'w:tc/(w:tcPr/w:tcW{w:w=1440,w:type=dxa},w:p))', 0, 2, - 'w:tr/(w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p))'), - # only first one has a width - ('w:tr/(w:tc/(w:tcPr/w:tcW{w:w=1440,w:type=dxa},w:p),' - 'w:tc/w:p)', 0, 2, - 'w:tr/(w:tc/(w:tcPr/(w:tcW{w:w=1440,w:type=dxa},' - 'w:gridSpan{w:val=2}),w:p))'), - ]) + @pytest.fixture( + params=[ + # both cells have a width + ( + "w:tr/(w:tc/(w:tcPr/w:tcW{w:w=1440,w:type=dxa},w:p)," + "w:tc/(w:tcPr/w:tcW{w:w=1440,w:type=dxa},w:p))", + 0, + 2, + "w:tr/(w:tc/(w:tcPr/(w:tcW{w:w=2880,w:type=dxa}," + "w:gridSpan{w:val=2}),w:p))", + ), + # neither have a width + ( + "w:tr/(w:tc/w:p,w:tc/w:p)", + 0, + 2, + "w:tr/(w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p))", + ), + # only second one has a width + ( + "w:tr/(w:tc/w:p," "w:tc/(w:tcPr/w:tcW{w:w=1440,w:type=dxa},w:p))", + 0, + 2, + "w:tr/(w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p))", + ), + # only first one has a width + ( + "w:tr/(w:tc/(w:tcPr/w:tcW{w:w=1440,w:type=dxa},w:p)," "w:tc/w:p)", + 0, + 2, + "w:tr/(w:tc/(w:tcPr/(w:tcW{w:w=1440,w:type=dxa}," + "w:gridSpan{w:val=2}),w:p))", + ), + ] + ) def add_width_fixture(self, request): tr_cxml, tc_idx, grid_width, expected_tr_cxml = request.param tr = element(tr_cxml) @@ -157,30 +174,42 @@ def add_width_fixture(self, request): expected_tr_xml = xml(expected_tr_cxml) return tc, grid_width, top_tc, tr, expected_tr_xml - @pytest.fixture(params=[ - (0, 0, 0, 'top', 0), (2, 0, 1, 'top', 0), - (2, 1, 1, 'top', 0), (4, 2, 1, 'top', 1), - (0, 0, 0, 'left', 0), (1, 0, 1, 'left', 2), - (3, 1, 0, 'left', 0), (3, 1, 1, 'left', 2), - (0, 0, 0, 'bottom', 1), (1, 0, 0, 'bottom', 1), - (2, 0, 1, 'bottom', 2), (4, 1, 1, 'bottom', 3), - (0, 0, 0, 'right', 1), (1, 0, 0, 'right', 2), - (0, 0, 0, 'right', 1), (4, 2, 1, 'right', 3), - ]) + @pytest.fixture( + params=[ + (0, 0, 0, "top", 0), + (2, 0, 1, "top", 0), + (2, 1, 1, "top", 0), + (4, 2, 1, "top", 1), + (0, 0, 0, "left", 0), + (1, 0, 1, "left", 2), + (3, 1, 0, "left", 0), + (3, 1, 1, "left", 2), + (0, 0, 0, "bottom", 1), + (1, 0, 0, "bottom", 1), + (2, 0, 1, "bottom", 2), + (4, 1, 1, "bottom", 3), + (0, 0, 0, "right", 1), + (1, 0, 0, "right", 2), + (0, 0, 0, "right", 1), + (4, 2, 1, "right", 3), + ] + ) def extents_fixture(self, request): snippet_idx, row, col, attr_name, expected_value = request.param tbl = self._snippet_tbl(snippet_idx) tc = tbl.tr_lst[row].tc_lst[col] return tc, attr_name, expected_value - @pytest.fixture(params=[ - (0, 0, 0, 2, 1), - (0, 0, 1, 1, 2), - (0, 1, 1, 2, 2), - (1, 0, 0, 2, 2), - (2, 0, 0, 2, 2), - (2, 1, 2, 1, 2), - ]) + @pytest.fixture( + params=[ + (0, 0, 0, 2, 1), + (0, 0, 1, 1, 2), + (0, 1, 1, 2, 2), + (1, 0, 0, 2, 2), + (2, 0, 0, 2, 2), + (2, 1, 2, 1, 2), + ] + ) def grow_to_fixture(self, request, _span_to_width_): snippet_idx, row, col, width, height = request.param tbl = self._snippet_tbl(snippet_idx) @@ -189,45 +218,47 @@ def grow_to_fixture(self, request, _span_to_width_): end = start + height expected_calls = [ call(width, tc, None), - call(width, tc, 'restart'), - call(width, tc, 'continue'), - call(width, tc, 'continue'), + call(width, tc, "restart"), + call(width, tc, "continue"), + call(width, tc, "continue"), ][start:end] return tc, width, height, None, expected_calls - @pytest.fixture(params=[ - ('w:tc/w:p', 'w:tc/w:p', - 'w:tc/w:p', 'w:tc/w:p'), - ('w:tc/w:p', 'w:tc/w:p/w:r', - 'w:tc/w:p', 'w:tc/w:p/w:r'), - ('w:tc/w:p/w:r', 'w:tc/w:p', - 'w:tc/w:p', 'w:tc/w:p/w:r'), - ('w:tc/(w:p/w:r,w:sdt)', 'w:tc/w:p', - 'w:tc/w:p', 'w:tc/(w:p/w:r,w:sdt)'), - ('w:tc/(w:p/w:r,w:sdt)', 'w:tc/(w:tbl,w:p)', - 'w:tc/w:p', 'w:tc/(w:tbl,w:p/w:r,w:sdt)'), - ]) + @pytest.fixture( + params=[ + ("w:tc/w:p", "w:tc/w:p", "w:tc/w:p", "w:tc/w:p"), + ("w:tc/w:p", "w:tc/w:p/w:r", "w:tc/w:p", "w:tc/w:p/w:r"), + ("w:tc/w:p/w:r", "w:tc/w:p", "w:tc/w:p", "w:tc/w:p/w:r"), + ("w:tc/(w:p/w:r,w:sdt)", "w:tc/w:p", "w:tc/w:p", "w:tc/(w:p/w:r,w:sdt)"), + ( + "w:tc/(w:p/w:r,w:sdt)", + "w:tc/(w:tbl,w:p)", + "w:tc/w:p", + "w:tc/(w:tbl,w:p/w:r,w:sdt)", + ), + ] + ) def move_fixture(self, request): - tc_cxml, tc_2_cxml, expected_tc_cxml, expected_tc_2_cxml = ( - request.param - ) + tc_cxml, tc_2_cxml, expected_tc_cxml, expected_tc_2_cxml = request.param tc, tc_2 = element(tc_cxml), element(tc_2_cxml) expected_tc_xml = xml(expected_tc_cxml) expected_tc_2_xml = xml(expected_tc_2_cxml) return tc, tc_2, expected_tc_xml, expected_tc_2_xml - @pytest.fixture(params=[ - (0, 0, 0, 0, 1, (0, 0, 1, 2)), - (0, 0, 1, 2, 1, (0, 1, 3, 1)), - (0, 2, 2, 1, 1, (1, 1, 2, 2)), - (0, 1, 2, 1, 0, (1, 0, 1, 3)), - (1, 0, 0, 1, 1, (0, 0, 2, 2)), - (1, 0, 1, 0, 0, (0, 0, 1, 3)), - (2, 0, 1, 2, 1, (0, 1, 3, 1)), - (2, 0, 1, 1, 0, (0, 0, 2, 2)), - (2, 1, 2, 0, 1, (0, 1, 2, 2)), - (4, 0, 1, 0, 0, (0, 0, 1, 3)), - ]) + @pytest.fixture( + params=[ + (0, 0, 0, 0, 1, (0, 0, 1, 2)), + (0, 0, 1, 2, 1, (0, 1, 3, 1)), + (0, 2, 2, 1, 1, (1, 1, 2, 2)), + (0, 1, 2, 1, 0, (1, 0, 1, 3)), + (1, 0, 0, 1, 1, (0, 0, 2, 2)), + (1, 0, 1, 0, 0, (0, 0, 1, 3)), + (2, 0, 1, 2, 1, (0, 1, 3, 1)), + (2, 0, 1, 1, 0, (0, 0, 2, 2)), + (2, 1, 2, 0, 1, (0, 1, 2, 2)), + (4, 0, 1, 0, 0, (0, 0, 1, 3)), + ] + ) def span_fixture(self, request): snippet_idx, row, col, row_2, col_2, expected_value = request.param tbl = self._snippet_tbl(snippet_idx) @@ -235,15 +266,17 @@ def span_fixture(self, request): tc_2 = tbl.tr_lst[row_2].tc_lst[col_2] return tc, tc_2, expected_value - @pytest.fixture(params=[ - (1, 0, 0, 1, 0), # inverted-L horz - (1, 1, 0, 0, 0), # same in opposite order - (2, 0, 2, 0, 1), # inverted-L vert - (5, 0, 1, 1, 0), # tee-shape horz bar - (5, 1, 0, 2, 1), # same, opposite side - (6, 1, 0, 0, 1), # tee-shape vert bar - (6, 0, 1, 1, 2), # same, opposite side - ]) + @pytest.fixture( + params=[ + (1, 0, 0, 1, 0), # inverted-L horz + (1, 1, 0, 0, 0), # same in opposite order + (2, 0, 2, 0, 1), # inverted-L vert + (5, 0, 1, 1, 0), # tee-shape horz bar + (5, 1, 0, 2, 1), # same, opposite side + (6, 1, 0, 0, 1), # tee-shape vert bar + (6, 0, 1, 1, 2), # same, opposite side + ] + ) def span_raise_fixture(self, request): snippet_idx, row, col, row_2, col_2 = request.param tbl = self._snippet_tbl(snippet_idx) @@ -251,19 +284,41 @@ def span_raise_fixture(self, request): tc_2 = tbl.tr_lst[row_2].tc_lst[col_2] return tc, tc_2 - @pytest.fixture(params=[ - ('w:tr/(w:tc/w:p,w:tc/w:p)', 0, 2, - 'w:tr/(w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p))'), - ('w:tr/(w:tc/w:p,w:tc/w:p,w:tc/w:p)', 1, 2, - 'w:tr/(w:tc/w:p,w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p))'), - ('w:tr/(w:tc/w:p/w:r/w:t"a",w:tc/w:p/w:r/w:t"b")', 0, 2, - 'w:tr/(w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p/w:r/w:t"a",' - 'w:p/w:r/w:t"b"))'), - ('w:tr/(w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p),w:tc/w:p)', 0, 3, - 'w:tr/(w:tc/(w:tcPr/w:gridSpan{w:val=3},w:p))'), - ('w:tr/(w:tc/w:p,w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p))', 0, 3, - 'w:tr/(w:tc/(w:tcPr/w:gridSpan{w:val=3},w:p))'), - ]) + @pytest.fixture( + params=[ + ( + "w:tr/(w:tc/w:p,w:tc/w:p)", + 0, + 2, + "w:tr/(w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p))", + ), + ( + "w:tr/(w:tc/w:p,w:tc/w:p,w:tc/w:p)", + 1, + 2, + "w:tr/(w:tc/w:p,w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p))", + ), + ( + 'w:tr/(w:tc/w:p/w:r/w:t"a",w:tc/w:p/w:r/w:t"b")', + 0, + 2, + 'w:tr/(w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p/w:r/w:t"a",' + 'w:p/w:r/w:t"b"))', + ), + ( + "w:tr/(w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p),w:tc/w:p)", + 0, + 3, + "w:tr/(w:tc/(w:tcPr/w:gridSpan{w:val=3},w:p))", + ), + ( + "w:tr/(w:tc/w:p,w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p))", + 0, + 3, + "w:tr/(w:tc/(w:tcPr/w:gridSpan{w:val=3},w:p))", + ), + ] + ) def swallow_fixture(self, request): tr_cxml, tc_idx, grid_width, expected_tr_cxml = request.param tr = element(tr_cxml) @@ -271,10 +326,12 @@ def swallow_fixture(self, request): expected_tr_xml = xml(expected_tr_cxml) return tc, grid_width, top_tc, tr, expected_tr_xml - @pytest.fixture(params=[ - ('w:tr/w:tc/w:p', 0, 2), - ('w:tr/(w:tc/w:p,w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p))', 0, 2), - ]) + @pytest.fixture( + params=[ + ("w:tr/w:tc/w:p", 0, 2), + ("w:tr/(w:tc/w:p,w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p))", 0, 2), + ] + ) def swallow_raise_fixture(self, request): tr_cxml, tc_idx, grid_width = request.param tr = element(tr_cxml) @@ -284,7 +341,7 @@ def swallow_raise_fixture(self, request): @pytest.fixture(params=[(0, 0, 0), (4, 0, 0)]) def tr_above_raise_fixture(self, request): snippet_idx, row_idx, col_idx = request.param - tbl = parse_xml(snippet_seq('tbl-cells')[snippet_idx]) + tbl = parse_xml(snippet_seq("tbl-cells")[snippet_idx]) tc = tbl.tr_lst[row_idx].tc_lst[col_idx] return tc @@ -292,38 +349,38 @@ def tr_above_raise_fixture(self, request): @pytest.fixture def grid_span_(self, request): - return property_mock(request, CT_Tc, 'grid_span') + return property_mock(request, CT_Tc, "grid_span") @pytest.fixture def _grow_to_(self, request): - return method_mock(request, CT_Tc, '_grow_to') + return method_mock(request, CT_Tc, "_grow_to") @pytest.fixture def _move_content_to_(self, request): - return method_mock(request, CT_Tc, '_move_content_to') + return method_mock(request, CT_Tc, "_move_content_to") @pytest.fixture def _span_dimensions_(self, request): - return method_mock(request, CT_Tc, '_span_dimensions') + return method_mock(request, CT_Tc, "_span_dimensions") @pytest.fixture def _span_to_width_(self, request): - return method_mock(request, CT_Tc, '_span_to_width', autospec=False) + return method_mock(request, CT_Tc, "_span_to_width", autospec=False) def _snippet_tbl(self, idx): """ Return a element for snippet at *idx* in 'tbl-cells' snippet file. """ - return parse_xml(snippet_seq('tbl-cells')[idx]) + return parse_xml(snippet_seq("tbl-cells")[idx]) @pytest.fixture def _swallow_next_tc_(self, request): - return method_mock(request, CT_Tc, '_swallow_next_tc') + return method_mock(request, CT_Tc, "_swallow_next_tc") @pytest.fixture def _tbl_(self, request): - return property_mock(request, CT_Tc, '_tbl') + return property_mock(request, CT_Tc, "_tbl") @pytest.fixture def top_tc_(self, request): diff --git a/tests/oxml/test_xmlchemy.py b/tests/oxml/test_xmlchemy.py index 407eaefc..15f68fac 100644 --- a/tests/oxml/test_xmlchemy.py +++ b/tests/oxml/test_xmlchemy.py @@ -14,9 +14,17 @@ from docx.oxml.ns import qn from docx.oxml.simpletypes import BaseIntType from docx.oxml.xmlchemy import ( - BaseOxmlElement, Choice, serialize_for_reading, OneOrMore, OneAndOnlyOne, - OptionalAttribute, RequiredAttribute, ZeroOrMore, ZeroOrOne, - ZeroOrOneChoice, XmlString + BaseOxmlElement, + Choice, + serialize_for_reading, + OneOrMore, + OneAndOnlyOne, + OptionalAttribute, + RequiredAttribute, + ZeroOrMore, + ZeroOrOne, + ZeroOrOneChoice, + XmlString, ) from ..unitdata import BaseBuilder @@ -24,64 +32,71 @@ class DescribeBaseOxmlElement(object): - - def it_can_find_the_first_of_its_children_named_in_a_sequence( - self, first_fixture): + def it_can_find_the_first_of_its_children_named_in_a_sequence(self, first_fixture): element, tagnames, matching_child = first_fixture assert element.first_child_found_in(*tagnames) is matching_child - def it_can_insert_an_element_before_named_successors( - self, insert_fixture): + def it_can_insert_an_element_before_named_successors(self, insert_fixture): element, child, tagnames, expected_xml = insert_fixture element.insert_element_before(child, *tagnames) assert element.xml == expected_xml - def it_can_remove_all_children_with_name_in_sequence( - self, remove_fixture): + def it_can_remove_all_children_with_name_in_sequence(self, remove_fixture): element, tagnames, expected_xml = remove_fixture element.remove_all(*tagnames) assert element.xml == expected_xml # fixtures --------------------------------------------- - @pytest.fixture(params=[ - ('biu', 'iu', 'i'), - ('bu', 'iu', 'u'), - ('bi', 'u', None), - ('b', 'iu', None), - ('iu', 'biu', 'i'), - ('', 'biu', None), - ]) + @pytest.fixture( + params=[ + ("biu", "iu", "i"), + ("bu", "iu", "u"), + ("bi", "u", None), + ("b", "iu", None), + ("iu", "biu", "i"), + ("", "biu", None), + ] + ) def first_fixture(self, request): present, matching, match = request.param element = self.rPr_bldr(present).element tagnames = self.nsptags(matching) - matching_child = element.find(qn('w:%s' % match)) if match else None + matching_child = element.find(qn("w:%s" % match)) if match else None return element, tagnames, matching_child - @pytest.fixture(params=[ - ('iu', 'b', 'iu', 'biu'), - ('u', 'b', 'iu', 'bu'), - ('', 'b', 'iu', 'b'), - ('bu', 'i', 'u', 'biu'), - ('bi', 'u', '', 'biu'), - ]) + @pytest.fixture( + params=[ + ("iu", "b", "iu", "biu"), + ("u", "b", "iu", "bu"), + ("", "b", "iu", "b"), + ("bu", "i", "u", "biu"), + ("bi", "u", "", "biu"), + ] + ) def insert_fixture(self, request): present, new, successors, after = request.param element = self.rPr_bldr(present).element - child = { - 'b': a_b(), 'i': an_i(), 'u': a_u() - }[new].with_nsdecls().element - tagnames = [('w:%s' % char) for char in successors] + child = {"b": a_b(), "i": an_i(), "u": a_u()}[new].with_nsdecls().element + tagnames = [("w:%s" % char) for char in successors] expected_xml = self.rPr_bldr(after).xml() return element, child, tagnames, expected_xml - @pytest.fixture(params=[ - ('biu', 'b', 'iu'), ('biu', 'bi', 'u'), ('bbiiuu', 'i', 'bbuu'), - ('biu', 'i', 'bu'), ('biu', 'bu', 'i'), ('bbiiuu', '', 'bbiiuu'), - ('biu', 'u', 'bi'), ('biu', 'ui', 'b'), ('bbiiuu', 'bi', 'uu'), - ('bu', 'i', 'bu'), ('', 'ui', ''), - ]) + @pytest.fixture( + params=[ + ("biu", "b", "iu"), + ("biu", "bi", "u"), + ("bbiiuu", "i", "bbuu"), + ("biu", "i", "bu"), + ("biu", "bu", "i"), + ("bbiiuu", "", "bbiiuu"), + ("biu", "u", "bi"), + ("biu", "ui", "b"), + ("bbiiuu", "bi", "uu"), + ("bu", "i", "bu"), + ("", "ui", ""), + ] + ) def remove_fixture(self, request): present, remove, after = request.param element = self.rPr_bldr(present).element @@ -92,16 +107,16 @@ def remove_fixture(self, request): # fixture components --------------------------------------------- def nsptags(self, letters): - return [('w:%s' % letter) for letter in letters] + return [("w:%s" % letter) for letter in letters] def rPr_bldr(self, children): rPr_bldr = an_rPr().with_nsdecls() for char in children: - if char == 'b': + if char == "b": rPr_bldr.with_child(a_b()) - elif char == 'i': + elif char == "i": rPr_bldr.with_child(an_i()) - elif char == 'u': + elif char == "u": rPr_bldr.with_child(a_u()) else: raise NotImplementedError("got '%s'" % char) @@ -109,7 +124,6 @@ def rPr_bldr(self, children): class DescribeSerializeForReading(object): - def it_pretty_prints_an_lxml_element(self, pretty_fixture): element, expected_xml_text = pretty_fixture xml_text = serialize_for_reading(element) @@ -124,11 +138,7 @@ def it_returns_unicode_text(self, type_fixture): @pytest.fixture def pretty_fixture(self, element): - expected_xml_text = ( - '\n' - ' text\n' - '\n' - ) + expected_xml_text = "\n" " text\n" "\n" return element, expected_xml_text @pytest.fixture @@ -139,11 +149,10 @@ def type_fixture(self, element): @pytest.fixture def element(self): - return parse_xml('text') + return parse_xml("text") class DescribeXmlString(object): - def it_parses_a_line_to_help_compare(self, parse_fixture): """ This internal function is important to test separately because if it @@ -167,54 +176,67 @@ def it_knows_if_two_xml_lines_are_equivalent(self, xml_line_case): # fixtures --------------------------------------------- - @pytest.fixture(params=[ - ('text', '', 'text'), - ('', '', None), - ('', '', None), - ('t', '', 't'), - ('2013-12-23T23:15:00Z', '', '2013-12-23T23:15:00Z'), - ]) + @pytest.fixture( + params=[ + ("text", "", "text"), + ("", "", None), + ('', "", None), + ("t", "", "t"), + ( + '2013-12-23T23:15:00Z", + "", + "2013-12-23T23:15:00Z", + ), + ] + ) def parse_fixture(self, request): line, front, attrs, close, text = request.param return line, front, attrs, close, text - @pytest.fixture(params=[ - 'simple_elm', 'nsp_tagname', 'indent', 'attrs', 'nsdecl_order', - 'closing_elm', - ]) + @pytest.fixture( + params=[ + "simple_elm", + "nsp_tagname", + "indent", + "attrs", + "nsdecl_order", + "closing_elm", + ] + ) def xml_line_case(self, request): cases = { - 'simple_elm': ( - '', - '', - '', + "simple_elm": ( + "", + "", + "", ), - 'nsp_tagname': ( - '', - '', - '', + "nsp_tagname": ( + "", + "", + "", ), - 'indent': ( - ' ', - ' ', - '', + "indent": ( + " ", + " ", + "", ), - 'attrs': ( + "attrs": ( ' ', ' ', ' ', ), - 'nsdecl_order': ( + "nsdecl_order": ( ' ', ' ', ' ', ), - 'closing_elm': ( - '', - '', - '', + "closing_elm": ( + "", + "", + "", ), } line, other, differs = cases[request.param] @@ -222,9 +244,7 @@ def xml_line_case(self, request): class DescribeChoice(object): - - def it_adds_a_getter_property_for_the_choice_element( - self, getter_fixture): + def it_adds_a_getter_property_for_the_choice_element(self, getter_fixture): parent, expected_choice = getter_fixture assert parent.choice is expected_choice @@ -238,7 +258,7 @@ def it_adds_an_insert_method_for_the_child_element(self, insert_fixture): parent._insert_choice(choice) assert parent.xml == expected_xml assert parent._insert_choice.__doc__.startswith( - 'Return the passed ```` ' + "Return the passed ```` " ) def it_adds_an_add_method_for_the_child_element(self, add_fixture): @@ -247,11 +267,12 @@ def it_adds_an_add_method_for_the_child_element(self, add_fixture): assert parent.xml == expected_xml assert isinstance(choice, CT_Choice) assert parent._add_choice.__doc__.startswith( - 'Add a new ```` child element ' + "Add a new ```` child element " ) def it_adds_a_get_or_change_to_method_for_the_child_element( - self, get_or_change_to_fixture): + self, get_or_change_to_fixture + ): parent, expected_xml = get_or_change_to_fixture choice = parent.get_or_change_to_choice() assert isinstance(choice, CT_Choice) @@ -262,40 +283,44 @@ def it_adds_a_get_or_change_to_method_for_the_child_element( @pytest.fixture def add_fixture(self): parent = self.parent_bldr().element - expected_xml = self.parent_bldr('choice').xml() + expected_xml = self.parent_bldr("choice").xml() return parent, expected_xml - @pytest.fixture(params=[ - ('choice2', 'choice'), - (None, 'choice'), - ('choice', 'choice'), - ]) + @pytest.fixture( + params=[ + ("choice2", "choice"), + (None, "choice"), + ("choice", "choice"), + ] + ) def get_or_change_to_fixture(self, request): before_member_tag, after_member_tag = request.param parent = self.parent_bldr(before_member_tag).element expected_xml = self.parent_bldr(after_member_tag).xml() return parent, expected_xml - @pytest.fixture(params=['choice', None]) + @pytest.fixture(params=["choice", None]) def getter_fixture(self, request): choice_tag = request.param parent = self.parent_bldr(choice_tag).element - expected_choice = parent.find(qn('w:choice')) # None if not found + expected_choice = parent.find(qn("w:choice")) # None if not found return parent, expected_choice @pytest.fixture def insert_fixture(self): parent = ( - a_parent().with_nsdecls().with_child( - an_oomChild()).with_child( - an_oooChild()) + a_parent() + .with_nsdecls() + .with_child(an_oomChild()) + .with_child(an_oooChild()) ).element choice = a_choice().with_nsdecls().element expected_xml = ( - a_parent().with_nsdecls().with_child( - a_choice()).with_child( - an_oomChild()).with_child( - an_oooChild()) + a_parent() + .with_nsdecls() + .with_child(a_choice()) + .with_child(an_oomChild()) + .with_child(an_oooChild()) ).xml() return parent, choice, expected_xml @@ -309,15 +334,14 @@ def new_fixture(self): def parent_bldr(self, choice_tag=None): parent_bldr = a_parent().with_nsdecls() - if choice_tag == 'choice': + if choice_tag == "choice": parent_bldr.with_child(a_choice()) - if choice_tag == 'choice2': + if choice_tag == "choice2": parent_bldr.with_child(a_choice2()) return parent_bldr class DescribeOneAndOnlyOne(object): - def it_adds_a_getter_property_for_the_child_element(self, getter_fixture): parent, oooChild = getter_fixture assert parent.oooChild is oooChild @@ -327,14 +351,12 @@ def it_adds_a_getter_property_for_the_child_element(self, getter_fixture): @pytest.fixture def getter_fixture(self): parent = a_parent().with_nsdecls().with_child(an_oooChild()).element - oooChild = parent.find(qn('w:oooChild')) + oooChild = parent.find(qn("w:oooChild")) return parent, oooChild class DescribeOneOrMore(object): - - def it_adds_a_getter_property_for_the_child_element_list( - self, getter_fixture): + def it_adds_a_getter_property_for_the_child_element_list(self, getter_fixture): parent, oomChild = getter_fixture assert parent.oomChild_lst[0] is oomChild @@ -348,7 +370,7 @@ def it_adds_an_insert_method_for_the_child_element(self, insert_fixture): parent._insert_oomChild(oomChild) assert parent.xml == expected_xml assert parent._insert_oomChild.__doc__.startswith( - 'Return the passed ```` ' + "Return the passed ```` " ) def it_adds_a_private_add_method_for_the_child_element(self, add_fixture): @@ -357,7 +379,7 @@ def it_adds_a_private_add_method_for_the_child_element(self, add_fixture): assert parent.xml == expected_xml assert isinstance(oomChild, CT_OomChild) assert parent._add_oomChild.__doc__.startswith( - 'Add a new ```` child element ' + "Add a new ```` child element " ) def it_adds_a_public_add_method_for_the_child_element(self, add_fixture): @@ -366,7 +388,7 @@ def it_adds_a_public_add_method_for_the_child_element(self, add_fixture): assert parent.xml == expected_xml assert isinstance(oomChild, CT_OomChild) assert parent._add_oomChild.__doc__.startswith( - 'Add a new ```` child element ' + "Add a new ```` child element " ) # fixtures ------------------------------------------------------- @@ -380,24 +402,26 @@ def add_fixture(self): @pytest.fixture def getter_fixture(self): parent = self.parent_bldr(True).element - oomChild = parent.find(qn('w:oomChild')) + oomChild = parent.find(qn("w:oomChild")) return parent, oomChild @pytest.fixture def insert_fixture(self): parent = ( - a_parent().with_nsdecls().with_child( - an_oooChild()).with_child( - a_zomChild()).with_child( - a_zooChild()) + a_parent() + .with_nsdecls() + .with_child(an_oooChild()) + .with_child(a_zomChild()) + .with_child(a_zooChild()) ).element oomChild = an_oomChild().with_nsdecls().element expected_xml = ( - a_parent().with_nsdecls().with_child( - an_oomChild()).with_child( - an_oooChild()).with_child( - a_zomChild()).with_child( - a_zooChild()) + a_parent() + .with_nsdecls() + .with_child(an_oomChild()) + .with_child(an_oooChild()) + .with_child(a_zomChild()) + .with_child(a_zooChild()) ).xml() return parent, oomChild, expected_xml @@ -417,7 +441,6 @@ def parent_bldr(self, oomChild_is_present): class DescribeOptionalAttribute(object): - def it_adds_a_getter_property_for_the_attr_value(self, getter_fixture): parent, optAttr_python_value = getter_fixture assert parent.optAttr == optAttr_python_value @@ -436,13 +459,13 @@ def it_adds_a_docstring_for_the_property(self): @pytest.fixture def getter_fixture(self): - parent = a_parent().with_nsdecls().with_optAttr('24').element + parent = a_parent().with_nsdecls().with_optAttr("24").element return parent, 24 @pytest.fixture(params=[36, None]) def setter_fixture(self, request): value = request.param - parent = a_parent().with_nsdecls().with_optAttr('42').element + parent = a_parent().with_nsdecls().with_optAttr("42").element if value is None: expected_xml = a_parent().with_nsdecls().xml() else: @@ -451,7 +474,6 @@ def setter_fixture(self, request): class DescribeRequiredAttribute(object): - def it_adds_a_getter_property_for_the_attr_value(self, getter_fixture): parent, reqAttr_python_value = getter_fixture assert parent.reqAttr == reqAttr_python_value @@ -480,14 +502,16 @@ def it_raises_on_assign_invalid_value(self, invalid_assign_fixture): @pytest.fixture def getter_fixture(self): - parent = a_parent().with_nsdecls().with_reqAttr('42').element + parent = a_parent().with_nsdecls().with_reqAttr("42").element return parent, 42 - @pytest.fixture(params=[ - (None, TypeError), - (-4, ValueError), - ('2', TypeError), - ]) + @pytest.fixture( + params=[ + (None, TypeError), + (-4, ValueError), + ("2", TypeError), + ] + ) def invalid_assign_fixture(self, request): invalid_value, expected_exception = request.param parent = a_parent().with_nsdecls().with_reqAttr(1).element @@ -495,16 +519,14 @@ def invalid_assign_fixture(self, request): @pytest.fixture def setter_fixture(self): - parent = a_parent().with_nsdecls().with_reqAttr('42').element + parent = a_parent().with_nsdecls().with_reqAttr("42").element value = 24 expected_xml = a_parent().with_nsdecls().with_reqAttr(value).xml() return parent, value, expected_xml class DescribeZeroOrMore(object): - - def it_adds_a_getter_property_for_the_child_element_list( - self, getter_fixture): + def it_adds_a_getter_property_for_the_child_element_list(self, getter_fixture): parent, zomChild = getter_fixture assert parent.zomChild_lst[0] is zomChild @@ -518,7 +540,7 @@ def it_adds_an_insert_method_for_the_child_element(self, insert_fixture): parent._insert_zomChild(zomChild) assert parent.xml == expected_xml assert parent._insert_zomChild.__doc__.startswith( - 'Return the passed ```` ' + "Return the passed ```` " ) def it_adds_an_add_method_for_the_child_element(self, add_fixture): @@ -527,7 +549,7 @@ def it_adds_an_add_method_for_the_child_element(self, add_fixture): assert parent.xml == expected_xml assert isinstance(zomChild, CT_ZomChild) assert parent._add_zomChild.__doc__.startswith( - 'Add a new ```` child element ' + "Add a new ```` child element " ) def it_adds_a_public_add_method_for_the_child_element(self, add_fixture): @@ -536,11 +558,11 @@ def it_adds_a_public_add_method_for_the_child_element(self, add_fixture): assert parent.xml == expected_xml assert isinstance(zomChild, CT_ZomChild) assert parent._add_zomChild.__doc__.startswith( - 'Add a new ```` child element ' + "Add a new ```` child element " ) def it_removes_the_property_root_name_used_for_declaration(self): - assert not hasattr(CT_Parent, 'zomChild') + assert not hasattr(CT_Parent, "zomChild") # fixtures ------------------------------------------------------- @@ -553,24 +575,26 @@ def add_fixture(self): @pytest.fixture def getter_fixture(self): parent = self.parent_bldr(True).element - zomChild = parent.find(qn('w:zomChild')) + zomChild = parent.find(qn("w:zomChild")) return parent, zomChild @pytest.fixture def insert_fixture(self): parent = ( - a_parent().with_nsdecls().with_child( - an_oomChild()).with_child( - an_oooChild()).with_child( - a_zooChild()) + a_parent() + .with_nsdecls() + .with_child(an_oomChild()) + .with_child(an_oooChild()) + .with_child(a_zooChild()) ).element zomChild = a_zomChild().with_nsdecls().element expected_xml = ( - a_parent().with_nsdecls().with_child( - an_oomChild()).with_child( - an_oooChild()).with_child( - a_zomChild()).with_child( - a_zooChild()) + a_parent() + .with_nsdecls() + .with_child(an_oomChild()) + .with_child(an_oooChild()) + .with_child(a_zomChild()) + .with_child(a_zooChild()) ).xml() return parent, zomChild, expected_xml @@ -588,7 +612,6 @@ def parent_bldr(self, zomChild_is_present): class DescribeZeroOrOne(object): - def it_adds_a_getter_property_for_the_child_element(self, getter_fixture): parent, zooChild = getter_fixture assert parent.zooChild is zooChild @@ -599,7 +622,7 @@ def it_adds_an_add_method_for_the_child_element(self, add_fixture): assert parent.xml == expected_xml assert isinstance(zooChild, CT_ZooChild) assert parent._add_zooChild.__doc__.startswith( - 'Add a new ```` child element ' + "Add a new ```` child element " ) def it_adds_an_insert_method_for_the_child_element(self, insert_fixture): @@ -607,11 +630,10 @@ def it_adds_an_insert_method_for_the_child_element(self, insert_fixture): parent._insert_zooChild(zooChild) assert parent.xml == expected_xml assert parent._insert_zooChild.__doc__.startswith( - 'Return the passed ```` ' + "Return the passed ```` " ) - def it_adds_a_get_or_add_method_for_the_child_element( - self, get_or_add_fixture): + def it_adds_a_get_or_add_method_for_the_child_element(self, get_or_add_fixture): parent, expected_xml = get_or_add_fixture zooChild = parent.get_or_add_zooChild() assert isinstance(zooChild, CT_ZooChild) @@ -634,7 +656,7 @@ def add_fixture(self): def getter_fixture(self, request): zooChild_is_present = request.param parent = self.parent_bldr(zooChild_is_present).element - zooChild = parent.find(qn('w:zooChild')) # None if not found + zooChild = parent.find(qn("w:zooChild")) # None if not found return parent, zooChild @pytest.fixture(params=[True, False]) @@ -647,18 +669,20 @@ def get_or_add_fixture(self, request): @pytest.fixture def insert_fixture(self): parent = ( - a_parent().with_nsdecls().with_child( - an_oomChild()).with_child( - an_oooChild()).with_child( - a_zomChild()) + a_parent() + .with_nsdecls() + .with_child(an_oomChild()) + .with_child(an_oooChild()) + .with_child(a_zomChild()) ).element zooChild = a_zooChild().with_nsdecls().element expected_xml = ( - a_parent().with_nsdecls().with_child( - an_oomChild()).with_child( - an_oooChild()).with_child( - a_zomChild()).with_child( - a_zooChild()) + a_parent() + .with_nsdecls() + .with_child(an_oomChild()) + .with_child(an_oooChild()) + .with_child(a_zomChild()) + .with_child(a_zooChild()) ).xml() return parent, zooChild, expected_xml @@ -679,18 +703,17 @@ def parent_bldr(self, zooChild_is_present): class DescribeZeroOrOneChoice(object): - def it_adds_a_getter_for_the_current_choice(self, getter_fixture): parent, expected_choice = getter_fixture assert parent.eg_zooChoice is expected_choice # fixtures ------------------------------------------------------- - @pytest.fixture(params=[None, 'choice', 'choice2']) + @pytest.fixture(params=[None, "choice", "choice2"]) def getter_fixture(self, request): choice_tag = request.param parent = self.parent_bldr(choice_tag).element - tagname = 'w:%s' % choice_tag + tagname = "w:%s" % choice_tag expected_choice = parent.find(qn(tagname)) # None if not found return parent, expected_choice @@ -698,9 +721,9 @@ def getter_fixture(self, request): def parent_bldr(self, choice_tag=None): parent_bldr = a_parent().with_nsdecls() - if choice_tag == 'choice': + if choice_tag == "choice": parent_bldr.with_child(a_choice()) - if choice_tag == 'choice2': + if choice_tag == "choice2": parent_bldr.with_child(a_choice2()) return parent_bldr @@ -709,33 +732,32 @@ def parent_bldr(self, choice_tag=None): # static shared fixture # -------------------------------------------------------------------- -class ST_IntegerType(BaseIntType): +class ST_IntegerType(BaseIntType): @classmethod def validate(cls, value): cls.validate_int(value) if value < 1 or value > 42: - raise ValueError( - "value must be in range 1 to 42 inclusive" - ) + raise ValueError("value must be in range 1 to 42 inclusive") class CT_Parent(BaseOxmlElement): """ ```` element, an invented element for use in testing. """ + eg_zooChoice = ZeroOrOneChoice( - (Choice('w:choice'), Choice('w:choice2')), - successors=('w:oomChild', 'w:oooChild') + (Choice("w:choice"), Choice("w:choice2")), + successors=("w:oomChild", "w:oooChild"), + ) + oomChild = OneOrMore( + "w:oomChild", successors=("w:oooChild", "w:zomChild", "w:zooChild") ) - oomChild = OneOrMore('w:oomChild', successors=( - 'w:oooChild', 'w:zomChild', 'w:zooChild' - )) - oooChild = OneAndOnlyOne('w:oooChild') - zomChild = ZeroOrMore('w:zomChild', successors=('w:zooChild',)) - zooChild = ZeroOrOne('w:zooChild', successors=()) - optAttr = OptionalAttribute('w:optAttr', ST_IntegerType) - reqAttr = RequiredAttribute('reqAttr', ST_IntegerType) + oooChild = OneAndOnlyOne("w:oooChild") + zomChild = ZeroOrMore("w:zomChild", successors=("w:zooChild",)) + zooChild = ZeroOrOne("w:zooChild", successors=()) + optAttr = OptionalAttribute("w:optAttr", ST_IntegerType) + reqAttr = RequiredAttribute("reqAttr", ST_IntegerType) class CT_Choice(BaseOxmlElement): @@ -766,52 +788,52 @@ class CT_ZooChild(BaseOxmlElement): """ -register_element_cls('w:parent', CT_Parent) -register_element_cls('w:choice', CT_Choice) -register_element_cls('w:oomChild', CT_OomChild) -register_element_cls('w:zomChild', CT_ZomChild) -register_element_cls('w:zooChild', CT_ZooChild) +register_element_cls("w:parent", CT_Parent) +register_element_cls("w:choice", CT_Choice) +register_element_cls("w:oomChild", CT_OomChild) +register_element_cls("w:zomChild", CT_ZomChild) +register_element_cls("w:zooChild", CT_ZooChild) class CT_ChoiceBuilder(BaseBuilder): - __tag__ = 'w:choice' - __nspfxs__ = ('w',) + __tag__ = "w:choice" + __nspfxs__ = ("w",) __attrs__ = () class CT_Choice2Builder(BaseBuilder): - __tag__ = 'w:choice2' - __nspfxs__ = ('w',) + __tag__ = "w:choice2" + __nspfxs__ = ("w",) __attrs__ = () class CT_ParentBuilder(BaseBuilder): - __tag__ = 'w:parent' - __nspfxs__ = ('w',) - __attrs__ = ('w:optAttr', 'reqAttr') + __tag__ = "w:parent" + __nspfxs__ = ("w",) + __attrs__ = ("w:optAttr", "reqAttr") class CT_OomChildBuilder(BaseBuilder): - __tag__ = 'w:oomChild' - __nspfxs__ = ('w',) + __tag__ = "w:oomChild" + __nspfxs__ = ("w",) __attrs__ = () class CT_OooChildBuilder(BaseBuilder): - __tag__ = 'w:oooChild' - __nspfxs__ = ('w',) + __tag__ = "w:oooChild" + __nspfxs__ = ("w",) __attrs__ = () class CT_ZomChildBuilder(BaseBuilder): - __tag__ = 'w:zomChild' - __nspfxs__ = ('w',) + __tag__ = "w:zomChild" + __nspfxs__ = ("w",) __attrs__ = () class CT_ZooChildBuilder(BaseBuilder): - __tag__ = 'w:zooChild' - __nspfxs__ = ('w',) + __tag__ = "w:zooChild" + __nspfxs__ = ("w",) __attrs__ = () diff --git a/tests/oxml/text/test_run.py b/tests/oxml/text/test_run.py index 57b8580f..0dc091b2 100644 --- a/tests/oxml/text/test_run.py +++ b/tests/oxml/text/test_run.py @@ -4,9 +4,7 @@ Test suite for the docx.oxml.text.run module. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals import pytest @@ -14,7 +12,6 @@ class DescribeCT_R(object): - def it_can_add_a_t_preserving_edge_whitespace(self, add_t_fixture): r, text, expected_xml = add_t_fixture r.add_t(text) @@ -22,12 +19,17 @@ def it_can_add_a_t_preserving_edge_whitespace(self, add_t_fixture): # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - ('w:r', 'foobar', 'w:r/w:t"foobar"'), - ('w:r', 'foobar ', 'w:r/w:t{xml:space=preserve}"foobar "'), - ('w:r/(w:rPr/w:rStyle{w:val=emphasis}, w:cr)', 'foobar', - 'w:r/(w:rPr/w:rStyle{w:val=emphasis}, w:cr, w:t"foobar")'), - ]) + @pytest.fixture( + params=[ + ("w:r", "foobar", 'w:r/w:t"foobar"'), + ("w:r", "foobar ", 'w:r/w:t{xml:space=preserve}"foobar "'), + ( + "w:r/(w:rPr/w:rStyle{w:val=emphasis}, w:cr)", + "foobar", + 'w:r/(w:rPr/w:rStyle{w:val=emphasis}, w:cr, w:t"foobar")', + ), + ] + ) def add_t_fixture(self, request): initial_cxml, text, expected_cxml = request.param r = element(initial_cxml) diff --git a/tests/oxml/unitdata/dml.py b/tests/oxml/unitdata/dml.py index 84518f8b..d2ba72ed 100644 --- a/tests/oxml/unitdata/dml.py +++ b/tests/oxml/unitdata/dml.py @@ -8,50 +8,50 @@ class CT_BlipBuilder(BaseBuilder): - __tag__ = 'a:blip' - __nspfxs__ = ('a',) - __attrs__ = ('r:embed', 'r:link', 'cstate') + __tag__ = "a:blip" + __nspfxs__ = ("a",) + __attrs__ = ("r:embed", "r:link", "cstate") class CT_BlipFillPropertiesBuilder(BaseBuilder): - __tag__ = 'pic:blipFill' - __nspfxs__ = ('pic',) + __tag__ = "pic:blipFill" + __nspfxs__ = ("pic",) __attrs__ = () class CT_DrawingBuilder(BaseBuilder): - __tag__ = 'w:drawing' - __nspfxs__ = ('w',) + __tag__ = "w:drawing" + __nspfxs__ = ("w",) __attrs__ = () class CT_GraphicalObjectBuilder(BaseBuilder): - __tag__ = 'a:graphic' - __nspfxs__ = ('a',) + __tag__ = "a:graphic" + __nspfxs__ = ("a",) __attrs__ = () class CT_GraphicalObjectDataBuilder(BaseBuilder): - __tag__ = 'a:graphicData' - __nspfxs__ = ('a',) - __attrs__ = ('uri',) + __tag__ = "a:graphicData" + __nspfxs__ = ("a",) + __attrs__ = ("uri",) class CT_GraphicalObjectFrameLockingBuilder(BaseBuilder): - __tag__ = 'a:graphicFrameLocks' - __nspfxs__ = ('a',) - __attrs__ = ('noChangeAspect',) + __tag__ = "a:graphicFrameLocks" + __nspfxs__ = ("a",) + __attrs__ = ("noChangeAspect",) class CT_InlineBuilder(BaseBuilder): - __tag__ = 'wp:inline' - __nspfxs__ = ('wp',) - __attrs__ = ('distT', 'distB', 'distL', 'distR') + __tag__ = "wp:inline" + __nspfxs__ = ("wp",) + __attrs__ = ("distT", "distB", "distL", "distR") class CT_NonVisualDrawingPropsBuilder(BaseBuilder): - __nspfxs__ = ('wp',) - __attrs__ = ('id', 'name', 'descr', 'hidden', 'title') + __nspfxs__ = ("wp",) + __attrs__ = ("id", "name", "descr", "hidden", "title") def __init__(self, tag): self.__tag__ = tag @@ -59,38 +59,38 @@ def __init__(self, tag): class CT_NonVisualGraphicFramePropertiesBuilder(BaseBuilder): - __tag__ = 'wp:cNvGraphicFramePr' - __nspfxs__ = ('wp',) + __tag__ = "wp:cNvGraphicFramePr" + __nspfxs__ = ("wp",) __attrs__ = () class CT_NonVisualPicturePropertiesBuilder(BaseBuilder): - __tag__ = 'pic:cNvPicPr' - __nspfxs__ = ('pic',) - __attrs__ = ('preferRelativeResize') + __tag__ = "pic:cNvPicPr" + __nspfxs__ = ("pic",) + __attrs__ = "preferRelativeResize" class CT_PictureBuilder(BaseBuilder): - __tag__ = 'pic:pic' - __nspfxs__ = ('pic',) + __tag__ = "pic:pic" + __nspfxs__ = ("pic",) __attrs__ = () class CT_PictureNonVisualBuilder(BaseBuilder): - __tag__ = 'pic:nvPicPr' - __nspfxs__ = ('pic',) + __tag__ = "pic:nvPicPr" + __nspfxs__ = ("pic",) __attrs__ = () class CT_Point2DBuilder(BaseBuilder): - __tag__ = 'a:off' - __nspfxs__ = ('a',) - __attrs__ = ('x', 'y') + __tag__ = "a:off" + __nspfxs__ = ("a",) + __attrs__ = ("x", "y") class CT_PositiveSize2DBuilder(BaseBuilder): __nspfxs__ = () - __attrs__ = ('cx', 'cy') + __attrs__ = ("cx", "cy") def __init__(self, tag): self.__tag__ = tag @@ -98,33 +98,33 @@ def __init__(self, tag): class CT_PresetGeometry2DBuilder(BaseBuilder): - __tag__ = 'a:prstGeom' - __nspfxs__ = ('a',) - __attrs__ = ('prst',) + __tag__ = "a:prstGeom" + __nspfxs__ = ("a",) + __attrs__ = ("prst",) class CT_RelativeRectBuilder(BaseBuilder): - __tag__ = 'a:fillRect' - __nspfxs__ = ('a',) - __attrs__ = ('l', 't', 'r', 'b') + __tag__ = "a:fillRect" + __nspfxs__ = ("a",) + __attrs__ = ("l", "t", "r", "b") class CT_ShapePropertiesBuilder(BaseBuilder): - __tag__ = 'pic:spPr' - __nspfxs__ = ('pic', 'a') - __attrs__ = ('bwMode',) + __tag__ = "pic:spPr" + __nspfxs__ = ("pic", "a") + __attrs__ = ("bwMode",) class CT_StretchInfoPropertiesBuilder(BaseBuilder): - __tag__ = 'a:stretch' - __nspfxs__ = ('a',) + __tag__ = "a:stretch" + __nspfxs__ = ("a",) __attrs__ = () class CT_Transform2DBuilder(BaseBuilder): - __tag__ = 'a:xfrm' - __nspfxs__ = ('a',) - __attrs__ = ('rot', 'flipH', 'flipV') + __tag__ = "a:xfrm" + __nspfxs__ = ("a",) + __attrs__ = ("rot", "flipH", "flipV") def a_blip(): @@ -144,11 +144,11 @@ def a_cNvPicPr(): def a_cNvPr(): - return CT_NonVisualDrawingPropsBuilder('pic:cNvPr') + return CT_NonVisualDrawingPropsBuilder("pic:cNvPr") def a_docPr(): - return CT_NonVisualDrawingPropsBuilder('wp:docPr') + return CT_NonVisualDrawingPropsBuilder("wp:docPr") def a_drawing(): @@ -184,11 +184,11 @@ def a_stretch(): def an_ext(): - return CT_PositiveSize2DBuilder('a:ext') + return CT_PositiveSize2DBuilder("a:ext") def an_extent(): - return CT_PositiveSize2DBuilder('wp:extent') + return CT_PositiveSize2DBuilder("wp:extent") def an_inline(): diff --git a/tests/oxml/unitdata/numbering.py b/tests/oxml/unitdata/numbering.py index 984667b3..92f943fd 100644 --- a/tests/oxml/unitdata/numbering.py +++ b/tests/oxml/unitdata/numbering.py @@ -8,14 +8,14 @@ class CT_NumBuilder(BaseBuilder): - __tag__ = 'w:num' - __nspfxs__ = ('w',) - __attrs__ = ('w:numId') + __tag__ = "w:num" + __nspfxs__ = ("w",) + __attrs__ = "w:numId" class CT_NumberingBuilder(BaseBuilder): - __tag__ = 'w:numbering' - __nspfxs__ = ('w',) + __tag__ = "w:numbering" + __nspfxs__ = ("w",) __attrs__ = () diff --git a/tests/oxml/unitdata/section.py b/tests/oxml/unitdata/section.py index 2f5f4115..13194f4c 100644 --- a/tests/oxml/unitdata/section.py +++ b/tests/oxml/unitdata/section.py @@ -8,30 +8,35 @@ class CT_PageMarBuilder(BaseBuilder): - __tag__ = 'w:pgMar' - __nspfxs__ = ('w',) + __tag__ = "w:pgMar" + __nspfxs__ = ("w",) __attrs__ = ( - 'w:top', 'w:right', 'w:bottom', 'w:left', 'w:header', 'w:footer', - 'w:gutter' + "w:top", + "w:right", + "w:bottom", + "w:left", + "w:header", + "w:footer", + "w:gutter", ) class CT_PageSzBuilder(BaseBuilder): - __tag__ = 'w:pgSz' - __nspfxs__ = ('w',) - __attrs__ = ('w:w', 'w:h', 'w:orient', 'w:code') + __tag__ = "w:pgSz" + __nspfxs__ = ("w",) + __attrs__ = ("w:w", "w:h", "w:orient", "w:code") class CT_SectPrBuilder(BaseBuilder): - __tag__ = 'w:sectPr' - __nspfxs__ = ('w',) + __tag__ = "w:sectPr" + __nspfxs__ = ("w",) __attrs__ = () class CT_SectTypeBuilder(BaseBuilder): - __tag__ = 'w:type' - __nspfxs__ = ('w',) - __attrs__ = ('w:val',) + __tag__ = "w:type" + __nspfxs__ = ("w",) + __attrs__ = ("w:val",) def a_pgMar(): diff --git a/tests/oxml/unitdata/shared.py b/tests/oxml/unitdata/shared.py index 4bee3ae0..a7007862 100644 --- a/tests/oxml/unitdata/shared.py +++ b/tests/oxml/unitdata/shared.py @@ -8,20 +8,20 @@ class CT_OnOffBuilder(BaseBuilder): - __nspfxs__ = ('w',) - __attrs__ = ('w:val') + __nspfxs__ = ("w",) + __attrs__ = "w:val" def __init__(self, tag): self.__tag__ = tag super(CT_OnOffBuilder, self).__init__() def with_val(self, value): - self._set_xmlattr('w:val', str(value)) + self._set_xmlattr("w:val", str(value)) return self class CT_StringBuilder(BaseBuilder): - __nspfxs__ = ('w',) + __nspfxs__ = ("w",) __attrs__ = () def __init__(self, tag): @@ -29,5 +29,5 @@ def __init__(self, tag): super(CT_StringBuilder, self).__init__() def with_val(self, value): - self._set_xmlattr('w:val', str(value)) + self._set_xmlattr("w:val", str(value)) return self diff --git a/tests/oxml/unitdata/styles.py b/tests/oxml/unitdata/styles.py index cf7dd4fa..0411c93e 100644 --- a/tests/oxml/unitdata/styles.py +++ b/tests/oxml/unitdata/styles.py @@ -8,14 +8,14 @@ class CT_StyleBuilder(BaseBuilder): - __tag__ = 'w:style' - __nspfxs__ = ('w',) - __attrs__ = ('w:type', 'w:styleId', 'w:default', 'w:customStyle') + __tag__ = "w:style" + __nspfxs__ = ("w",) + __attrs__ = ("w:type", "w:styleId", "w:default", "w:customStyle") class CT_StylesBuilder(BaseBuilder): - __tag__ = 'w:styles' - __nspfxs__ = ('w',) + __tag__ = "w:styles" + __nspfxs__ = ("w",) __attrs__ = () diff --git a/tests/oxml/unitdata/table.py b/tests/oxml/unitdata/table.py index 5f0cb272..45536d49 100644 --- a/tests/oxml/unitdata/table.py +++ b/tests/oxml/unitdata/table.py @@ -9,50 +9,50 @@ class CT_RowBuilder(BaseBuilder): - __tag__ = 'w:tr' - __nspfxs__ = ('w',) - __attrs__ = ('w:w',) + __tag__ = "w:tr" + __nspfxs__ = ("w",) + __attrs__ = ("w:w",) class CT_TblBuilder(BaseBuilder): - __tag__ = 'w:tbl' - __nspfxs__ = ('w',) + __tag__ = "w:tbl" + __nspfxs__ = ("w",) __attrs__ = () class CT_TblGridBuilder(BaseBuilder): - __tag__ = 'w:tblGrid' - __nspfxs__ = ('w',) - __attrs__ = ('w:w',) + __tag__ = "w:tblGrid" + __nspfxs__ = ("w",) + __attrs__ = ("w:w",) class CT_TblGridColBuilder(BaseBuilder): - __tag__ = 'w:gridCol' - __nspfxs__ = ('w',) - __attrs__ = ('w:w',) + __tag__ = "w:gridCol" + __nspfxs__ = ("w",) + __attrs__ = ("w:w",) class CT_TblPrBuilder(BaseBuilder): - __tag__ = 'w:tblPr' - __nspfxs__ = ('w',) + __tag__ = "w:tblPr" + __nspfxs__ = ("w",) __attrs__ = () class CT_TblWidthBuilder(BaseBuilder): - __tag__ = 'w:tblW' - __nspfxs__ = ('w',) - __attrs__ = ('w:w', 'w:type') + __tag__ = "w:tblW" + __nspfxs__ = ("w",) + __attrs__ = ("w:w", "w:type") class CT_TcBuilder(BaseBuilder): - __tag__ = 'w:tc' - __nspfxs__ = ('w',) - __attrs__ = ('w:id',) + __tag__ = "w:tc" + __nspfxs__ = ("w",) + __attrs__ = ("w:id",) class CT_TcPrBuilder(BaseBuilder): - __tag__ = 'w:tcPr' - __nspfxs__ = ('w',) + __tag__ = "w:tcPr" + __nspfxs__ = ("w",) __attrs__ = () @@ -73,7 +73,7 @@ def a_tblPr(): def a_tblStyle(): - return CT_StringBuilder('w:tblStyle') + return CT_StringBuilder("w:tblStyle") def a_tblW(): diff --git a/tests/oxml/unitdata/text.py b/tests/oxml/unitdata/text.py index 36129614..de1d984d 100644 --- a/tests/oxml/unitdata/text.py +++ b/tests/oxml/unitdata/text.py @@ -9,13 +9,13 @@ class CT_BrBuilder(BaseBuilder): - __tag__ = 'w:br' - __nspfxs__ = ('w',) - __attrs__ = ('w:type', 'w:clear') + __tag__ = "w:br" + __nspfxs__ = ("w",) + __attrs__ = ("w:type", "w:clear") class CT_EmptyBuilder(BaseBuilder): - __nspfxs__ = ('w',) + __nspfxs__ = ("w",) __attrs__ = () def __init__(self, tag): @@ -24,65 +24,63 @@ def __init__(self, tag): class CT_JcBuilder(BaseBuilder): - __tag__ = 'w:jc' - __nspfxs__ = ('w',) - __attrs__ = ('w:val',) + __tag__ = "w:jc" + __nspfxs__ = ("w",) + __attrs__ = ("w:val",) class CT_PBuilder(BaseBuilder): - __tag__ = 'w:p' - __nspfxs__ = ('w',) + __tag__ = "w:p" + __nspfxs__ = ("w",) __attrs__ = () class CT_PPrBuilder(BaseBuilder): - __tag__ = 'w:pPr' - __nspfxs__ = ('w',) + __tag__ = "w:pPr" + __nspfxs__ = ("w",) __attrs__ = () class CT_RBuilder(BaseBuilder): - __tag__ = 'w:r' - __nspfxs__ = ('w',) + __tag__ = "w:r" + __nspfxs__ = ("w",) __attrs__ = () class CT_RPrBuilder(BaseBuilder): - __tag__ = 'w:rPr' - __nspfxs__ = ('w',) + __tag__ = "w:rPr" + __nspfxs__ = ("w",) __attrs__ = () class CT_SectPrBuilder(BaseBuilder): - __tag__ = 'w:sectPr' - __nspfxs__ = ('w',) + __tag__ = "w:sectPr" + __nspfxs__ = ("w",) __attrs__ = () class CT_TextBuilder(BaseBuilder): - __tag__ = 'w:t' - __nspfxs__ = ('w',) + __tag__ = "w:t" + __nspfxs__ = ("w",) __attrs__ = () def with_space(self, value): - self._set_xmlattr('xml:space', str(value)) + self._set_xmlattr("xml:space", str(value)) return self class CT_UnderlineBuilder(BaseBuilder): - __tag__ = 'w:u' - __nspfxs__ = ('w',) - __attrs__ = ( - 'w:val', 'w:color', 'w:themeColor', 'w:themeTint', 'w:themeShade' - ) + __tag__ = "w:u" + __nspfxs__ = ("w",) + __attrs__ = ("w:val", "w:color", "w:themeColor", "w:themeTint", "w:themeShade") def a_b(): - return CT_OnOffBuilder('w:b') + return CT_OnOffBuilder("w:b") def a_bCs(): - return CT_OnOffBuilder('w:bCs') + return CT_OnOffBuilder("w:bCs") def a_br(): @@ -90,19 +88,19 @@ def a_br(): def a_caps(): - return CT_OnOffBuilder('w:caps') + return CT_OnOffBuilder("w:caps") def a_cr(): - return CT_EmptyBuilder('w:cr') + return CT_EmptyBuilder("w:cr") def a_cs(): - return CT_OnOffBuilder('w:cs') + return CT_OnOffBuilder("w:cs") def a_dstrike(): - return CT_OnOffBuilder('w:dstrike') + return CT_OnOffBuilder("w:dstrike") def a_jc(): @@ -110,39 +108,39 @@ def a_jc(): def a_noProof(): - return CT_OnOffBuilder('w:noProof') + return CT_OnOffBuilder("w:noProof") def a_shadow(): - return CT_OnOffBuilder('w:shadow') + return CT_OnOffBuilder("w:shadow") def a_smallCaps(): - return CT_OnOffBuilder('w:smallCaps') + return CT_OnOffBuilder("w:smallCaps") def a_snapToGrid(): - return CT_OnOffBuilder('w:snapToGrid') + return CT_OnOffBuilder("w:snapToGrid") def a_specVanish(): - return CT_OnOffBuilder('w:specVanish') + return CT_OnOffBuilder("w:specVanish") def a_strike(): - return CT_OnOffBuilder('w:strike') + return CT_OnOffBuilder("w:strike") def a_tab(): - return CT_EmptyBuilder('w:tab') + return CT_EmptyBuilder("w:tab") def a_vanish(): - return CT_OnOffBuilder('w:vanish') + return CT_OnOffBuilder("w:vanish") def a_webHidden(): - return CT_OnOffBuilder('w:webHidden') + return CT_OnOffBuilder("w:webHidden") def a_p(): @@ -154,7 +152,7 @@ def a_pPr(): def a_pStyle(): - return CT_StringBuilder('w:pStyle') + return CT_StringBuilder("w:pStyle") def a_sectPr(): @@ -170,27 +168,27 @@ def a_u(): def an_emboss(): - return CT_OnOffBuilder('w:emboss') + return CT_OnOffBuilder("w:emboss") def an_i(): - return CT_OnOffBuilder('w:i') + return CT_OnOffBuilder("w:i") def an_iCs(): - return CT_OnOffBuilder('w:iCs') + return CT_OnOffBuilder("w:iCs") def an_imprint(): - return CT_OnOffBuilder('w:imprint') + return CT_OnOffBuilder("w:imprint") def an_oMath(): - return CT_OnOffBuilder('w:oMath') + return CT_OnOffBuilder("w:oMath") def an_outline(): - return CT_OnOffBuilder('w:outline') + return CT_OnOffBuilder("w:outline") def an_r(): @@ -202,8 +200,8 @@ def an_rPr(): def an_rStyle(): - return CT_StringBuilder('w:rStyle') + return CT_StringBuilder("w:rStyle") def an_rtl(): - return CT_OnOffBuilder('w:rtl') + return CT_OnOffBuilder("w:rtl") diff --git a/tests/parts/test_document.py b/tests/parts/test_document.py index 2d23a53e..f4e1e06a 100644 --- a/tests/parts/test_document.py +++ b/tests/parts/test_document.py @@ -24,7 +24,6 @@ class DescribeDocumentPart(object): - def it_can_add_a_footer_part(self, package_, FooterPart_, footer_part_, relate_to_): FooterPart_.new.return_value = footer_part_ relate_to_.return_value = "rId12" @@ -101,7 +100,8 @@ def it_provides_access_to_its_core_properties(self, core_props_fixture): assert core_properties is core_properties_ def it_provides_access_to_the_inline_shapes_in_the_document( - self, inline_shapes_fixture): + self, inline_shapes_fixture + ): document, InlineShapes_, body_elm = inline_shapes_fixture inline_shapes = document.inline_shapes InlineShapes_.assert_called_once_with(body_elm, document) @@ -209,10 +209,7 @@ def core_props_fixture(self, package_, core_properties_): @pytest.fixture def inline_shapes_fixture(self, request, InlineShapes_): - document_elm = ( - a_document().with_nsdecls().with_child( - a_body()) - ).element + document_elm = (a_document().with_nsdecls().with_child(a_body())).element body_elm = document_elm[0] document = DocumentPart(None, None, document_elm, None) return document, InlineShapes_, body_elm @@ -220,12 +217,11 @@ def inline_shapes_fixture(self, request, InlineShapes_): @pytest.fixture def save_fixture(self, package_): document_part = DocumentPart(None, None, None, package_) - file_ = 'foobar.docx' + file_ = "foobar.docx" return document_part, file_ @pytest.fixture - def settings_fixture(self, _settings_part_prop_, settings_part_, - settings_): + def settings_fixture(self, _settings_part_prop_, settings_part_, settings_): document_part = DocumentPart(None, None, None, None) _settings_part_prop_.return_value = settings_part_ settings_part_.settings = settings_ @@ -250,7 +246,7 @@ def drop_rel_(self, request): @pytest.fixture def FooterPart_(self, request): - return class_mock(request, 'docx.parts.document.FooterPart') + return class_mock(request, "docx.parts.document.FooterPart") @pytest.fixture def footer_part_(self, request): @@ -258,7 +254,7 @@ def footer_part_(self, request): @pytest.fixture def HeaderPart_(self, request): - return class_mock(request, 'docx.parts.document.HeaderPart') + return class_mock(request, "docx.parts.document.HeaderPart") @pytest.fixture def header_part_(self, request): @@ -266,11 +262,11 @@ def header_part_(self, request): @pytest.fixture def InlineShapes_(self, request): - return class_mock(request, 'docx.parts.document.InlineShapes') + return class_mock(request, "docx.parts.document.InlineShapes") @pytest.fixture def NumberingPart_(self, request): - return class_mock(request, 'docx.parts.document.NumberingPart') + return class_mock(request, "docx.parts.document.NumberingPart") @pytest.fixture def numbering_part_(self, request): @@ -282,11 +278,11 @@ def package_(self, request): @pytest.fixture def part_related_by_(self, request): - return method_mock(request, DocumentPart, 'part_related_by') + return method_mock(request, DocumentPart, "part_related_by") @pytest.fixture def relate_to_(self, request): - return method_mock(request, DocumentPart, 'relate_to') + return method_mock(request, DocumentPart, "relate_to") @pytest.fixture def related_parts_(self, request): @@ -294,11 +290,11 @@ def related_parts_(self, request): @pytest.fixture def related_parts_prop_(self, request): - return property_mock(request, DocumentPart, 'related_parts') + return property_mock(request, DocumentPart, "related_parts") @pytest.fixture def SettingsPart_(self, request): - return class_mock(request, 'docx.parts.document.SettingsPart') + return class_mock(request, "docx.parts.document.SettingsPart") @pytest.fixture def settings_(self, request): @@ -310,7 +306,7 @@ def settings_part_(self, request): @pytest.fixture def _settings_part_prop_(self, request): - return property_mock(request, DocumentPart, '_settings_part') + return property_mock(request, DocumentPart, "_settings_part") @pytest.fixture def style_(self, request): @@ -322,7 +318,7 @@ def styles_(self, request): @pytest.fixture def StylesPart_(self, request): - return class_mock(request, 'docx.parts.document.StylesPart') + return class_mock(request, "docx.parts.document.StylesPart") @pytest.fixture def styles_part_(self, request): @@ -330,8 +326,8 @@ def styles_part_(self, request): @pytest.fixture def styles_prop_(self, request): - return property_mock(request, DocumentPart, 'styles') + return property_mock(request, DocumentPart, "styles") @pytest.fixture def _styles_part_prop_(self, request): - return property_mock(request, DocumentPart, '_styles_part') + return property_mock(request, DocumentPart, "_styles_part") diff --git a/tests/parts/test_hdrftr.py b/tests/parts/test_hdrftr.py index 20573803..815b207c 100644 --- a/tests/parts/test_hdrftr.py +++ b/tests/parts/test_hdrftr.py @@ -16,7 +16,6 @@ class DescribeFooterPart(object): - def it_is_used_by_loader_to_construct_footer_part( self, package_, FooterPart_load_, footer_part_ ): @@ -85,7 +84,6 @@ def parse_xml_(self, request): class DescribeHeaderPart(object): - def it_is_used_by_loader_to_construct_header_part( self, package_, HeaderPart_load_, header_part_ ): diff --git a/tests/parts/test_numbering.py b/tests/parts/test_numbering.py index e5292a67..44dedde7 100644 --- a/tests/parts/test_numbering.py +++ b/tests/parts/test_numbering.py @@ -16,11 +16,13 @@ class DescribeNumberingPart(object): - - def it_provides_access_to_the_numbering_definitions( - self, num_defs_fixture): - (numbering_part, _NumberingDefinitions_, numbering_elm_, - numbering_definitions_) = num_defs_fixture + def it_provides_access_to_the_numbering_definitions(self, num_defs_fixture): + ( + numbering_part, + _NumberingDefinitions_, + numbering_elm_, + numbering_definitions_, + ) = num_defs_fixture numbering_definitions = numbering_part.numbering_definitions _NumberingDefinitions_.assert_called_once_with(numbering_elm_) assert numbering_definitions is numbering_definitions_ @@ -29,12 +31,14 @@ def it_provides_access_to_the_numbering_definitions( @pytest.fixture def num_defs_fixture( - self, _NumberingDefinitions_, numbering_elm_, - numbering_definitions_): + self, _NumberingDefinitions_, numbering_elm_, numbering_definitions_ + ): numbering_part = NumberingPart(None, None, numbering_elm_, None) return ( - numbering_part, _NumberingDefinitions_, numbering_elm_, - numbering_definitions_ + numbering_part, + _NumberingDefinitions_, + numbering_elm_, + numbering_definitions_, ) # fixture components --------------------------------------------- @@ -42,8 +46,9 @@ def num_defs_fixture( @pytest.fixture def _NumberingDefinitions_(self, request, numbering_definitions_): return class_mock( - request, 'docx.parts.numbering._NumberingDefinitions', - return_value=numbering_definitions_ + request, + "docx.parts.numbering._NumberingDefinitions", + return_value=numbering_definitions_, ) @pytest.fixture @@ -56,9 +61,7 @@ def numbering_elm_(self, request): class Describe_NumberingDefinitions(object): - - def it_knows_how_many_numbering_definitions_it_contains( - self, len_fixture): + def it_knows_how_many_numbering_definitions_it_contains(self, len_fixture): numbering_definitions, numbering_definition_count = len_fixture assert len(numbering_definitions) == numbering_definition_count diff --git a/tests/parts/test_settings.py b/tests/parts/test_settings.py index 12c6b1d2..21ba2ec4 100644 --- a/tests/parts/test_settings.py +++ b/tests/parts/test_settings.py @@ -18,11 +18,10 @@ class DescribeSettingsPart(object): - def it_is_used_by_loader_to_construct_settings_part( self, load_, package_, settings_part_ ): - partname, blob = 'partname', 'blob' + partname, blob = "partname", "blob" content_type = CT.WML_SETTINGS load_.return_value = settings_part_ @@ -41,7 +40,7 @@ def it_constructs_a_default_settings_part_to_help(self): package = OpcPackage() settings_part = SettingsPart.default(package) assert isinstance(settings_part, SettingsPart) - assert settings_part.partname == '/word/settings.xml' + assert settings_part.partname == "/word/settings.xml" assert settings_part.content_type == CT.WML_SETTINGS assert settings_part.package is package assert len(settings_part.element) == 6 @@ -50,7 +49,7 @@ def it_constructs_a_default_settings_part_to_help(self): @pytest.fixture def settings_fixture(self, Settings_, settings_): - settings_elm = element('w:settings') + settings_elm = element("w:settings") settings_part = SettingsPart(None, None, settings_elm, None) return settings_part, Settings_, settings_ @@ -58,7 +57,7 @@ def settings_fixture(self, Settings_, settings_): @pytest.fixture def load_(self, request): - return method_mock(request, SettingsPart, 'load', autospec=False) + return method_mock(request, SettingsPart, "load", autospec=False) @pytest.fixture def package_(self, request): @@ -67,7 +66,7 @@ def package_(self, request): @pytest.fixture def Settings_(self, request, settings_): return class_mock( - request, 'docx.parts.settings.Settings', return_value=settings_ + request, "docx.parts.settings.Settings", return_value=settings_ ) @pytest.fixture diff --git a/tests/parts/test_story.py b/tests/parts/test_story.py index e42fc49a..67154758 100644 --- a/tests/parts/test_story.py +++ b/tests/parts/test_story.py @@ -21,7 +21,6 @@ class DescribeBaseStoryPart(object): - def it_can_get_or_add_an_image(self, package_, image_part_, image_, relate_to_): package_.get_or_add_image_part.return_value = image_part_ relate_to_.return_value = "rId42" diff --git a/tests/parts/test_styles.py b/tests/parts/test_styles.py index 8ff60035..0f2a7b11 100644 --- a/tests/parts/test_styles.py +++ b/tests/parts/test_styles.py @@ -18,7 +18,6 @@ class DescribeStylesPart(object): - def it_provides_access_to_its_styles(self, styles_fixture): styles_part, Styles_, styles_ = styles_fixture styles = styles_part.styles @@ -29,7 +28,7 @@ def it_can_construct_a_default_styles_part_to_help(self): package = OpcPackage() styles_part = StylesPart.default(package) assert isinstance(styles_part, StylesPart) - assert styles_part.partname == '/word/styles.xml' + assert styles_part.partname == "/word/styles.xml" assert styles_part.content_type == CT.WML_STYLES assert styles_part.package is package assert len(styles_part.element) == 6 @@ -45,9 +44,7 @@ def styles_fixture(self, Styles_, styles_elm_, styles_): @pytest.fixture def Styles_(self, request, styles_): - return class_mock( - request, 'docx.parts.styles.Styles', return_value=styles_ - ) + return class_mock(request, "docx.parts.styles.Styles", return_value=styles_) @pytest.fixture def styles_(self, request): diff --git a/tests/styles/test_latent.py b/tests/styles/test_latent.py index f42214cf..ee4bead8 100644 --- a/tests/styles/test_latent.py +++ b/tests/styles/test_latent.py @@ -4,9 +4,7 @@ Unit test suite for the docx.styles.latent module """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals import pytest @@ -16,7 +14,6 @@ class DescribeLatentStyle(object): - def it_can_delete_itself(self, delete_fixture): latent_style, latent_styles, expected_xml = delete_fixture latent_style.delete() @@ -50,77 +47,87 @@ def it_can_change_its_on_off_properties(self, on_off_set_fixture): @pytest.fixture def delete_fixture(self): - latent_styles = element('w:latentStyles/w:lsdException{w:name=Foo}') + latent_styles = element("w:latentStyles/w:lsdException{w:name=Foo}") latent_style = _LatentStyle(latent_styles[0]) - expected_xml = xml('w:latentStyles') + expected_xml = xml("w:latentStyles") return latent_style, latent_styles, expected_xml - @pytest.fixture(params=[ - ('w:lsdException{w:name=heading 1}', 'Heading 1'), - ]) + @pytest.fixture( + params=[ + ("w:lsdException{w:name=heading 1}", "Heading 1"), + ] + ) def name_get_fixture(self, request): lsdException_cxml, expected_value = request.param latent_style = _LatentStyle(element(lsdException_cxml)) return latent_style, expected_value - @pytest.fixture(params=[ - ('w:lsdException', 'hidden', None), - ('w:lsdException', 'locked', None), - ('w:lsdException', 'quick_style', None), - ('w:lsdException', 'unhide_when_used', None), - ('w:lsdException{w:semiHidden=1}', 'hidden', True), - ('w:lsdException{w:locked=1}', 'locked', True), - ('w:lsdException{w:qFormat=1}', 'quick_style', True), - ('w:lsdException{w:unhideWhenUsed=1}', 'unhide_when_used', True), - ('w:lsdException{w:semiHidden=0}', 'hidden', False), - ('w:lsdException{w:locked=0}', 'locked', False), - ('w:lsdException{w:qFormat=0}', 'quick_style', False), - ('w:lsdException{w:unhideWhenUsed=0}', 'unhide_when_used', False), - ]) + @pytest.fixture( + params=[ + ("w:lsdException", "hidden", None), + ("w:lsdException", "locked", None), + ("w:lsdException", "quick_style", None), + ("w:lsdException", "unhide_when_used", None), + ("w:lsdException{w:semiHidden=1}", "hidden", True), + ("w:lsdException{w:locked=1}", "locked", True), + ("w:lsdException{w:qFormat=1}", "quick_style", True), + ("w:lsdException{w:unhideWhenUsed=1}", "unhide_when_used", True), + ("w:lsdException{w:semiHidden=0}", "hidden", False), + ("w:lsdException{w:locked=0}", "locked", False), + ("w:lsdException{w:qFormat=0}", "quick_style", False), + ("w:lsdException{w:unhideWhenUsed=0}", "unhide_when_used", False), + ] + ) def on_off_get_fixture(self, request): lsdException_cxml, prop_name, expected_value = request.param latent_style = _LatentStyle(element(lsdException_cxml)) return latent_style, prop_name, expected_value - @pytest.fixture(params=[ - ('w:lsdException', 'hidden', True, - 'w:lsdException{w:semiHidden=1}'), - ('w:lsdException{w:semiHidden=1}', 'hidden', False, - 'w:lsdException{w:semiHidden=0}'), - ('w:lsdException{w:semiHidden=0}', 'hidden', None, - 'w:lsdException'), - ('w:lsdException', 'locked', True, - 'w:lsdException{w:locked=1}'), - ('w:lsdException', 'quick_style', False, - 'w:lsdException{w:qFormat=0}'), - ('w:lsdException', 'unhide_when_used', True, - 'w:lsdException{w:unhideWhenUsed=1}'), - ('w:lsdException{w:locked=1}', 'locked', None, - 'w:lsdException'), - ]) + @pytest.fixture( + params=[ + ("w:lsdException", "hidden", True, "w:lsdException{w:semiHidden=1}"), + ( + "w:lsdException{w:semiHidden=1}", + "hidden", + False, + "w:lsdException{w:semiHidden=0}", + ), + ("w:lsdException{w:semiHidden=0}", "hidden", None, "w:lsdException"), + ("w:lsdException", "locked", True, "w:lsdException{w:locked=1}"), + ("w:lsdException", "quick_style", False, "w:lsdException{w:qFormat=0}"), + ( + "w:lsdException", + "unhide_when_used", + True, + "w:lsdException{w:unhideWhenUsed=1}", + ), + ("w:lsdException{w:locked=1}", "locked", None, "w:lsdException"), + ] + ) def on_off_set_fixture(self, request): lsdException_cxml, prop_name, value, expected_cxml = request.param latent_styles = _LatentStyle(element(lsdException_cxml)) expected_xml = xml(expected_cxml) return latent_styles, prop_name, value, expected_xml - @pytest.fixture(params=[ - ('w:lsdException', None), - ('w:lsdException{w:uiPriority=42}', 42), - ]) + @pytest.fixture( + params=[ + ("w:lsdException", None), + ("w:lsdException{w:uiPriority=42}", 42), + ] + ) def priority_get_fixture(self, request): lsdException_cxml, expected_value = request.param latent_style = _LatentStyle(element(lsdException_cxml)) return latent_style, expected_value - @pytest.fixture(params=[ - ('w:lsdException', 42, - 'w:lsdException{w:uiPriority=42}'), - ('w:lsdException{w:uiPriority=42}', 24, - 'w:lsdException{w:uiPriority=24}'), - ('w:lsdException{w:uiPriority=24}', None, - 'w:lsdException'), - ]) + @pytest.fixture( + params=[ + ("w:lsdException", 42, "w:lsdException{w:uiPriority=42}"), + ("w:lsdException{w:uiPriority=42}", 24, "w:lsdException{w:uiPriority=24}"), + ("w:lsdException{w:uiPriority=24}", None, "w:lsdException"), + ] + ) def priority_set_fixture(self, request): lsdException_cxml, new_value, expected_cxml = request.param latent_style = _LatentStyle(element(lsdException_cxml)) @@ -129,7 +136,6 @@ def priority_set_fixture(self, request): class DescribeLatentStyles(object): - def it_can_add_a_latent_style(self, add_fixture): latent_styles, name, expected_xml = add_fixture @@ -193,79 +199,113 @@ def it_can_change_its_boolean_properties(self, bool_prop_set_fixture): @pytest.fixture def add_fixture(self): - latent_styles = LatentStyles(element('w:latentStyles')) - name = 'Heading 1' - expected_xml = xml('w:latentStyles/w:lsdException{w:name=heading 1}') + latent_styles = LatentStyles(element("w:latentStyles")) + name = "Heading 1" + expected_xml = xml("w:latentStyles/w:lsdException{w:name=heading 1}") return latent_styles, name, expected_xml - @pytest.fixture(params=[ - ('w:latentStyles', 'default_to_hidden', False), - ('w:latentStyles', 'default_to_locked', False), - ('w:latentStyles', 'default_to_quick_style', False), - ('w:latentStyles', 'default_to_unhide_when_used', False), - ('w:latentStyles{w:defSemiHidden=1}', - 'default_to_hidden', True), - ('w:latentStyles{w:defLockedState=0}', - 'default_to_locked', False), - ('w:latentStyles{w:defQFormat=on}', - 'default_to_quick_style', True), - ('w:latentStyles{w:defUnhideWhenUsed=false}', - 'default_to_unhide_when_used', False), - ]) + @pytest.fixture( + params=[ + ("w:latentStyles", "default_to_hidden", False), + ("w:latentStyles", "default_to_locked", False), + ("w:latentStyles", "default_to_quick_style", False), + ("w:latentStyles", "default_to_unhide_when_used", False), + ("w:latentStyles{w:defSemiHidden=1}", "default_to_hidden", True), + ("w:latentStyles{w:defLockedState=0}", "default_to_locked", False), + ("w:latentStyles{w:defQFormat=on}", "default_to_quick_style", True), + ( + "w:latentStyles{w:defUnhideWhenUsed=false}", + "default_to_unhide_when_used", + False, + ), + ] + ) def bool_prop_get_fixture(self, request): latentStyles_cxml, prop_name, expected_value = request.param latent_styles = LatentStyles(element(latentStyles_cxml)) return latent_styles, prop_name, expected_value - @pytest.fixture(params=[ - ('w:latentStyles', 'default_to_hidden', True, - 'w:latentStyles{w:defSemiHidden=1}'), - ('w:latentStyles', 'default_to_locked', False, - 'w:latentStyles{w:defLockedState=0}'), - ('w:latentStyles', 'default_to_quick_style', True, - 'w:latentStyles{w:defQFormat=1}'), - ('w:latentStyles', 'default_to_unhide_when_used', False, - 'w:latentStyles{w:defUnhideWhenUsed=0}'), - ('w:latentStyles{w:defSemiHidden=0}', 'default_to_hidden', 'Foo', - 'w:latentStyles{w:defSemiHidden=1}'), - ('w:latentStyles{w:defLockedState=1}', 'default_to_locked', None, - 'w:latentStyles{w:defLockedState=0}'), - ]) + @pytest.fixture( + params=[ + ( + "w:latentStyles", + "default_to_hidden", + True, + "w:latentStyles{w:defSemiHidden=1}", + ), + ( + "w:latentStyles", + "default_to_locked", + False, + "w:latentStyles{w:defLockedState=0}", + ), + ( + "w:latentStyles", + "default_to_quick_style", + True, + "w:latentStyles{w:defQFormat=1}", + ), + ( + "w:latentStyles", + "default_to_unhide_when_used", + False, + "w:latentStyles{w:defUnhideWhenUsed=0}", + ), + ( + "w:latentStyles{w:defSemiHidden=0}", + "default_to_hidden", + "Foo", + "w:latentStyles{w:defSemiHidden=1}", + ), + ( + "w:latentStyles{w:defLockedState=1}", + "default_to_locked", + None, + "w:latentStyles{w:defLockedState=0}", + ), + ] + ) def bool_prop_set_fixture(self, request): latentStyles_cxml, prop_name, value, expected_cxml = request.param latent_styles = LatentStyles(element(latentStyles_cxml)) expected_xml = xml(expected_cxml) return latent_styles, prop_name, value, expected_xml - @pytest.fixture(params=[ - ('w:latentStyles', None), - ('w:latentStyles{w:count=42}', 42), - ]) + @pytest.fixture( + params=[ + ("w:latentStyles", None), + ("w:latentStyles{w:count=42}", 42), + ] + ) def count_get_fixture(self, request): latentStyles_cxml, expected_value = request.param latent_styles = LatentStyles(element(latentStyles_cxml)) return latent_styles, expected_value - @pytest.fixture(params=[ - ('w:latentStyles', 42, 'w:latentStyles{w:count=42}'), - ('w:latentStyles{w:count=24}', 42, 'w:latentStyles{w:count=42}'), - ('w:latentStyles{w:count=24}', None, 'w:latentStyles'), - ]) + @pytest.fixture( + params=[ + ("w:latentStyles", 42, "w:latentStyles{w:count=42}"), + ("w:latentStyles{w:count=24}", 42, "w:latentStyles{w:count=42}"), + ("w:latentStyles{w:count=24}", None, "w:latentStyles"), + ] + ) def count_set_fixture(self, request): latentStyles_cxml, value, expected_cxml = request.param latent_styles = LatentStyles(element(latentStyles_cxml)) expected_xml = xml(expected_cxml) return latent_styles, value, expected_xml - @pytest.fixture(params=[ - ('w:lsdException{w:name=Ab},w:lsdException,w:lsdException', 'Ab', 0), - ('w:lsdException,w:lsdException{w:name=Cd},w:lsdException', 'Cd', 1), - ('w:lsdException,w:lsdException,w:lsdException{w:name=Ef}', 'Ef', 2), - ('w:lsdException{w:name=heading 1}', 'Heading 1', 0), - ]) + @pytest.fixture( + params=[ + ("w:lsdException{w:name=Ab},w:lsdException,w:lsdException", "Ab", 0), + ("w:lsdException,w:lsdException{w:name=Cd},w:lsdException", "Cd", 1), + ("w:lsdException,w:lsdException,w:lsdException{w:name=Ef}", "Ef", 2), + ("w:lsdException{w:name=heading 1}", "Heading 1", 0), + ] + ) def getitem_fixture(self, request): cxml, name, idx = request.param - latentStyles_cxml = 'w:latentStyles/(%s)' % cxml + latentStyles_cxml = "w:latentStyles/(%s)" % cxml latentStyles = element(latentStyles_cxml) lsdException = latentStyles[idx] latent_styles = LatentStyles(latentStyles) @@ -273,46 +313,55 @@ def getitem_fixture(self, request): @pytest.fixture def getitem_raises_fixture(self): - latent_styles = LatentStyles(element('w:latentStyles')) - return latent_styles, 'Foobar' - - @pytest.fixture(params=[ - ('w:latentStyles', 0), - ('w:latentStyles/w:lsdException', 1), - ('w:latentStyles/(w:lsdException,w:lsdException)', 2), - ]) + latent_styles = LatentStyles(element("w:latentStyles")) + return latent_styles, "Foobar" + + @pytest.fixture( + params=[ + ("w:latentStyles", 0), + ("w:latentStyles/w:lsdException", 1), + ("w:latentStyles/(w:lsdException,w:lsdException)", 2), + ] + ) def iter_fixture(self, request): latentStyles_cxml, count = request.param latent_styles = LatentStyles(element(latentStyles_cxml)) return latent_styles, count - @pytest.fixture(params=[ - ('w:latentStyles', 0), - ('w:latentStyles/w:lsdException', 1), - ('w:latentStyles/(w:lsdException,w:lsdException)', 2), - ]) + @pytest.fixture( + params=[ + ("w:latentStyles", 0), + ("w:latentStyles/w:lsdException", 1), + ("w:latentStyles/(w:lsdException,w:lsdException)", 2), + ] + ) def len_fixture(self, request): latentStyles_cxml, count = request.param latent_styles = LatentStyles(element(latentStyles_cxml)) return latent_styles, count - @pytest.fixture(params=[ - ('w:latentStyles', None), - ('w:latentStyles{w:defUIPriority=42}', 42), - ]) + @pytest.fixture( + params=[ + ("w:latentStyles", None), + ("w:latentStyles{w:defUIPriority=42}", 42), + ] + ) def priority_get_fixture(self, request): latentStyles_cxml, expected_value = request.param latent_styles = LatentStyles(element(latentStyles_cxml)) return latent_styles, expected_value - @pytest.fixture(params=[ - ('w:latentStyles', 42, - 'w:latentStyles{w:defUIPriority=42}'), - ('w:latentStyles{w:defUIPriority=24}', 42, - 'w:latentStyles{w:defUIPriority=42}'), - ('w:latentStyles{w:defUIPriority=24}', None, - 'w:latentStyles'), - ]) + @pytest.fixture( + params=[ + ("w:latentStyles", 42, "w:latentStyles{w:defUIPriority=42}"), + ( + "w:latentStyles{w:defUIPriority=24}", + 42, + "w:latentStyles{w:defUIPriority=42}", + ), + ("w:latentStyles{w:defUIPriority=24}", None, "w:latentStyles"), + ] + ) def priority_set_fixture(self, request): latentStyles_cxml, value, expected_cxml = request.param latent_styles = LatentStyles(element(latentStyles_cxml)) diff --git a/tests/styles/test_style.py b/tests/styles/test_style.py index 437e390e..caa281db 100644 --- a/tests/styles/test_style.py +++ b/tests/styles/test_style.py @@ -4,16 +4,18 @@ Test suite for the docx.styles.style module """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals import pytest from docx.enum.style import WD_STYLE_TYPE from docx.styles.style import ( - BaseStyle, _CharacterStyle, _ParagraphStyle, _NumberingStyle, - StyleFactory, _TableStyle + BaseStyle, + _CharacterStyle, + _ParagraphStyle, + _NumberingStyle, + StyleFactory, + _TableStyle, ) from docx.text.font import Font from docx.text.parfmt import ParagraphFormat @@ -23,7 +25,6 @@ class DescribeStyleFactory(object): - def it_constructs_the_right_type_of_style(self, factory_fixture): style_elm, StyleCls_, style_ = factory_fixture style = StyleFactory(style_elm) @@ -32,19 +33,27 @@ def it_constructs_the_right_type_of_style(self, factory_fixture): # fixtures ------------------------------------------------------- - @pytest.fixture(params=['paragraph', 'character', 'table', 'numbering']) + @pytest.fixture(params=["paragraph", "character", "table", "numbering"]) def factory_fixture( - self, request, paragraph_style_, _ParagraphStyle_, - character_style_, _CharacterStyle_, table_style_, _TableStyle_, - numbering_style_, _NumberingStyle_): + self, + request, + paragraph_style_, + _ParagraphStyle_, + character_style_, + _CharacterStyle_, + table_style_, + _TableStyle_, + numbering_style_, + _NumberingStyle_, + ): type_attr_val = request.param StyleCls_, style_mock = { - 'paragraph': (_ParagraphStyle_, paragraph_style_), - 'character': (_CharacterStyle_, character_style_), - 'table': (_TableStyle_, table_style_), - 'numbering': (_NumberingStyle_, numbering_style_), + "paragraph": (_ParagraphStyle_, paragraph_style_), + "character": (_CharacterStyle_, character_style_), + "table": (_TableStyle_, table_style_), + "numbering": (_NumberingStyle_, numbering_style_), }[request.param] - style_cxml = 'w:style{w:type=%s}' % type_attr_val + style_cxml = "w:style{w:type=%s}" % type_attr_val style_elm = element(style_cxml) return style_elm, StyleCls_, style_mock @@ -53,8 +62,7 @@ def factory_fixture( @pytest.fixture def _ParagraphStyle_(self, request, paragraph_style_): return class_mock( - request, 'docx.styles.style._ParagraphStyle', - return_value=paragraph_style_ + request, "docx.styles.style._ParagraphStyle", return_value=paragraph_style_ ) @pytest.fixture @@ -64,8 +72,7 @@ def paragraph_style_(self, request): @pytest.fixture def _CharacterStyle_(self, request, character_style_): return class_mock( - request, 'docx.styles.style._CharacterStyle', - return_value=character_style_ + request, "docx.styles.style._CharacterStyle", return_value=character_style_ ) @pytest.fixture @@ -75,8 +82,7 @@ def character_style_(self, request): @pytest.fixture def _TableStyle_(self, request, table_style_): return class_mock( - request, 'docx.styles.style._TableStyle', - return_value=table_style_ + request, "docx.styles.style._TableStyle", return_value=table_style_ ) @pytest.fixture @@ -86,8 +92,7 @@ def table_style_(self, request): @pytest.fixture def _NumberingStyle_(self, request, numbering_style_): return class_mock( - request, 'docx.styles.style._NumberingStyle', - return_value=numbering_style_ + request, "docx.styles.style._NumberingStyle", return_value=numbering_style_ ) @pytest.fixture @@ -96,7 +101,6 @@ def numbering_style_(self, request): class DescribeBaseStyle(object): - def it_knows_its_style_id(self, id_get_fixture): style, expected_value = id_get_fixture assert style.style_id == expected_value @@ -176,11 +180,13 @@ def it_can_delete_itself_from_the_document(self, delete_fixture): # fixture -------------------------------------------------------- - @pytest.fixture(params=[ - ('w:style', True), - ('w:style{w:customStyle=0}', True), - ('w:style{w:customStyle=1}', False), - ]) + @pytest.fixture( + params=[ + ("w:style", True), + ("w:style{w:customStyle=0}", True), + ("w:style{w:customStyle=1}", False), + ] + ) def builtin_get_fixture(self, request): style_cxml, expected_value = request.param style = BaseStyle(element(style_cxml)) @@ -188,186 +194,207 @@ def builtin_get_fixture(self, request): @pytest.fixture def delete_fixture(self): - styles = element('w:styles/w:style') + styles = element("w:styles/w:style") style = BaseStyle(styles[0]) - expected_xml = xml('w:styles') + expected_xml = xml("w:styles") return style, styles, expected_xml - @pytest.fixture(params=[ - ('w:style', False), - ('w:style/w:semiHidden', True), - ('w:style/w:semiHidden{w:val=0}', False), - ('w:style/w:semiHidden{w:val=1}', True), - ]) + @pytest.fixture( + params=[ + ("w:style", False), + ("w:style/w:semiHidden", True), + ("w:style/w:semiHidden{w:val=0}", False), + ("w:style/w:semiHidden{w:val=1}", True), + ] + ) def hidden_get_fixture(self, request): style_cxml, expected_value = request.param style = BaseStyle(element(style_cxml)) return style, expected_value - @pytest.fixture(params=[ - ('w:style', True, 'w:style/w:semiHidden'), - ('w:style/w:semiHidden{w:val=0}', True, 'w:style/w:semiHidden'), - ('w:style/w:semiHidden{w:val=1}', True, 'w:style/w:semiHidden'), - ('w:style', False, 'w:style'), - ('w:style/w:semiHidden', False, 'w:style'), - ('w:style/w:semiHidden{w:val=1}', False, 'w:style'), - ]) + @pytest.fixture( + params=[ + ("w:style", True, "w:style/w:semiHidden"), + ("w:style/w:semiHidden{w:val=0}", True, "w:style/w:semiHidden"), + ("w:style/w:semiHidden{w:val=1}", True, "w:style/w:semiHidden"), + ("w:style", False, "w:style"), + ("w:style/w:semiHidden", False, "w:style"), + ("w:style/w:semiHidden{w:val=1}", False, "w:style"), + ] + ) def hidden_set_fixture(self, request): style_cxml, value, expected_cxml = request.param style = BaseStyle(element(style_cxml)) expected_xml = xml(expected_cxml) return style, value, expected_xml - @pytest.fixture(params=[ - ('w:style', None), - ('w:style{w:styleId=Foobar}', 'Foobar'), - ]) + @pytest.fixture( + params=[ + ("w:style", None), + ("w:style{w:styleId=Foobar}", "Foobar"), + ] + ) def id_get_fixture(self, request): style_cxml, expected_value = request.param style = BaseStyle(element(style_cxml)) return style, expected_value - @pytest.fixture(params=[ - ('w:style', 'Foo', 'w:style{w:styleId=Foo}'), - ('w:style{w:styleId=Foo}', 'Bar', 'w:style{w:styleId=Bar}'), - ('w:style{w:styleId=Bar}', None, 'w:style'), - ('w:style', None, 'w:style'), - ]) + @pytest.fixture( + params=[ + ("w:style", "Foo", "w:style{w:styleId=Foo}"), + ("w:style{w:styleId=Foo}", "Bar", "w:style{w:styleId=Bar}"), + ("w:style{w:styleId=Bar}", None, "w:style"), + ("w:style", None, "w:style"), + ] + ) def id_set_fixture(self, request): style_cxml, new_value, expected_style_cxml = request.param style = BaseStyle(element(style_cxml)) expected_xml = xml(expected_style_cxml) return style, new_value, expected_xml - @pytest.fixture(params=[ - ('w:style', False), - ('w:style/w:locked', True), - ('w:style/w:locked{w:val=0}', False), - ('w:style/w:locked{w:val=1}', True), - ]) + @pytest.fixture( + params=[ + ("w:style", False), + ("w:style/w:locked", True), + ("w:style/w:locked{w:val=0}", False), + ("w:style/w:locked{w:val=1}", True), + ] + ) def locked_get_fixture(self, request): style_cxml, expected_value = request.param style = BaseStyle(element(style_cxml)) return style, expected_value - @pytest.fixture(params=[ - ('w:style', True, 'w:style/w:locked'), - ('w:style/w:locked{w:val=0}', True, 'w:style/w:locked'), - ('w:style/w:locked{w:val=1}', True, 'w:style/w:locked'), - ('w:style', False, 'w:style'), - ('w:style/w:locked', False, 'w:style'), - ('w:style/w:locked{w:val=1}', False, 'w:style'), - ]) + @pytest.fixture( + params=[ + ("w:style", True, "w:style/w:locked"), + ("w:style/w:locked{w:val=0}", True, "w:style/w:locked"), + ("w:style/w:locked{w:val=1}", True, "w:style/w:locked"), + ("w:style", False, "w:style"), + ("w:style/w:locked", False, "w:style"), + ("w:style/w:locked{w:val=1}", False, "w:style"), + ] + ) def locked_set_fixture(self, request): style_cxml, value, expected_cxml = request.param style = BaseStyle(element(style_cxml)) expected_xml = xml(expected_cxml) return style, value, expected_xml - @pytest.fixture(params=[ - ('w:style{w:type=table}', None), - ('w:style{w:type=table}/w:name{w:val=Boofar}', 'Boofar'), - ('w:style{w:type=table}/w:name{w:val=heading 1}', 'Heading 1'), - ]) + @pytest.fixture( + params=[ + ("w:style{w:type=table}", None), + ("w:style{w:type=table}/w:name{w:val=Boofar}", "Boofar"), + ("w:style{w:type=table}/w:name{w:val=heading 1}", "Heading 1"), + ] + ) def name_get_fixture(self, request): style_cxml, expected_value = request.param style = BaseStyle(element(style_cxml)) return style, expected_value - @pytest.fixture(params=[ - ('w:style', 'Foo', 'w:style/w:name{w:val=Foo}'), - ('w:style/w:name{w:val=Foo}', 'Bar', 'w:style/w:name{w:val=Bar}'), - ('w:style/w:name{w:val=Bar}', None, 'w:style'), - ]) + @pytest.fixture( + params=[ + ("w:style", "Foo", "w:style/w:name{w:val=Foo}"), + ("w:style/w:name{w:val=Foo}", "Bar", "w:style/w:name{w:val=Bar}"), + ("w:style/w:name{w:val=Bar}", None, "w:style"), + ] + ) def name_set_fixture(self, request): style_cxml, new_value, expected_style_cxml = request.param style = BaseStyle(element(style_cxml)) expected_xml = xml(expected_style_cxml) return style, new_value, expected_xml - @pytest.fixture(params=[ - ('w:style', None), - ('w:style/w:uiPriority{w:val=42}', 42), - ]) + @pytest.fixture( + params=[ + ("w:style", None), + ("w:style/w:uiPriority{w:val=42}", 42), + ] + ) def priority_get_fixture(self, request): style_cxml, expected_value = request.param style = BaseStyle(element(style_cxml)) return style, expected_value - @pytest.fixture(params=[ - ('w:style', 42, - 'w:style/w:uiPriority{w:val=42}'), - ('w:style/w:uiPriority{w:val=42}', 24, - 'w:style/w:uiPriority{w:val=24}'), - ('w:style/w:uiPriority{w:val=24}', None, - 'w:style'), - ]) + @pytest.fixture( + params=[ + ("w:style", 42, "w:style/w:uiPriority{w:val=42}"), + ("w:style/w:uiPriority{w:val=42}", 24, "w:style/w:uiPriority{w:val=24}"), + ("w:style/w:uiPriority{w:val=24}", None, "w:style"), + ] + ) def priority_set_fixture(self, request): style_cxml, value, expected_cxml = request.param style = BaseStyle(element(style_cxml)) expected_xml = xml(expected_cxml) return style, value, expected_xml - @pytest.fixture(params=[ - ('w:style', False), - ('w:style/w:qFormat', True), - ('w:style/w:qFormat{w:val=0}', False), - ('w:style/w:qFormat{w:val=on}', True), - ]) + @pytest.fixture( + params=[ + ("w:style", False), + ("w:style/w:qFormat", True), + ("w:style/w:qFormat{w:val=0}", False), + ("w:style/w:qFormat{w:val=on}", True), + ] + ) def quick_get_fixture(self, request): style_cxml, expected_value = request.param style = BaseStyle(element(style_cxml)) return style, expected_value - @pytest.fixture(params=[ - ('w:style', True, 'w:style/w:qFormat'), - ('w:style/w:qFormat', False, 'w:style'), - ('w:style/w:qFormat', True, 'w:style/w:qFormat'), - ('w:style/w:qFormat{w:val=0}', False, 'w:style'), - ('w:style/w:qFormat{w:val=on}', True, 'w:style/w:qFormat'), - ]) + @pytest.fixture( + params=[ + ("w:style", True, "w:style/w:qFormat"), + ("w:style/w:qFormat", False, "w:style"), + ("w:style/w:qFormat", True, "w:style/w:qFormat"), + ("w:style/w:qFormat{w:val=0}", False, "w:style"), + ("w:style/w:qFormat{w:val=on}", True, "w:style/w:qFormat"), + ] + ) def quick_set_fixture(self, request): style_cxml, new_value, expected_style_cxml = request.param style = BaseStyle(element(style_cxml)) expected_xml = xml(expected_style_cxml) return style, new_value, expected_xml - @pytest.fixture(params=[ - ('w:style', WD_STYLE_TYPE.PARAGRAPH), - ('w:style{w:type=paragraph}', WD_STYLE_TYPE.PARAGRAPH), - ('w:style{w:type=character}', WD_STYLE_TYPE.CHARACTER), - ('w:style{w:type=numbering}', WD_STYLE_TYPE.LIST), - ]) + @pytest.fixture( + params=[ + ("w:style", WD_STYLE_TYPE.PARAGRAPH), + ("w:style{w:type=paragraph}", WD_STYLE_TYPE.PARAGRAPH), + ("w:style{w:type=character}", WD_STYLE_TYPE.CHARACTER), + ("w:style{w:type=numbering}", WD_STYLE_TYPE.LIST), + ] + ) def type_get_fixture(self, request): style_cxml, expected_value = request.param style = BaseStyle(element(style_cxml)) return style, expected_value - @pytest.fixture(params=[ - ('w:style', False), - ('w:style/w:unhideWhenUsed', True), - ('w:style/w:unhideWhenUsed{w:val=0}', False), - ('w:style/w:unhideWhenUsed{w:val=1}', True), - ]) + @pytest.fixture( + params=[ + ("w:style", False), + ("w:style/w:unhideWhenUsed", True), + ("w:style/w:unhideWhenUsed{w:val=0}", False), + ("w:style/w:unhideWhenUsed{w:val=1}", True), + ] + ) def unhide_get_fixture(self, request): style_cxml, expected_value = request.param style = BaseStyle(element(style_cxml)) return style, expected_value - @pytest.fixture(params=[ - ('w:style', True, - 'w:style/w:unhideWhenUsed'), - ('w:style/w:unhideWhenUsed', False, - 'w:style'), - ('w:style/w:unhideWhenUsed{w:val=0}', True, - 'w:style/w:unhideWhenUsed'), - ('w:style/w:unhideWhenUsed{w:val=1}', True, - 'w:style/w:unhideWhenUsed'), - ('w:style/w:unhideWhenUsed{w:val=1}', False, - 'w:style'), - ('w:style', False, - 'w:style'), - ]) + @pytest.fixture( + params=[ + ("w:style", True, "w:style/w:unhideWhenUsed"), + ("w:style/w:unhideWhenUsed", False, "w:style"), + ("w:style/w:unhideWhenUsed{w:val=0}", True, "w:style/w:unhideWhenUsed"), + ("w:style/w:unhideWhenUsed{w:val=1}", True, "w:style/w:unhideWhenUsed"), + ("w:style/w:unhideWhenUsed{w:val=1}", False, "w:style"), + ("w:style", False, "w:style"), + ] + ) def unhide_set_fixture(self, request): style_cxml, value, expected_cxml = request.param style = BaseStyle(element(style_cxml)) @@ -376,11 +403,8 @@ def unhide_set_fixture(self, request): class Describe_CharacterStyle(object): - def it_knows_which_style_it_is_based_on(self, base_get_fixture): - style, StyleFactory_, StyleFactory_calls, base_style_ = ( - base_get_fixture - ) + style, StyleFactory_, StyleFactory_calls, base_style_ = base_get_fixture base_style = style.base_style assert StyleFactory_.call_args_list == StyleFactory_calls @@ -399,14 +423,13 @@ def it_provides_access_to_its_font(self, font_fixture): # fixture -------------------------------------------------------- - @pytest.fixture(params=[ - ('w:styles/(w:style{w:styleId=Foo},w:style/w:basedOn{w:val=Foo})', - 1, 0), - ('w:styles/(w:style{w:styleId=Foo},w:style/w:basedOn{w:val=Bar})', - 1, -1), - ('w:styles/w:style', - 0, -1), - ]) + @pytest.fixture( + params=[ + ("w:styles/(w:style{w:styleId=Foo},w:style/w:basedOn{w:val=Foo})", 1, 0), + ("w:styles/(w:style{w:styleId=Foo},w:style/w:basedOn{w:val=Bar})", 1, -1), + ("w:styles/w:style", 0, -1), + ] + ) def base_get_fixture(self, request, StyleFactory_): styles_cxml, style_idx, base_style_idx = request.param styles = element(styles_cxml) @@ -420,14 +443,13 @@ def base_get_fixture(self, request, StyleFactory_): expected_value = None return style, StyleFactory_, StyleFactory_calls, expected_value - @pytest.fixture(params=[ - ('w:style', 'Foo', - 'w:style/w:basedOn{w:val=Foo}'), - ('w:style/w:basedOn{w:val=Foo}', 'Bar', - 'w:style/w:basedOn{w:val=Bar}'), - ('w:style/w:basedOn{w:val=Bar}', None, - 'w:style'), - ]) + @pytest.fixture( + params=[ + ("w:style", "Foo", "w:style/w:basedOn{w:val=Foo}"), + ("w:style/w:basedOn{w:val=Foo}", "Bar", "w:style/w:basedOn{w:val=Bar}"), + ("w:style/w:basedOn{w:val=Bar}", None, "w:style"), + ] + ) def base_set_fixture(self, request, style_): style_cxml, base_style_id, expected_style_cxml = request.param style = _CharacterStyle(element(style_cxml)) @@ -438,16 +460,14 @@ def base_set_fixture(self, request, style_): @pytest.fixture def font_fixture(self, Font_, font_): - style = _CharacterStyle(element('w:style')) + style = _CharacterStyle(element("w:style")) return style, Font_, font_ # fixture components --------------------------------------------- @pytest.fixture def Font_(self, request, font_): - return class_mock( - request, 'docx.styles.style.Font', return_value=font_ - ) + return class_mock(request, "docx.styles.style.Font", return_value=font_) @pytest.fixture def font_(self, request): @@ -459,11 +479,10 @@ def style_(self, request): @pytest.fixture def StyleFactory_(self, request): - return function_mock(request, 'docx.styles.style.StyleFactory') + return function_mock(request, "docx.styles.style.StyleFactory") class Describe_ParagraphStyle(object): - def it_knows_its_next_paragraph_style(self, next_get_fixture): style, expected_value = next_get_fixture assert style.next_paragraph_style == expected_value @@ -481,56 +500,61 @@ def it_provides_access_to_its_paragraph_format(self, parfmt_fixture): # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - ('H1', 'Body'), - ('H2', 'H2'), - ('Body', 'Body'), - ('Foo', 'Foo'), - ]) + @pytest.fixture( + params=[ + ("H1", "Body"), + ("H2", "H2"), + ("Body", "Body"), + ("Foo", "Foo"), + ] + ) def next_get_fixture(self, request): style_name, next_style_name = request.param styles = element( - 'w:styles/(' - 'w:style{w:type=paragraph,w:styleId=H1}/w:next{w:val=Body},' - 'w:style{w:type=paragraph,w:styleId=H2}/w:next{w:val=Char},' - 'w:style{w:type=paragraph,w:styleId=Body},' - 'w:style{w:type=paragraph,w:styleId=Foo}/w:next{w:val=Bar},' - 'w:style{w:type=character,w:styleId=Char})' + "w:styles/(" + "w:style{w:type=paragraph,w:styleId=H1}/w:next{w:val=Body}," + "w:style{w:type=paragraph,w:styleId=H2}/w:next{w:val=Char}," + "w:style{w:type=paragraph,w:styleId=Body}," + "w:style{w:type=paragraph,w:styleId=Foo}/w:next{w:val=Bar}," + "w:style{w:type=character,w:styleId=Char})" ) - style_names = ['H1', 'H2', 'Body', 'Foo', 'Char'] + style_names = ["H1", "H2", "Body", "Foo", "Char"] style_elm = styles[style_names.index(style_name)] next_style_elm = styles[style_names.index(next_style_name)] style = _ParagraphStyle(style_elm) - if style_name == 'H1': + if style_name == "H1": next_style = _ParagraphStyle(next_style_elm) else: next_style = style return style, next_style - @pytest.fixture(params=[ - ('H', 'B', 'w:style{w:type=paragraph,w:styleId=H}/w:next{w:val=B}'), - ('H', None, 'w:style{w:type=paragraph,w:styleId=H}'), - ('H', 'H', 'w:style{w:type=paragraph,w:styleId=H}'), - ]) + @pytest.fixture( + params=[ + ("H", "B", "w:style{w:type=paragraph,w:styleId=H}/w:next{w:val=B}"), + ("H", None, "w:style{w:type=paragraph,w:styleId=H}"), + ("H", "H", "w:style{w:type=paragraph,w:styleId=H}"), + ] + ) def next_set_fixture(self, request): style_name, next_style_name, style_cxml = request.param styles = element( - 'w:styles/(' - 'w:style{w:type=paragraph,w:styleId=H},' - 'w:style{w:type=paragraph,w:styleId=B})' + "w:styles/(" + "w:style{w:type=paragraph,w:styleId=H}," + "w:style{w:type=paragraph,w:styleId=B})" ) - style_elms = {'H': styles[0], 'B': styles[1]} + style_elms = {"H": styles[0], "B": styles[1]} style = _ParagraphStyle(style_elms[style_name]) next_style = ( - None if next_style_name is None else - _ParagraphStyle(style_elms[next_style_name]) + None + if next_style_name is None + else _ParagraphStyle(style_elms[next_style_name]) ) expected_xml = xml(style_cxml) return style, next_style, expected_xml @pytest.fixture def parfmt_fixture(self, ParagraphFormat_, paragraph_format_): - style = _ParagraphStyle(element('w:style')) + style = _ParagraphStyle(element("w:style")) return style, ParagraphFormat_, paragraph_format_ # fixture components --------------------------------------------- @@ -538,8 +562,7 @@ def parfmt_fixture(self, ParagraphFormat_, paragraph_format_): @pytest.fixture def ParagraphFormat_(self, request, paragraph_format_): return class_mock( - request, 'docx.styles.style.ParagraphFormat', - return_value=paragraph_format_ + request, "docx.styles.style.ParagraphFormat", return_value=paragraph_format_ ) @pytest.fixture diff --git a/tests/styles/test_styles.py b/tests/styles/test_styles.py index 650acf34..c01d2138 100644 --- a/tests/styles/test_styles.py +++ b/tests/styles/test_styles.py @@ -13,13 +13,10 @@ from docx.styles.styles import Styles from ..unitutil.cxml import element -from ..unitutil.mock import ( - call, class_mock, function_mock, instance_mock, method_mock -) +from ..unitutil.mock import call, class_mock, function_mock, instance_mock, method_mock class DescribeStyles(object): - def it_supports_the_in_operator_on_style_name(self, in_fixture): styles, name, expected_value = in_fixture assert (name in styles) is expected_value @@ -29,9 +26,7 @@ def it_knows_its_length(self, len_fixture): assert len(styles) == expected_value def it_can_iterate_over_its_styles(self, iter_fixture): - styles, expected_count, style_, StyleFactory_, expected_calls = ( - iter_fixture - ) + styles, expected_count, style_, StyleFactory_, expected_calls = iter_fixture count = 0 for style in styles: assert style is style_ @@ -39,7 +34,7 @@ def it_can_iterate_over_its_styles(self, iter_fixture): assert count == expected_count assert StyleFactory_.call_args_list == expected_calls - @pytest.mark.filterwarnings('ignore::UserWarning') + @pytest.mark.filterwarnings("ignore::UserWarning") def it_can_get_a_style_by_id(self, getitem_id_fixture): styles, key, expected_element = getitem_id_fixture style = styles[key] @@ -144,7 +139,7 @@ def it_gets_a_style_by_id_to_help(self, _get_by_id_fixture): def it_gets_a_style_id_from_a_name_to_help( self, _getitem_, _get_style_id_from_style_, style_ ): - style_name, style_type, style_id_ = 'Foo Bar', 1, 'FooBar' + style_name, style_type, style_id_ = "Foo Bar", 1, "FooBar" _getitem_.return_value = style_ _get_style_id_from_style_.return_value = style_id_ styles = Styles(None) @@ -176,37 +171,53 @@ def it_provides_access_to_the_latent_styles(self, latent_styles_fixture): # fixture -------------------------------------------------------- - @pytest.fixture(params=[ - ('Foo Bar', 'Foo Bar', WD_STYLE_TYPE.CHARACTER, False), - ('Heading 1', 'heading 1', WD_STYLE_TYPE.PARAGRAPH, True), - ]) - def add_fixture(self, request, styles_elm_, _getitem_, style_elm_, - StyleFactory_, style_): + @pytest.fixture( + params=[ + ("Foo Bar", "Foo Bar", WD_STYLE_TYPE.CHARACTER, False), + ("Heading 1", "heading 1", WD_STYLE_TYPE.PARAGRAPH, True), + ] + ) + def add_fixture( + self, request, styles_elm_, _getitem_, style_elm_, StyleFactory_, style_ + ): name, name_, style_type, builtin = request.param styles = Styles(styles_elm_) _getitem_.return_value = None styles_elm_.add_style_of_type.return_value = style_elm_ StyleFactory_.return_value = style_ return ( - styles, name, style_type, builtin, name_, StyleFactory_, - style_elm_, style_ + styles, + name, + style_type, + builtin, + name_, + StyleFactory_, + style_elm_, + style_, ) @pytest.fixture def add_raises_fixture(self, _getitem_): - styles = Styles(element('w:styles/w:style/w:name{w:val=heading 1}')) - name = 'Heading 1' + styles = Styles(element("w:styles/w:style/w:name{w:val=heading 1}")) + name = "Heading 1" return styles, name - @pytest.fixture(params=[ - ('w:styles', - False, WD_STYLE_TYPE.CHARACTER), - ('w:styles/w:style{w:type=paragraph,w:default=1}', - True, WD_STYLE_TYPE.PARAGRAPH), - ('w:styles/(w:style{w:type=table,w:default=1},w:style{w:type=table,w' - ':default=1})', - True, WD_STYLE_TYPE.TABLE), - ]) + @pytest.fixture( + params=[ + ("w:styles", False, WD_STYLE_TYPE.CHARACTER), + ( + "w:styles/w:style{w:type=paragraph,w:default=1}", + True, + WD_STYLE_TYPE.PARAGRAPH, + ), + ( + "w:styles/(w:style{w:type=table,w:default=1},w:style{w:type=table,w" + ":default=1})", + True, + WD_STYLE_TYPE.TABLE, + ), + ] + ) def default_fixture(self, request, StyleFactory_, style_): styles_cxml, is_defined, style_type = request.param styles_elm = element(styles_cxml) @@ -214,70 +225,89 @@ def default_fixture(self, request, StyleFactory_, style_): StyleFactory_calls = [call(styles_elm[-1])] if is_defined else [] StyleFactory_.return_value = style_ expected_value = style_ if is_defined else None - return ( - styles, style_type, StyleFactory_, StyleFactory_calls, - expected_value - ) - - @pytest.fixture(params=[ - ('w:styles/w:style{w:type=paragraph,w:styleId=Foo}', 'Foo', - WD_STYLE_TYPE.PARAGRAPH), - ('w:styles/w:style{w:type=paragraph,w:styleId=Foo}', 'Bar', - WD_STYLE_TYPE.PARAGRAPH), - ('w:styles/w:style{w:type=table,w:styleId=Bar}', 'Bar', - WD_STYLE_TYPE.PARAGRAPH), - ]) + return (styles, style_type, StyleFactory_, StyleFactory_calls, expected_value) + + @pytest.fixture( + params=[ + ( + "w:styles/w:style{w:type=paragraph,w:styleId=Foo}", + "Foo", + WD_STYLE_TYPE.PARAGRAPH, + ), + ( + "w:styles/w:style{w:type=paragraph,w:styleId=Foo}", + "Bar", + WD_STYLE_TYPE.PARAGRAPH, + ), + ( + "w:styles/w:style{w:type=table,w:styleId=Bar}", + "Bar", + WD_STYLE_TYPE.PARAGRAPH, + ), + ] + ) def _get_by_id_fixture(self, request, default_, StyleFactory_, style_): styles_cxml, style_id, style_type = request.param styles_elm = element(styles_cxml) style_elm = styles_elm[0] styles = Styles(styles_elm) - default_calls = [] if style_id == 'Foo' else [call(styles, style_type)] - StyleFactory_calls = [call(style_elm)] if style_id == 'Foo' else [] + default_calls = [] if style_id == "Foo" else [call(styles, style_type)] + StyleFactory_calls = [call(style_elm)] if style_id == "Foo" else [] default_.return_value = StyleFactory_.return_value = style_ return ( - styles, style_id, style_type, default_calls, StyleFactory_, - StyleFactory_calls, style_ + styles, + style_id, + style_type, + default_calls, + StyleFactory_, + StyleFactory_calls, + style_, ) - @pytest.fixture(params=[ - ('w:styles/(w:style{%s,w:styleId=Foobar},w:style,w:style)', 0), - ('w:styles/(w:style,w:style{%s,w:styleId=Foobar},w:style)', 1), - ('w:styles/(w:style,w:style,w:style{%s,w:styleId=Foobar})', 2), - ]) + @pytest.fixture( + params=[ + ("w:styles/(w:style{%s,w:styleId=Foobar},w:style,w:style)", 0), + ("w:styles/(w:style,w:style{%s,w:styleId=Foobar},w:style)", 1), + ("w:styles/(w:style,w:style,w:style{%s,w:styleId=Foobar})", 2), + ] + ) def getitem_id_fixture(self, request): styles_cxml_tmpl, style_idx = request.param - styles_cxml = styles_cxml_tmpl % 'w:type=paragraph' + styles_cxml = styles_cxml_tmpl % "w:type=paragraph" styles = Styles(element(styles_cxml)) expected_element = styles._element[style_idx] - return styles, 'Foobar', expected_element - - @pytest.fixture(params=[ - ('w:styles/(w:style%s/w:name{w:val=foo},w:style)', 'foo', 0), - ('w:styles/(w:style,w:style%s/w:name{w:val=foo})', 'foo', 1), - ('w:styles/w:style%s/w:name{w:val=heading 1}', 'Heading 1', 0), - ]) + return styles, "Foobar", expected_element + + @pytest.fixture( + params=[ + ("w:styles/(w:style%s/w:name{w:val=foo},w:style)", "foo", 0), + ("w:styles/(w:style,w:style%s/w:name{w:val=foo})", "foo", 1), + ("w:styles/w:style%s/w:name{w:val=heading 1}", "Heading 1", 0), + ] + ) def getitem_name_fixture(self, request): styles_cxml_tmpl, key, style_idx = request.param - styles_cxml = styles_cxml_tmpl % '{w:type=character}' + styles_cxml = styles_cxml_tmpl % "{w:type=character}" styles = Styles(element(styles_cxml)) expected_element = styles._element[style_idx] return styles, key, expected_element - @pytest.fixture(params=[ - ('w:styles/(w:style,w:style/w:name{w:val=foo},w:style)'), - ('w:styles/(w:style{w:styleId=foo},w:style,w:style)'), - ]) + @pytest.fixture( + params=[ + ("w:styles/(w:style,w:style/w:name{w:val=foo},w:style)"), + ("w:styles/(w:style{w:styleId=foo},w:style,w:style)"), + ] + ) def get_raises_fixture(self, request): styles_cxml = request.param styles = Styles(element(styles_cxml)) - return styles, 'bar' + return styles, "bar" @pytest.fixture(params=[True, False]) def id_style_fixture(self, request, default_, style_): style_is_default = request.param styles = Styles(None) - style_id, style_type = 'FooBar', 1 + style_id, style_type = "FooBar", 1 default_.return_value = style_ if style_is_default else None style_.style_id, style_.type = style_id, style_type expected_value = None if style_is_default else style_id @@ -290,23 +320,27 @@ def id_style_raises_fixture(self, style_): style_type = 2 return styles, style_, style_type - @pytest.fixture(params=[ - ('w:styles/w:style/w:name{w:val=heading 1}', 'Heading 1', True), - ('w:styles/w:style/w:name{w:val=Foo Bar}', 'Foo Bar', True), - ('w:styles/w:style/w:name{w:val=heading 1}', 'Foobar', False), - ('w:styles', 'Foobar', False), - ]) + @pytest.fixture( + params=[ + ("w:styles/w:style/w:name{w:val=heading 1}", "Heading 1", True), + ("w:styles/w:style/w:name{w:val=Foo Bar}", "Foo Bar", True), + ("w:styles/w:style/w:name{w:val=heading 1}", "Foobar", False), + ("w:styles", "Foobar", False), + ] + ) def in_fixture(self, request): styles_cxml, name, expected_value = request.param styles = Styles(element(styles_cxml)) return styles, name, expected_value - @pytest.fixture(params=[ - ('w:styles', 0), - ('w:styles/w:style', 1), - ('w:styles/(w:style,w:style)', 2), - ('w:styles/(w:style,w:style,w:style)', 3), - ]) + @pytest.fixture( + params=[ + ("w:styles", 0), + ("w:styles/w:style", 1), + ("w:styles/(w:style,w:style)", 2), + ("w:styles/(w:style,w:style,w:style)", 3), + ] + ) def iter_fixture(self, request, StyleFactory_, style_): styles_cxml, expected_count = request.param styles_elm = element(styles_cxml) @@ -317,15 +351,17 @@ def iter_fixture(self, request, StyleFactory_, style_): @pytest.fixture def latent_styles_fixture(self, LatentStyles_, latent_styles_): - styles = Styles(element('w:styles/w:latentStyles')) + styles = Styles(element("w:styles/w:latentStyles")) return styles, LatentStyles_, latent_styles_ - @pytest.fixture(params=[ - ('w:styles', 0), - ('w:styles/w:style', 1), - ('w:styles/(w:style,w:style)', 2), - ('w:styles/(w:style,w:style,w:style)', 3), - ]) + @pytest.fixture( + params=[ + ("w:styles", 0), + ("w:styles/w:style", 1), + ("w:styles/(w:style,w:style)", 2), + ("w:styles/(w:style,w:style,w:style)", 3), + ] + ) def len_fixture(self, request): styles_cxml, expected_value = request.param styles = Styles(element(styles_cxml)) @@ -335,29 +371,28 @@ def len_fixture(self, request): @pytest.fixture def default_(self, request): - return method_mock(request, Styles, 'default') + return method_mock(request, Styles, "default") @pytest.fixture def _get_by_id_(self, request): - return method_mock(request, Styles, '_get_by_id') + return method_mock(request, Styles, "_get_by_id") @pytest.fixture def _getitem_(self, request): - return method_mock(request, Styles, '__getitem__') + return method_mock(request, Styles, "__getitem__") @pytest.fixture def _get_style_id_from_name_(self, request): - return method_mock(request, Styles, '_get_style_id_from_name') + return method_mock(request, Styles, "_get_style_id_from_name") @pytest.fixture def _get_style_id_from_style_(self, request): - return method_mock(request, Styles, '_get_style_id_from_style') + return method_mock(request, Styles, "_get_style_id_from_style") @pytest.fixture def LatentStyles_(self, request, latent_styles_): return class_mock( - request, 'docx.styles.styles.LatentStyles', - return_value=latent_styles_ + request, "docx.styles.styles.LatentStyles", return_value=latent_styles_ ) @pytest.fixture @@ -370,7 +405,7 @@ def style_(self, request): @pytest.fixture def StyleFactory_(self, request): - return function_mock(request, 'docx.styles.styles.StyleFactory') + return function_mock(request, "docx.styles.styles.StyleFactory") @pytest.fixture def style_elm_(self, request): diff --git a/tests/test_api.py b/tests/test_api.py index cc3553cc..23251cf3 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -4,9 +4,7 @@ Test suite for the docx.api module """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals import pytest @@ -19,7 +17,6 @@ class DescribeDocument(object): - def it_opens_a_docx_file(self, open_fixture): docx, Package_, document_ = open_fixture document = Document(docx) @@ -41,7 +38,7 @@ def it_raises_on_not_a_Word_file(self, raise_fixture): @pytest.fixture def default_fixture(self, _default_docx_path_, Package_, document_): - docx = 'barfoo.docx' + docx = "barfoo.docx" _default_docx_path_.return_value = docx document_part = Package_.open.return_value.main_document_part document_part.document = document_ @@ -50,7 +47,7 @@ def default_fixture(self, _default_docx_path_, Package_, document_): @pytest.fixture def open_fixture(self, Package_, document_): - docx = 'foobar.docx' + docx = "foobar.docx" document_part = Package_.open.return_value.main_document_part document_part.document = document_ document_part.content_type = CT.WML_DOCUMENT_MAIN @@ -58,15 +55,15 @@ def open_fixture(self, Package_, document_): @pytest.fixture def raise_fixture(self, Package_): - not_a_docx = 'foobar.xlsx' - Package_.open.return_value.main_document_part.content_type = 'BOGUS' + not_a_docx = "foobar.xlsx" + Package_.open.return_value.main_document_part.content_type = "BOGUS" return not_a_docx # fixture components --------------------------------------------- @pytest.fixture def _default_docx_path_(self, request): - return function_mock(request, 'docx.api._default_docx_path') + return function_mock(request, "docx.api._default_docx_path") @pytest.fixture def document_(self, request): @@ -74,4 +71,4 @@ def document_(self, request): @pytest.fixture def Package_(self, request): - return class_mock(request, 'docx.api.Package') + return class_mock(request, "docx.api.Package") diff --git a/tests/test_blkcntnr.py b/tests/test_blkcntnr.py index 5bc9bab3..3fe2d0ff 100644 --- a/tests/test_blkcntnr.py +++ b/tests/test_blkcntnr.py @@ -17,7 +17,6 @@ class DescribeBlockItemContainer(object): - def it_can_add_a_paragraph(self, add_paragraph_fixture, _add_paragraph_): text, style, paragraph_, add_run_calls = add_paragraph_fixture _add_paragraph_.return_value = paragraph_ @@ -37,8 +36,7 @@ def it_can_add_a_table(self, add_table_fixture): assert table._element.xml == expected_xml assert table._parent is blkcntnr - def it_provides_access_to_the_paragraphs_it_contains( - self, paragraphs_fixture): + def it_provides_access_to_the_paragraphs_it_contains(self, paragraphs_fixture): # test len(), iterable, and indexed access blkcntnr, expected_count = paragraphs_fixture paragraphs = blkcntnr.paragraphs @@ -71,12 +69,14 @@ def it_adds_a_paragraph_to_help(self, _add_paragraph_fixture): # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - ('', None), - ('Foo', None), - ('', 'Bar'), - ('Foo', 'Bar'), - ]) + @pytest.fixture( + params=[ + ("", None), + ("Foo", None), + ("", "Bar"), + ("Foo", "Bar"), + ] + ) def add_paragraph_fixture(self, request, paragraph_): text, style = request.param paragraph_.style = None @@ -85,37 +85,41 @@ def add_paragraph_fixture(self, request, paragraph_): @pytest.fixture def _add_paragraph_fixture(self, request): - blkcntnr_cxml, after_cxml = 'w:body', 'w:body/w:p' + blkcntnr_cxml, after_cxml = "w:body", "w:body/w:p" blkcntnr = BlockItemContainer(element(blkcntnr_cxml), None) expected_xml = xml(after_cxml) return blkcntnr, expected_xml @pytest.fixture def add_table_fixture(self): - blkcntnr = BlockItemContainer(element('w:body'), None) + blkcntnr = BlockItemContainer(element("w:body"), None) rows, cols, width = 2, 2, Inches(2) - expected_xml = snippet_seq('new-tbl')[0] + expected_xml = snippet_seq("new-tbl")[0] return blkcntnr, rows, cols, width, expected_xml - @pytest.fixture(params=[ - ('w:body', 0), - ('w:body/w:p', 1), - ('w:body/(w:p,w:p)', 2), - ('w:body/(w:p,w:tbl)', 1), - ('w:body/(w:p,w:tbl,w:p)', 2), - ]) + @pytest.fixture( + params=[ + ("w:body", 0), + ("w:body/w:p", 1), + ("w:body/(w:p,w:p)", 2), + ("w:body/(w:p,w:tbl)", 1), + ("w:body/(w:p,w:tbl,w:p)", 2), + ] + ) def paragraphs_fixture(self, request): blkcntnr_cxml, expected_count = request.param blkcntnr = BlockItemContainer(element(blkcntnr_cxml), None) return blkcntnr, expected_count - @pytest.fixture(params=[ - ('w:body', 0), - ('w:body/w:tbl', 1), - ('w:body/(w:tbl,w:tbl)', 2), - ('w:body/(w:p,w:tbl)', 1), - ('w:body/(w:tbl,w:tbl,w:p)', 2), - ]) + @pytest.fixture( + params=[ + ("w:body", 0), + ("w:body/w:tbl", 1), + ("w:body/(w:tbl,w:tbl)", 2), + ("w:body/(w:p,w:tbl)", 1), + ("w:body/(w:tbl,w:tbl,w:p)", 2), + ] + ) def tables_fixture(self, request): blkcntnr_cxml, expected_count = request.param blkcntnr = BlockItemContainer(element(blkcntnr_cxml), None) @@ -125,7 +129,7 @@ def tables_fixture(self, request): @pytest.fixture def _add_paragraph_(self, request): - return method_mock(request, BlockItemContainer, '_add_paragraph') + return method_mock(request, BlockItemContainer, "_add_paragraph") @pytest.fixture def paragraph_(self, request): diff --git a/tests/test_document.py b/tests/test_document.py index 0de469c3..27f17f97 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -25,7 +25,6 @@ class DescribeDocument(object): - def it_can_add_a_heading(self, add_heading_fixture, add_paragraph_, paragraph_): level, style = add_heading_fixture add_paragraph_.return_value = paragraph_ @@ -77,7 +76,7 @@ def it_can_add_a_section( section = document.add_section(start_type) assert document.element.xml == expected_xml - sectPr = document.element.xpath('w:body/w:sectPr')[0] + sectPr = document.element.xpath("w:body/w:sectPr")[0] Section_.assert_called_once_with(sectPr, document_part_) assert section is section_ @@ -108,7 +107,7 @@ def it_provides_access_to_its_paragraphs(self, paragraphs_fixture): assert paragraphs is paragraphs_ def it_provides_access_to_its_sections(self, document_part_, Sections_, sections_): - document_elm = element('w:document') + document_elm = element("w:document") Sections_.return_value = sections_ document = Document(document_elm, document_part_) @@ -148,21 +147,25 @@ def it_determines_block_width_to_help(self, block_width_fixture): # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - (0, 'Title'), - (1, 'Heading 1'), - (2, 'Heading 2'), - (9, 'Heading 9'), - ]) + @pytest.fixture( + params=[ + (0, "Title"), + (1, "Heading 1"), + (2, "Heading 2"), + (9, "Heading 9"), + ] + ) def add_heading_fixture(self, request): level, style = request.param return level, style - @pytest.fixture(params=[ - ('', None), - ('', 'Heading 1'), - ('foo\rbar', 'Body Text'), - ]) + @pytest.fixture( + params=[ + ("", None), + ("", "Heading 1"), + ("foo\rbar", "Body Text"), + ] + ) def add_paragraph_fixture(self, request, body_prop_, paragraph_): text, style = request.param document = Document(None, None) @@ -172,32 +175,34 @@ def add_paragraph_fixture(self, request, body_prop_, paragraph_): @pytest.fixture def add_picture_fixture(self, request, add_paragraph_, run_, picture_): document = Document(None, None) - path, width, height = 'foobar.png', 100, 200 + path, width, height = "foobar.png", 100, 200 add_paragraph_.return_value.add_run.return_value = run_ run_.add_picture.return_value = picture_ return document, path, width, height, run_, picture_ - @pytest.fixture(params=[ - ('w:sectPr', WD_SECTION.EVEN_PAGE, - 'w:sectPr/w:type{w:val=evenPage}'), - ('w:sectPr/w:type{w:val=evenPage}', WD_SECTION.ODD_PAGE, - 'w:sectPr/w:type{w:val=oddPage}'), - ('w:sectPr/w:type{w:val=oddPage}', WD_SECTION.NEW_PAGE, - 'w:sectPr'), - ]) + @pytest.fixture( + params=[ + ("w:sectPr", WD_SECTION.EVEN_PAGE, "w:sectPr/w:type{w:val=evenPage}"), + ( + "w:sectPr/w:type{w:val=evenPage}", + WD_SECTION.ODD_PAGE, + "w:sectPr/w:type{w:val=oddPage}", + ), + ("w:sectPr/w:type{w:val=oddPage}", WD_SECTION.NEW_PAGE, "w:sectPr"), + ] + ) def add_section_fixture(self, request): sentinel, start_type, new_sentinel = request.param - document_elm = element('w:document/w:body/(w:p,%s)' % sentinel) + document_elm = element("w:document/w:body/(w:p,%s)" % sentinel) expected_xml = xml( - 'w:document/w:body/(w:p,w:p/w:pPr/%s,%s)' % - (sentinel, new_sentinel) + "w:document/w:body/(w:p,w:p/w:pPr/%s,%s)" % (sentinel, new_sentinel) ) return document_elm, start_type, expected_xml @pytest.fixture def add_table_fixture(self, _block_width_prop_, body_prop_, table_): document = Document(None, None) - rows, cols, style = 4, 2, 'Light Shading Accent 1' + rows, cols, style = 4, 2, "Light Shading Accent 1" body_prop_.return_value.add_table.return_value = table_ _block_width_prop_.return_value = width = 42 return document, rows, cols, style, width, table_ @@ -214,7 +219,7 @@ def block_width_fixture(self, sections_prop_, section_): @pytest.fixture def body_fixture(self, _Body_, body_): - document_elm = element('w:document/w:body') + document_elm = element("w:document/w:body") body_elm = document_elm[0] document = Document(document_elm, None) return document, body_elm, _Body_, body_ @@ -245,7 +250,7 @@ def part_fixture(self, document_part_): @pytest.fixture def save_fixture(self, document_part_): document = Document(None, document_part_) - file_ = 'foobar.docx' + file_ = "foobar.docx" return document, file_ @pytest.fixture @@ -270,11 +275,11 @@ def tables_fixture(self, body_prop_, tables_): @pytest.fixture def add_paragraph_(self, request): - return method_mock(request, Document, 'add_paragraph') + return method_mock(request, Document, "add_paragraph") @pytest.fixture def _Body_(self, request, body_): - return class_mock(request, 'docx.document._Body', return_value=body_) + return class_mock(request, "docx.document._Body", return_value=body_) @pytest.fixture def body_(self, request): @@ -282,11 +287,11 @@ def body_(self, request): @pytest.fixture def _block_width_prop_(self, request): - return property_mock(request, Document, '_block_width') + return property_mock(request, Document, "_block_width") @pytest.fixture def body_prop_(self, request, body_): - return property_mock(request, Document, '_body', return_value=body_) + return property_mock(request, Document, "_body", return_value=body_) @pytest.fixture def core_properties_(self, request): @@ -318,7 +323,7 @@ def run_(self, request): @pytest.fixture def Section_(self, request): - return class_mock(request, 'docx.document.Section') + return class_mock(request, "docx.document.Section") @pytest.fixture def section_(self, request): @@ -326,7 +331,7 @@ def section_(self, request): @pytest.fixture def Sections_(self, request): - return class_mock(request, 'docx.document.Sections') + return class_mock(request, "docx.document.Sections") @pytest.fixture def sections_(self, request): @@ -334,7 +339,7 @@ def sections_(self, request): @pytest.fixture def sections_prop_(self, request): - return property_mock(request, Document, 'sections') + return property_mock(request, Document, "sections") @pytest.fixture def settings_(self, request): @@ -346,7 +351,7 @@ def styles_(self, request): @pytest.fixture def table_(self, request): - return instance_mock(request, Table, style='UNASSIGNED') + return instance_mock(request, Table, style="UNASSIGNED") @pytest.fixture def tables_(self, request): @@ -354,7 +359,6 @@ def tables_(self, request): class Describe_Body(object): - def it_can_clear_itself_of_all_content_it_holds(self, clear_fixture): body, expected_xml = clear_fixture _body = body.clear_content() @@ -363,12 +367,14 @@ def it_can_clear_itself_of_all_content_it_holds(self, clear_fixture): # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - ('w:body', 'w:body'), - ('w:body/w:p', 'w:body'), - ('w:body/w:sectPr', 'w:body/w:sectPr'), - ('w:body/(w:p, w:sectPr)', 'w:body/w:sectPr'), - ]) + @pytest.fixture( + params=[ + ("w:body", "w:body"), + ("w:body/w:p", "w:body"), + ("w:body/w:sectPr", "w:body/w:sectPr"), + ("w:body/(w:p, w:sectPr)", "w:body/w:sectPr"), + ] + ) def clear_fixture(self, request): before_cxml, after_cxml = request.param body = _Body(element(before_cxml), None) diff --git a/tests/test_enum.py b/tests/test_enum.py index edfe595d..a07795ed 100644 --- a/tests/test_enum.py +++ b/tests/test_enum.py @@ -12,55 +12,58 @@ import pytest from docx.enum.base import ( - alias, Enumeration, EnumMember, ReturnValueOnlyEnumMember, - XmlEnumeration, XmlMappedEnumMember + alias, + Enumeration, + EnumMember, + ReturnValueOnlyEnumMember, + XmlEnumeration, + XmlMappedEnumMember, ) -@alias('BARFOO') +@alias("BARFOO") class FOOBAR(Enumeration): """ Enumeration docstring """ - __ms_name__ = 'MsoFoobar' + __ms_name__ = "MsoFoobar" - __url__ = 'http://msdn.microsoft.com/foobar.aspx' + __url__ = "http://msdn.microsoft.com/foobar.aspx" __members__ = ( - EnumMember(None, None, 'No setting/remove setting'), - EnumMember('READ_WRITE', 1, 'Readable and settable'), - ReturnValueOnlyEnumMember('READ_ONLY', -2, 'Return value only'), + EnumMember(None, None, "No setting/remove setting"), + EnumMember("READ_WRITE", 1, "Readable and settable"), + ReturnValueOnlyEnumMember("READ_ONLY", -2, "Return value only"), ) -@alias('XML-FU') +@alias("XML-FU") class XMLFOO(XmlEnumeration): """ XmlEnumeration docstring """ - __ms_name__ = 'MsoXmlFoobar' + __ms_name__ = "MsoXmlFoobar" - __url__ = 'http://msdn.microsoft.com/msoxmlfoobar.aspx' + __url__ = "http://msdn.microsoft.com/msoxmlfoobar.aspx" __members__ = ( - XmlMappedEnumMember(None, None, None, 'No setting'), - XmlMappedEnumMember('XML_RW', 42, 'attrVal', 'Read/write setting'), - ReturnValueOnlyEnumMember('RO', -2, 'Return value only;'), + XmlMappedEnumMember(None, None, None, "No setting"), + XmlMappedEnumMember("XML_RW", 42, "attrVal", "Read/write setting"), + ReturnValueOnlyEnumMember("RO", -2, "Return value only;"), ) class DescribeEnumeration(object): - def it_has_the_right_metaclass(self): - assert type(FOOBAR).__name__ == 'MetaEnumeration' + assert type(FOOBAR).__name__ == "MetaEnumeration" def it_provides_an_EnumValue_instance_for_each_named_member(self): with pytest.raises(AttributeError): - getattr(FOOBAR, 'None') + getattr(FOOBAR, "None") for obj in (FOOBAR.READ_WRITE, FOOBAR.READ_ONLY): - assert type(obj).__name__ == 'EnumValue' + assert type(obj).__name__ == "EnumValue" def it_provides_the_enumeration_value_for_each_named_member(self): assert FOOBAR.READ_WRITE == 1 @@ -70,7 +73,7 @@ def it_knows_if_a_setting_is_valid(self): FOOBAR.validate(None) FOOBAR.validate(FOOBAR.READ_WRITE) with pytest.raises(ValueError): - FOOBAR.validate('foobar') + FOOBAR.validate("foobar") with pytest.raises(ValueError): FOOBAR.validate(FOOBAR.READ_ONLY) @@ -79,23 +82,21 @@ def it_can_be_referred_to_by_a_convenience_alias_if_defined(self): class DescribeEnumValue(object): - def it_provides_its_symbolic_name_as_its_string_value(self): - assert ('%s' % FOOBAR.READ_WRITE) == 'READ_WRITE (1)' + assert ("%s" % FOOBAR.READ_WRITE) == "READ_WRITE (1)" def it_provides_its_description_as_its_docstring(self): - assert FOOBAR.READ_ONLY.__doc__ == 'Return value only' + assert FOOBAR.READ_ONLY.__doc__ == "Return value only" class DescribeXmlEnumeration(object): - def it_knows_the_XML_value_for_each_of_its_xml_members(self): - assert XMLFOO.to_xml(XMLFOO.XML_RW) == 'attrVal' - assert XMLFOO.to_xml(42) == 'attrVal' + assert XMLFOO.to_xml(XMLFOO.XML_RW) == "attrVal" + assert XMLFOO.to_xml(42) == "attrVal" with pytest.raises(ValueError): XMLFOO.to_xml(XMLFOO.RO) def it_can_map_each_of_its_xml_members_from_the_XML_value(self): assert XMLFOO.from_xml(None) is None - assert XMLFOO.from_xml('attrVal') == XMLFOO.XML_RW - assert str(XMLFOO.from_xml('attrVal')) == 'XML_RW (42)' + assert XMLFOO.from_xml("attrVal") == XMLFOO.XML_RW + assert str(XMLFOO.from_xml("attrVal")) == "XML_RW (42)" diff --git a/tests/test_section.py b/tests/test_section.py index 7ac29a0f..ae887a96 100644 --- a/tests/test_section.py +++ b/tests/test_section.py @@ -17,7 +17,6 @@ class DescribeSections(object): - def it_knows_how_many_sections_it_contains(self): sections = Sections( element("w:document/w:body/(w:p/w:pPr/w:sectPr, w:sectPr)"), None @@ -35,7 +34,8 @@ def it_can_iterate_over_its_Section_instances( section_lst = [s for s in sections] assert Section_.call_args_list == [ - call(sectPrs[0], document_part_), call(sectPrs[1], document_part_) + call(sectPrs[0], document_part_), + call(sectPrs[1], document_part_), ] assert section_lst == [section_, section_] @@ -71,7 +71,8 @@ def it_can_access_its_Section_instances_by_slice( section_lst = sections[1:9] assert Section_.call_args_list == [ - call(sectPrs[1], document_part_), call(sectPrs[2], document_part_) + call(sectPrs[1], document_part_), + call(sectPrs[2], document_part_), ] assert section_lst == [section_, section_] @@ -91,7 +92,6 @@ def section_(self, request): class DescribeSection(object): - def it_knows_when_it_displays_a_distinct_first_page_header( self, diff_first_header_get_fixture ): @@ -115,7 +115,7 @@ def it_can_change_whether_the_document_has_distinct_odd_and_even_headers( def it_provides_access_to_its_even_page_footer( self, document_part_, _Footer_, footer_ ): - sectPr = element('w:sectPr') + sectPr = element("w:sectPr") _Footer_.return_value = footer_ section = Section(sectPr, document_part_) @@ -171,7 +171,7 @@ def it_provides_access_to_its_first_page_header( def it_provides_access_to_its_default_footer( self, document_part_, _Footer_, footer_ ): - sectPr = element('w:sectPr') + sectPr = element("w:sectPr") _Footer_.return_value = footer_ section = Section(sectPr, document_part_) @@ -185,7 +185,7 @@ def it_provides_access_to_its_default_footer( def it_provides_access_to_its_default_header( self, document_part_, _Header_, header_ ): - sectPr = element('w:sectPr') + sectPr = element("w:sectPr") _Header_.return_value = header_ section = Section(sectPr, document_part_) @@ -306,137 +306,171 @@ def diff_first_header_set_fixture(self, request): expected_xml = xml(expected_cxml) return sectPr, value, expected_xml - @pytest.fixture(params=[ - ('w:sectPr/w:pgMar{w:left=120}', 'left_margin', 76200), - ('w:sectPr/w:pgMar{w:right=240}', 'right_margin', 152400), - ('w:sectPr/w:pgMar{w:top=-360}', 'top_margin', -228600), - ('w:sectPr/w:pgMar{w:bottom=480}', 'bottom_margin', 304800), - ('w:sectPr/w:pgMar{w:gutter=600}', 'gutter', 381000), - ('w:sectPr/w:pgMar{w:header=720}', 'header_distance', 457200), - ('w:sectPr/w:pgMar{w:footer=840}', 'footer_distance', 533400), - ('w:sectPr/w:pgMar', 'left_margin', None), - ('w:sectPr', 'top_margin', None), - ]) + @pytest.fixture( + params=[ + ("w:sectPr/w:pgMar{w:left=120}", "left_margin", 76200), + ("w:sectPr/w:pgMar{w:right=240}", "right_margin", 152400), + ("w:sectPr/w:pgMar{w:top=-360}", "top_margin", -228600), + ("w:sectPr/w:pgMar{w:bottom=480}", "bottom_margin", 304800), + ("w:sectPr/w:pgMar{w:gutter=600}", "gutter", 381000), + ("w:sectPr/w:pgMar{w:header=720}", "header_distance", 457200), + ("w:sectPr/w:pgMar{w:footer=840}", "footer_distance", 533400), + ("w:sectPr/w:pgMar", "left_margin", None), + ("w:sectPr", "top_margin", None), + ] + ) def margins_get_fixture(self, request): sectPr_cxml, margin_prop_name, expected_value = request.param sectPr = element(sectPr_cxml) return sectPr, margin_prop_name, expected_value - @pytest.fixture(params=[ - ('w:sectPr', 'left_margin', Inches(1), - 'w:sectPr/w:pgMar{w:left=1440}'), - ('w:sectPr', 'right_margin', Inches(0.5), - 'w:sectPr/w:pgMar{w:right=720}'), - ('w:sectPr', 'top_margin', Inches(-0.25), - 'w:sectPr/w:pgMar{w:top=-360}'), - ('w:sectPr', 'bottom_margin', Inches(0.75), - 'w:sectPr/w:pgMar{w:bottom=1080}'), - ('w:sectPr', 'gutter', Inches(0.25), - 'w:sectPr/w:pgMar{w:gutter=360}'), - ('w:sectPr', 'header_distance', Inches(1.25), - 'w:sectPr/w:pgMar{w:header=1800}'), - ('w:sectPr', 'footer_distance', Inches(1.35), - 'w:sectPr/w:pgMar{w:footer=1944}'), - ('w:sectPr', 'left_margin', None, 'w:sectPr/w:pgMar'), - ('w:sectPr/w:pgMar{w:top=-360}', 'top_margin', Inches(0.6), - 'w:sectPr/w:pgMar{w:top=864}'), - ]) + @pytest.fixture( + params=[ + ("w:sectPr", "left_margin", Inches(1), "w:sectPr/w:pgMar{w:left=1440}"), + ("w:sectPr", "right_margin", Inches(0.5), "w:sectPr/w:pgMar{w:right=720}"), + ("w:sectPr", "top_margin", Inches(-0.25), "w:sectPr/w:pgMar{w:top=-360}"), + ( + "w:sectPr", + "bottom_margin", + Inches(0.75), + "w:sectPr/w:pgMar{w:bottom=1080}", + ), + ("w:sectPr", "gutter", Inches(0.25), "w:sectPr/w:pgMar{w:gutter=360}"), + ( + "w:sectPr", + "header_distance", + Inches(1.25), + "w:sectPr/w:pgMar{w:header=1800}", + ), + ( + "w:sectPr", + "footer_distance", + Inches(1.35), + "w:sectPr/w:pgMar{w:footer=1944}", + ), + ("w:sectPr", "left_margin", None, "w:sectPr/w:pgMar"), + ( + "w:sectPr/w:pgMar{w:top=-360}", + "top_margin", + Inches(0.6), + "w:sectPr/w:pgMar{w:top=864}", + ), + ] + ) def margins_set_fixture(self, request): sectPr_cxml, property_name, new_value, expected_cxml = request.param sectPr = element(sectPr_cxml) expected_xml = xml(expected_cxml) return sectPr, property_name, new_value, expected_xml - @pytest.fixture(params=[ - ('w:sectPr/w:pgSz{w:orient=landscape}', WD_ORIENT.LANDSCAPE), - ('w:sectPr/w:pgSz{w:orient=portrait}', WD_ORIENT.PORTRAIT), - ('w:sectPr/w:pgSz', WD_ORIENT.PORTRAIT), - ('w:sectPr', WD_ORIENT.PORTRAIT), - ]) + @pytest.fixture( + params=[ + ("w:sectPr/w:pgSz{w:orient=landscape}", WD_ORIENT.LANDSCAPE), + ("w:sectPr/w:pgSz{w:orient=portrait}", WD_ORIENT.PORTRAIT), + ("w:sectPr/w:pgSz", WD_ORIENT.PORTRAIT), + ("w:sectPr", WD_ORIENT.PORTRAIT), + ] + ) def orientation_get_fixture(self, request): sectPr_cxml, expected_orientation = request.param sectPr = element(sectPr_cxml) return sectPr, expected_orientation - @pytest.fixture(params=[ - (WD_ORIENT.LANDSCAPE, 'w:sectPr/w:pgSz{w:orient=landscape}'), - (WD_ORIENT.PORTRAIT, 'w:sectPr/w:pgSz'), - (None, 'w:sectPr/w:pgSz'), - ]) + @pytest.fixture( + params=[ + (WD_ORIENT.LANDSCAPE, "w:sectPr/w:pgSz{w:orient=landscape}"), + (WD_ORIENT.PORTRAIT, "w:sectPr/w:pgSz"), + (None, "w:sectPr/w:pgSz"), + ] + ) def orientation_set_fixture(self, request): new_orientation, expected_cxml = request.param - sectPr = element('w:sectPr') + sectPr = element("w:sectPr") expected_xml = xml(expected_cxml) return sectPr, new_orientation, expected_xml - @pytest.fixture(params=[ - ('w:sectPr/w:pgSz{w:h=2880}', Inches(2)), - ('w:sectPr/w:pgSz', None), - ('w:sectPr', None), - ]) + @pytest.fixture( + params=[ + ("w:sectPr/w:pgSz{w:h=2880}", Inches(2)), + ("w:sectPr/w:pgSz", None), + ("w:sectPr", None), + ] + ) def page_height_get_fixture(self, request): sectPr_cxml, expected_page_height = request.param sectPr = element(sectPr_cxml) return sectPr, expected_page_height - @pytest.fixture(params=[ - (None, 'w:sectPr/w:pgSz'), - (Inches(2), 'w:sectPr/w:pgSz{w:h=2880}'), - ]) + @pytest.fixture( + params=[ + (None, "w:sectPr/w:pgSz"), + (Inches(2), "w:sectPr/w:pgSz{w:h=2880}"), + ] + ) def page_height_set_fixture(self, request): new_page_height, expected_cxml = request.param - sectPr = element('w:sectPr') + sectPr = element("w:sectPr") expected_xml = xml(expected_cxml) return sectPr, new_page_height, expected_xml - @pytest.fixture(params=[ - ('w:sectPr/w:pgSz{w:w=1440}', Inches(1)), - ('w:sectPr/w:pgSz', None), - ('w:sectPr', None), - ]) + @pytest.fixture( + params=[ + ("w:sectPr/w:pgSz{w:w=1440}", Inches(1)), + ("w:sectPr/w:pgSz", None), + ("w:sectPr", None), + ] + ) def page_width_get_fixture(self, request): sectPr_cxml, expected_page_width = request.param sectPr = element(sectPr_cxml) return sectPr, expected_page_width - @pytest.fixture(params=[ - (None, 'w:sectPr/w:pgSz'), - (Inches(4), 'w:sectPr/w:pgSz{w:w=5760}'), - ]) + @pytest.fixture( + params=[ + (None, "w:sectPr/w:pgSz"), + (Inches(4), "w:sectPr/w:pgSz{w:w=5760}"), + ] + ) def page_width_set_fixture(self, request): new_page_width, expected_cxml = request.param - sectPr = element('w:sectPr') + sectPr = element("w:sectPr") expected_xml = xml(expected_cxml) return sectPr, new_page_width, expected_xml - @pytest.fixture(params=[ - ('w:sectPr', WD_SECTION.NEW_PAGE), - ('w:sectPr/w:type', WD_SECTION.NEW_PAGE), - ('w:sectPr/w:type{w:val=continuous}', WD_SECTION.CONTINUOUS), - ('w:sectPr/w:type{w:val=nextPage}', WD_SECTION.NEW_PAGE), - ('w:sectPr/w:type{w:val=oddPage}', WD_SECTION.ODD_PAGE), - ('w:sectPr/w:type{w:val=evenPage}', WD_SECTION.EVEN_PAGE), - ('w:sectPr/w:type{w:val=nextColumn}', WD_SECTION.NEW_COLUMN), - ]) + @pytest.fixture( + params=[ + ("w:sectPr", WD_SECTION.NEW_PAGE), + ("w:sectPr/w:type", WD_SECTION.NEW_PAGE), + ("w:sectPr/w:type{w:val=continuous}", WD_SECTION.CONTINUOUS), + ("w:sectPr/w:type{w:val=nextPage}", WD_SECTION.NEW_PAGE), + ("w:sectPr/w:type{w:val=oddPage}", WD_SECTION.ODD_PAGE), + ("w:sectPr/w:type{w:val=evenPage}", WD_SECTION.EVEN_PAGE), + ("w:sectPr/w:type{w:val=nextColumn}", WD_SECTION.NEW_COLUMN), + ] + ) def start_type_get_fixture(self, request): sectPr_cxml, expected_start_type = request.param sectPr = element(sectPr_cxml) return sectPr, expected_start_type - @pytest.fixture(params=[ - ('w:sectPr/w:type{w:val=oddPage}', WD_SECTION.EVEN_PAGE, - 'w:sectPr/w:type{w:val=evenPage}'), - ('w:sectPr/w:type{w:val=nextPage}', None, - 'w:sectPr'), - ('w:sectPr', None, - 'w:sectPr'), - ('w:sectPr/w:type{w:val=continuous}', WD_SECTION.NEW_PAGE, - 'w:sectPr'), - ('w:sectPr/w:type', WD_SECTION.NEW_PAGE, - 'w:sectPr'), - ('w:sectPr/w:type', WD_SECTION.NEW_COLUMN, - 'w:sectPr/w:type{w:val=nextColumn}'), - ]) + @pytest.fixture( + params=[ + ( + "w:sectPr/w:type{w:val=oddPage}", + WD_SECTION.EVEN_PAGE, + "w:sectPr/w:type{w:val=evenPage}", + ), + ("w:sectPr/w:type{w:val=nextPage}", None, "w:sectPr"), + ("w:sectPr", None, "w:sectPr"), + ("w:sectPr/w:type{w:val=continuous}", WD_SECTION.NEW_PAGE, "w:sectPr"), + ("w:sectPr/w:type", WD_SECTION.NEW_PAGE, "w:sectPr"), + ( + "w:sectPr/w:type", + WD_SECTION.NEW_COLUMN, + "w:sectPr/w:type{w:val=nextColumn}", + ), + ] + ) def start_type_set_fixture(self, request): initial_cxml, new_start_type, expected_cxml = request.param sectPr = element(initial_cxml) @@ -467,7 +501,6 @@ def header_(self, request): class Describe_BaseHeaderFooter(object): - def it_knows_when_its_linked_to_the_previous_header_or_footer( self, is_linked_get_fixture, _has_definition_prop_ ): @@ -553,7 +586,7 @@ def and_it_adds_a_definition_when_it_is_linked_and_the_first_section( _has_definition_prop_, _prior_headerfooter_prop_, _add_definition_, - header_part_ + header_part_, ): _has_definition_prop_.return_value = False _prior_headerfooter_prop_.return_value = None @@ -620,7 +653,6 @@ def _prior_headerfooter_prop_(self, request): class Describe_Footer(object): - def it_can_add_a_footer_part_to_help(self, document_part_, footer_part_): sectPr = element("w:sectPr{r:a=b}") document_part_.add_footer_part.return_value = footer_part_, "rId3" @@ -692,7 +724,8 @@ def but_it_returns_None_when_its_the_first_footer(self): @pytest.fixture( params=[ - ("w:sectPr", False), ("w:sectPr/w:footerReference{w:type=default}", True) + ("w:sectPr", False), + ("w:sectPr/w:footerReference{w:type=default}", True), ] ) def has_definition_fixture(self, request): @@ -716,7 +749,6 @@ def footer_part_(self, request): class Describe_Header(object): - def it_can_add_a_header_part_to_help(self, document_part_, header_part_): sectPr = element("w:sectPr{r:a=b}") document_part_.add_header_part.return_value = header_part_, "rId3" @@ -787,9 +819,7 @@ def but_it_returns_None_when_its_the_first_header(self): # fixtures ------------------------------------------------------- @pytest.fixture( - params=[ - ("w:sectPr", False), ("w:sectPr/w:headerReference{w:type=first}", True) - ] + params=[("w:sectPr", False), ("w:sectPr/w:headerReference{w:type=first}", True)] ) def has_definition_fixture(self, request): sectPr_cxml, expected_value = request.param diff --git a/tests/test_settings.py b/tests/test_settings.py index 5873ffa1..5c07a665 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -12,7 +12,6 @@ class DescribeSettings(object): - def it_knows_when_the_document_has_distinct_odd_and_even_headers( self, odd_and_even_get_fixture ): @@ -56,7 +55,7 @@ def odd_and_even_get_fixture(self, request): ( "w:settings/w:evenAndOddHeaders{w:val=1}", True, - "w:settings/w:evenAndOddHeaders" + "w:settings/w:evenAndOddHeaders", ), ("w:settings/w:evenAndOddHeaders{w:val=off}", False, "w:settings"), ] diff --git a/tests/test_shape.py b/tests/test_shape.py index 105d2fa4..5e08e974 100644 --- a/tests/test_shape.py +++ b/tests/test_shape.py @@ -14,21 +14,23 @@ from docx.shared import Length from .oxml.unitdata.dml import ( - a_blip, a_blipFill, a_graphic, a_graphicData, a_pic, an_inline, + a_blip, + a_blipFill, + a_graphic, + a_graphicData, + a_pic, + an_inline, ) from .unitutil.cxml import element, xml from .unitutil.mock import loose_mock class DescribeInlineShapes(object): - - def it_knows_how_many_inline_shapes_it_contains( - self, inline_shapes_fixture): + def it_knows_how_many_inline_shapes_it_contains(self, inline_shapes_fixture): inline_shapes, expected_count = inline_shapes_fixture assert len(inline_shapes) == expected_count - def it_can_iterate_over_its_InlineShape_instances( - self, inline_shapes_fixture): + def it_can_iterate_over_its_InlineShape_instances(self, inline_shapes_fixture): inline_shapes, inline_shape_count = inline_shapes_fixture actual_count = 0 for inline_shape in inline_shapes: @@ -36,15 +38,13 @@ def it_can_iterate_over_its_InlineShape_instances( actual_count += 1 assert actual_count == inline_shape_count - def it_provides_indexed_access_to_inline_shapes( - self, inline_shapes_fixture): + def it_provides_indexed_access_to_inline_shapes(self, inline_shapes_fixture): inline_shapes, inline_shape_count = inline_shapes_fixture for idx in range(-inline_shape_count, inline_shape_count): inline_shape = inline_shapes[idx] assert isinstance(inline_shape, InlineShape) - def it_raises_on_indexed_access_out_of_range( - self, inline_shapes_fixture): + def it_raises_on_indexed_access_out_of_range(self, inline_shapes_fixture): inline_shapes, inline_shape_count = inline_shapes_fixture with pytest.raises(IndexError): too_low = -1 - inline_shape_count @@ -62,9 +62,7 @@ def it_knows_the_part_it_belongs_to(self, inline_shapes_with_parent_): @pytest.fixture def inline_shapes_fixture(self): - body = element( - 'w:body/w:p/(w:r/w:drawing/wp:inline, w:r/w:drawing/wp:inline)' - ) + body = element("w:body/w:p/(w:r/w:drawing/wp:inline, w:r/w:drawing/wp:inline)") inline_shapes = InlineShapes(body, None) expected_count = 2 return inline_shapes, expected_count @@ -73,13 +71,12 @@ def inline_shapes_fixture(self): @pytest.fixture def inline_shapes_with_parent_(self, request): - parent_ = loose_mock(request, name='parent_') + parent_ = loose_mock(request, name="parent_") inline_shapes = InlineShapes(None, parent_) return inline_shapes, parent_ class DescribeInlineShape(object): - def it_knows_what_type_of_shape_it_is(self, shape_type_fixture): inline_shape, inline_shape_type = shape_type_fixture assert inline_shape.type == inline_shape_type @@ -104,7 +101,9 @@ def it_can_change_its_display_dimensions(self, dimensions_set_fixture): @pytest.fixture def dimensions_get_fixture(self): inline_cxml, expected_cx, expected_cy = ( - 'wp:inline/wp:extent{cx=333, cy=666}', 333, 666 + "wp:inline/wp:extent{cx=333, cy=666}", + 333, + 666, ) inline_shape = InlineShape(element(inline_cxml)) return inline_shape, expected_cx, expected_cy @@ -112,43 +111,50 @@ def dimensions_get_fixture(self): @pytest.fixture def dimensions_set_fixture(self): inline_cxml, new_cx, new_cy, expected_cxml = ( - 'wp:inline/(wp:extent{cx=333,cy=666},a:graphic/a:graphicData/' - 'pic:pic/pic:spPr/a:xfrm/a:ext{cx=333,cy=666})', - 444, 888, - 'wp:inline/(wp:extent{cx=444,cy=888},a:graphic/a:graphicData/' - 'pic:pic/pic:spPr/a:xfrm/a:ext{cx=444,cy=888})' + "wp:inline/(wp:extent{cx=333,cy=666},a:graphic/a:graphicData/" + "pic:pic/pic:spPr/a:xfrm/a:ext{cx=333,cy=666})", + 444, + 888, + "wp:inline/(wp:extent{cx=444,cy=888},a:graphic/a:graphicData/" + "pic:pic/pic:spPr/a:xfrm/a:ext{cx=444,cy=888})", ) inline_shape = InlineShape(element(inline_cxml)) expected_xml = xml(expected_cxml) return inline_shape, new_cx, new_cy, expected_xml - @pytest.fixture(params=[ - 'embed pic', 'link pic', 'link+embed pic', 'chart', 'smart art', - 'not implemented' - ]) + @pytest.fixture( + params=[ + "embed pic", + "link pic", + "link+embed pic", + "chart", + "smart art", + "not implemented", + ] + ) def shape_type_fixture(self, request): - if request.param == 'embed pic': + if request.param == "embed pic": inline = self._inline_with_picture(embed=True) shape_type = WD_INLINE_SHAPE.PICTURE - elif request.param == 'link pic': + elif request.param == "link pic": inline = self._inline_with_picture(link=True) shape_type = WD_INLINE_SHAPE.LINKED_PICTURE - elif request.param == 'link+embed pic': + elif request.param == "link+embed pic": inline = self._inline_with_picture(embed=True, link=True) shape_type = WD_INLINE_SHAPE.LINKED_PICTURE - elif request.param == 'chart': - inline = self._inline_with_uri(nsmap['c']) + elif request.param == "chart": + inline = self._inline_with_uri(nsmap["c"]) shape_type = WD_INLINE_SHAPE.CHART - elif request.param == 'smart art': - inline = self._inline_with_uri(nsmap['dgm']) + elif request.param == "smart art": + inline = self._inline_with_uri(nsmap["dgm"]) shape_type = WD_INLINE_SHAPE.SMART_ART - elif request.param == 'not implemented': - inline = self._inline_with_uri('foobar') + elif request.param == "not implemented": + inline = self._inline_with_uri("foobar") shape_type = WD_INLINE_SHAPE.NOT_IMPLEMENTED return InlineShape(inline), shape_type @@ -156,28 +162,39 @@ def shape_type_fixture(self, request): # fixture components --------------------------------------------- def _inline_with_picture(self, embed=False, link=False): - picture_ns = nsmap['pic'] + picture_ns = nsmap["pic"] blip_bldr = a_blip() if embed: - blip_bldr.with_embed('rId1') + blip_bldr.with_embed("rId1") if link: - blip_bldr.with_link('rId2') + blip_bldr.with_link("rId2") inline = ( - an_inline().with_nsdecls('wp', 'r').with_child( - a_graphic().with_nsdecls().with_child( - a_graphicData().with_uri(picture_ns).with_child( - a_pic().with_nsdecls().with_child( - a_blipFill().with_child( - blip_bldr))))) + an_inline() + .with_nsdecls("wp", "r") + .with_child( + a_graphic() + .with_nsdecls() + .with_child( + a_graphicData() + .with_uri(picture_ns) + .with_child( + a_pic() + .with_nsdecls() + .with_child(a_blipFill().with_child(blip_bldr)) + ) + ) + ) ).element return inline def _inline_with_uri(self, uri): inline = ( - an_inline().with_nsdecls('wp').with_child( - a_graphic().with_nsdecls().with_child( - a_graphicData().with_uri(uri))) + an_inline() + .with_nsdecls("wp") + .with_child( + a_graphic().with_nsdecls().with_child(a_graphicData().with_uri(uri)) + ) ).element return inline diff --git a/tests/test_shared.py b/tests/test_shared.py index 102a661e..7641c158 100644 --- a/tests/test_shared.py +++ b/tests/test_shared.py @@ -4,23 +4,18 @@ Test suite for the docx.shared module """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals import pytest from docx.opc.part import XmlPart -from docx.shared import ( - ElementProxy, Length, Cm, Emu, Inches, Mm, Pt, RGBColor, Twips -) +from docx.shared import ElementProxy, Length, Cm, Emu, Inches, Mm, Pt, RGBColor, Twips from .unitutil.cxml import element from .unitutil.mock import instance_mock class DescribeElementProxy(object): - def it_knows_when_its_equal_to_another_proxy_object(self, eq_fixture): proxy, proxy_2, proxy_3, not_a_proxy = eq_fixture @@ -44,17 +39,17 @@ def it_knows_its_part(self, part_fixture): @pytest.fixture def element_fixture(self): - p = element('w:p') + p = element("w:p") proxy = ElementProxy(p) return proxy, p @pytest.fixture def eq_fixture(self): - p, q = element('w:p'), element('w:p') + p, q = element("w:p"), element("w:p") proxy = ElementProxy(p) proxy_2 = ElementProxy(p) proxy_3 = ElementProxy(q) - not_a_proxy = 'Foobar' + not_a_proxy = "Foobar" return proxy, proxy_2, proxy_3, not_a_proxy @pytest.fixture @@ -75,7 +70,6 @@ def part_(self, request): class DescribeLength(object): - def it_can_construct_from_convenient_units(self, construct_fixture): UnitCls, units_val, emu = construct_fixture length = UnitCls(units_val) @@ -91,50 +85,53 @@ def it_can_self_convert_to_convenient_units(self, units_fixture): # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - (Length, 914400, 914400), - (Inches, 1.1, 1005840), - (Cm, 2.53, 910799), - (Emu, 9144.9, 9144), - (Mm, 13.8, 496800), - (Pt, 24.5, 311150), - (Twips, 360, 228600), - ]) + @pytest.fixture( + params=[ + (Length, 914400, 914400), + (Inches, 1.1, 1005840), + (Cm, 2.53, 910799), + (Emu, 9144.9, 9144), + (Mm, 13.8, 496800), + (Pt, 24.5, 311150), + (Twips, 360, 228600), + ] + ) def construct_fixture(self, request): UnitCls, units_val, emu = request.param return UnitCls, units_val, emu - @pytest.fixture(params=[ - (914400, 'inches', 1.0, float), - (914400, 'cm', 2.54, float), - (914400, 'emu', 914400, int), - (914400, 'mm', 25.4, float), - (914400, 'pt', 72.0, float), - (914400, 'twips', 1440, int), - ]) + @pytest.fixture( + params=[ + (914400, "inches", 1.0, float), + (914400, "cm", 2.54, float), + (914400, "emu", 914400, int), + (914400, "mm", 25.4, float), + (914400, "pt", 72.0, float), + (914400, "twips", 1440, int), + ] + ) def units_fixture(self, request): emu, units_prop_name, expected_length_in_units, type_ = request.param return emu, units_prop_name, expected_length_in_units, type_ class DescribeRGBColor(object): - def it_is_natively_constructed_using_three_ints_0_to_255(self): RGBColor(0x12, 0x34, 0x56) with pytest.raises(ValueError): - RGBColor('12', '34', '56') + RGBColor("12", "34", "56") with pytest.raises(ValueError): RGBColor(-1, 34, 56) with pytest.raises(ValueError): RGBColor(12, 256, 56) def it_can_construct_from_a_hex_string_rgb_value(self): - rgb = RGBColor.from_string('123456') + rgb = RGBColor.from_string("123456") assert rgb == RGBColor(0x12, 0x34, 0x56) def it_can_provide_a_hex_string_rgb_value(self): - assert str(RGBColor(0x12, 0x34, 0x56)) == '123456' + assert str(RGBColor(0x12, 0x34, 0x56)) == "123456" def it_has_a_custom_repr(self): rgb_color = RGBColor(0x42, 0xF0, 0xBA) - assert repr(rgb_color) == 'RGBColor(0x42, 0xf0, 0xba)' + assert repr(rgb_color) == "RGBColor(0x42, 0xf0, 0xba)" diff --git a/tests/test_table.py b/tests/test_table.py index 1d2183fd..b314b801 100644 --- a/tests/test_table.py +++ b/tests/test_table.py @@ -8,7 +8,10 @@ from docx.enum.style import WD_STYLE_TYPE from docx.enum.table import ( - WD_ALIGN_VERTICAL, WD_ROW_HEIGHT, WD_TABLE_ALIGNMENT, WD_TABLE_DIRECTION + WD_ALIGN_VERTICAL, + WD_ROW_HEIGHT, + WD_TABLE_ALIGNMENT, + WD_TABLE_DIRECTION, ) from docx.oxml import parse_xml from docx.oxml.table import CT_Tc @@ -25,7 +28,6 @@ class DescribeTable(object): - def it_can_add_a_row(self, add_row_fixture): table, expected_xml = add_row_fixture row = table.add_row() @@ -103,17 +105,13 @@ def it_can_change_its_direction(self, direction_set_fixture): def it_knows_its_table_style(self, style_get_fixture): table, style_id_, style_ = style_get_fixture style = table.style - table.part.get_style.assert_called_once_with( - style_id_, WD_STYLE_TYPE.TABLE - ) + table.part.get_style.assert_called_once_with(style_id_, WD_STYLE_TYPE.TABLE) assert style is style_ def it_can_change_its_table_style(self, style_set_fixture): table, value, expected_xml = style_set_fixture table.style = value - table.part.get_style_id.assert_called_once_with( - value, WD_STYLE_TYPE.TABLE - ) + table.part.get_style_id.assert_called_once_with(value, WD_STYLE_TYPE.TABLE) assert table._tbl.xml == expected_xml def it_provides_access_to_its_cells_to_help(self, cells_fixture): @@ -135,7 +133,7 @@ def it_knows_its_column_count_to_help(self, column_count_fixture): @pytest.fixture def add_column_fixture(self): - snippets = snippet_seq('add-row-col') + snippets = snippet_seq("add-row-col") tbl = parse_xml(snippets[0]) table = Table(tbl, None) width = Inches(1.5) @@ -144,76 +142,94 @@ def add_column_fixture(self): @pytest.fixture def add_row_fixture(self): - snippets = snippet_seq('add-row-col') + snippets = snippet_seq("add-row-col") tbl = parse_xml(snippets[0]) table = Table(tbl, None) expected_xml = snippets[1] return table, expected_xml - @pytest.fixture(params=[ - ('w:tbl/w:tblPr', None), - ('w:tbl/w:tblPr/w:jc{w:val=center}', WD_TABLE_ALIGNMENT.CENTER), - ('w:tbl/w:tblPr/w:jc{w:val=right}', WD_TABLE_ALIGNMENT.RIGHT), - ('w:tbl/w:tblPr/w:jc{w:val=left}', WD_TABLE_ALIGNMENT.LEFT), - ]) + @pytest.fixture( + params=[ + ("w:tbl/w:tblPr", None), + ("w:tbl/w:tblPr/w:jc{w:val=center}", WD_TABLE_ALIGNMENT.CENTER), + ("w:tbl/w:tblPr/w:jc{w:val=right}", WD_TABLE_ALIGNMENT.RIGHT), + ("w:tbl/w:tblPr/w:jc{w:val=left}", WD_TABLE_ALIGNMENT.LEFT), + ] + ) def alignment_get_fixture(self, request): tbl_cxml, expected_value = request.param table = Table(element(tbl_cxml), None) return table, expected_value - @pytest.fixture(params=[ - ('w:tbl/w:tblPr', WD_TABLE_ALIGNMENT.LEFT, - 'w:tbl/w:tblPr/w:jc{w:val=left}'), - ('w:tbl/w:tblPr/w:jc{w:val=left}', WD_TABLE_ALIGNMENT.RIGHT, - 'w:tbl/w:tblPr/w:jc{w:val=right}'), - ('w:tbl/w:tblPr/w:jc{w:val=right}', None, - 'w:tbl/w:tblPr'), - ]) + @pytest.fixture( + params=[ + ( + "w:tbl/w:tblPr", + WD_TABLE_ALIGNMENT.LEFT, + "w:tbl/w:tblPr/w:jc{w:val=left}", + ), + ( + "w:tbl/w:tblPr/w:jc{w:val=left}", + WD_TABLE_ALIGNMENT.RIGHT, + "w:tbl/w:tblPr/w:jc{w:val=right}", + ), + ("w:tbl/w:tblPr/w:jc{w:val=right}", None, "w:tbl/w:tblPr"), + ] + ) def alignment_set_fixture(self, request): tbl_cxml, new_value, expected_tbl_cxml = request.param table = Table(element(tbl_cxml), None) expected_xml = xml(expected_tbl_cxml) return table, new_value, expected_xml - @pytest.fixture(params=[ - ('w:tbl/w:tblPr', True), - ('w:tbl/w:tblPr/w:tblLayout', True), - ('w:tbl/w:tblPr/w:tblLayout{w:type=autofit}', True), - ('w:tbl/w:tblPr/w:tblLayout{w:type=fixed}', False), - ]) + @pytest.fixture( + params=[ + ("w:tbl/w:tblPr", True), + ("w:tbl/w:tblPr/w:tblLayout", True), + ("w:tbl/w:tblPr/w:tblLayout{w:type=autofit}", True), + ("w:tbl/w:tblPr/w:tblLayout{w:type=fixed}", False), + ] + ) def autofit_get_fixture(self, request): tbl_cxml, expected_autofit = request.param table = Table(element(tbl_cxml), None) return table, expected_autofit - @pytest.fixture(params=[ - ('w:tbl/w:tblPr', True, - 'w:tbl/w:tblPr/w:tblLayout{w:type=autofit}'), - ('w:tbl/w:tblPr', False, - 'w:tbl/w:tblPr/w:tblLayout{w:type=fixed}'), - ('w:tbl/w:tblPr', None, - 'w:tbl/w:tblPr/w:tblLayout{w:type=fixed}'), - ('w:tbl/w:tblPr/w:tblLayout{w:type=fixed}', True, - 'w:tbl/w:tblPr/w:tblLayout{w:type=autofit}'), - ('w:tbl/w:tblPr/w:tblLayout{w:type=autofit}', False, - 'w:tbl/w:tblPr/w:tblLayout{w:type=fixed}'), - ]) + @pytest.fixture( + params=[ + ("w:tbl/w:tblPr", True, "w:tbl/w:tblPr/w:tblLayout{w:type=autofit}"), + ("w:tbl/w:tblPr", False, "w:tbl/w:tblPr/w:tblLayout{w:type=fixed}"), + ("w:tbl/w:tblPr", None, "w:tbl/w:tblPr/w:tblLayout{w:type=fixed}"), + ( + "w:tbl/w:tblPr/w:tblLayout{w:type=fixed}", + True, + "w:tbl/w:tblPr/w:tblLayout{w:type=autofit}", + ), + ( + "w:tbl/w:tblPr/w:tblLayout{w:type=autofit}", + False, + "w:tbl/w:tblPr/w:tblLayout{w:type=fixed}", + ), + ] + ) def autofit_set_fixture(self, request): tbl_cxml, new_value, expected_tbl_cxml = request.param table = Table(element(tbl_cxml), None) expected_xml = xml(expected_tbl_cxml) return table, new_value, expected_xml - @pytest.fixture(params=[ - (0, 9, 9, ()), - (1, 9, 8, ((0, 1),)), - (2, 9, 8, ((1, 4),)), - (3, 9, 6, ((0, 1, 3, 4),)), - (4, 9, 4, ((0, 1), (3, 6), (4, 5, 7, 8))), - ]) + @pytest.fixture( + params=[ + (0, 9, 9, ()), + (1, 9, 8, ((0, 1),)), + (2, 9, 8, ((1, 4),)), + (3, 9, 6, ((0, 1, 3, 4),)), + (4, 9, 4, ((0, 1), (3, 6), (4, 5, 7, 8))), + ] + ) def cells_fixture(self, request): snippet_idx, cell_count, unique_count, matches = request.param - tbl_xml = snippet_seq('tbl-cells')[snippet_idx] + tbl_xml = snippet_seq("tbl-cells")[snippet_idx] table = Table(parse_xml(tbl_xml), None) return table, cell_count, unique_count, matches @@ -228,32 +244,40 @@ def col_cells_fixture(self, _cells_, _column_count_): @pytest.fixture def column_count_fixture(self): - tbl_cxml = 'w:tbl/w:tblGrid/(w:gridCol,w:gridCol,w:gridCol)' + tbl_cxml = "w:tbl/w:tblGrid/(w:gridCol,w:gridCol,w:gridCol)" expected_value = 3 table = Table(element(tbl_cxml), None) return table, expected_value - @pytest.fixture(params=[ - ('w:tbl/w:tblPr', None), - ('w:tbl/w:tblPr/w:bidiVisual', WD_TABLE_DIRECTION.RTL), - ('w:tbl/w:tblPr/w:bidiVisual{w:val=0}', WD_TABLE_DIRECTION.LTR), - ('w:tbl/w:tblPr/w:bidiVisual{w:val=on}', WD_TABLE_DIRECTION.RTL), - ]) + @pytest.fixture( + params=[ + ("w:tbl/w:tblPr", None), + ("w:tbl/w:tblPr/w:bidiVisual", WD_TABLE_DIRECTION.RTL), + ("w:tbl/w:tblPr/w:bidiVisual{w:val=0}", WD_TABLE_DIRECTION.LTR), + ("w:tbl/w:tblPr/w:bidiVisual{w:val=on}", WD_TABLE_DIRECTION.RTL), + ] + ) def direction_get_fixture(self, request): tbl_cxml, expected_value = request.param table = Table(element(tbl_cxml), None) return table, expected_value - @pytest.fixture(params=[ - ('w:tbl/w:tblPr', WD_TABLE_DIRECTION.RTL, - 'w:tbl/w:tblPr/w:bidiVisual'), - ('w:tbl/w:tblPr/w:bidiVisual', WD_TABLE_DIRECTION.LTR, - 'w:tbl/w:tblPr/w:bidiVisual{w:val=0}'), - ('w:tbl/w:tblPr/w:bidiVisual{w:val=0}', WD_TABLE_DIRECTION.RTL, - 'w:tbl/w:tblPr/w:bidiVisual'), - ('w:tbl/w:tblPr/w:bidiVisual{w:val=1}', None, - 'w:tbl/w:tblPr'), - ]) + @pytest.fixture( + params=[ + ("w:tbl/w:tblPr", WD_TABLE_DIRECTION.RTL, "w:tbl/w:tblPr/w:bidiVisual"), + ( + "w:tbl/w:tblPr/w:bidiVisual", + WD_TABLE_DIRECTION.LTR, + "w:tbl/w:tblPr/w:bidiVisual{w:val=0}", + ), + ( + "w:tbl/w:tblPr/w:bidiVisual{w:val=0}", + WD_TABLE_DIRECTION.RTL, + "w:tbl/w:tblPr/w:bidiVisual", + ), + ("w:tbl/w:tblPr/w:bidiVisual{w:val=1}", None, "w:tbl/w:tblPr"), + ] + ) def direction_set_fixture(self, request): tbl_cxml, new_value, expected_cxml = request.param table = Table(element(tbl_cxml), None) @@ -271,20 +295,24 @@ def row_cells_fixture(self, _cells_, _column_count_): @pytest.fixture def style_get_fixture(self, part_prop_): - style_id = 'Barbaz' - tbl_cxml = 'w:tbl/w:tblPr/w:tblStyle{w:val=%s}' % style_id + style_id = "Barbaz" + tbl_cxml = "w:tbl/w:tblPr/w:tblStyle{w:val=%s}" % style_id table = Table(element(tbl_cxml), None) style_ = part_prop_.return_value.get_style.return_value return table, style_id, style_ - @pytest.fixture(params=[ - ('w:tbl/w:tblPr', 'Tbl A', 'TblA', - 'w:tbl/w:tblPr/w:tblStyle{w:val=TblA}'), - ('w:tbl/w:tblPr/w:tblStyle{w:val=TblA}', 'Tbl B', 'TblB', - 'w:tbl/w:tblPr/w:tblStyle{w:val=TblB}'), - ('w:tbl/w:tblPr/w:tblStyle{w:val=TblB}', None, None, - 'w:tbl/w:tblPr'), - ]) + @pytest.fixture( + params=[ + ("w:tbl/w:tblPr", "Tbl A", "TblA", "w:tbl/w:tblPr/w:tblStyle{w:val=TblA}"), + ( + "w:tbl/w:tblPr/w:tblStyle{w:val=TblA}", + "Tbl B", + "TblB", + "w:tbl/w:tblPr/w:tblStyle{w:val=TblB}", + ), + ("w:tbl/w:tblPr/w:tblStyle{w:val=TblB}", None, None, "w:tbl/w:tblPr"), + ] + ) def style_set_fixture(self, request, part_prop_): tbl_cxml, value, style_id, expected_cxml = request.param table = Table(element(tbl_cxml), None) @@ -301,11 +329,11 @@ def table_fixture(self): @pytest.fixture def _cells_(self, request): - return property_mock(request, Table, '_cells') + return property_mock(request, Table, "_cells") @pytest.fixture def _column_count_(self, request): - return property_mock(request, Table, '_column_count') + return property_mock(request, Table, "_column_count") @pytest.fixture def document_part_(self, request): @@ -313,9 +341,7 @@ def document_part_(self, request): @pytest.fixture def part_prop_(self, request, document_part_): - return property_mock( - request, Table, 'part', return_value=document_part_ - ) + return property_mock(request, Table, "part", return_value=document_part_) @pytest.fixture def table(self): @@ -325,14 +351,12 @@ def table(self): class Describe_Cell(object): - def it_knows_what_text_it_contains(self, text_get_fixture): cell, expected_text = text_get_fixture text = cell.text assert text == expected_text - def it_can_replace_its_content_with_a_string_of_text( - self, text_set_fixture): + def it_can_replace_its_content_with_a_string_of_text(self, text_set_fixture): cell, text, expected_xml = text_set_fixture cell.text = text assert cell._tc.xml == expected_xml @@ -357,8 +381,7 @@ def it_can_change_its_width(self, width_set_fixture): assert cell.width == value assert cell._tc.xml == expected_xml - def it_provides_access_to_the_paragraphs_it_contains( - self, paragraphs_fixture): + def it_provides_access_to_the_paragraphs_it_contains(self, paragraphs_fixture): cell = paragraphs_fixture paragraphs = cell.paragraphs assert len(paragraphs) == 2 @@ -403,11 +426,13 @@ def it_can_merge_itself_with_other_cells(self, merge_fixture): # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - ('w:tc', 'w:tc/w:p'), - ('w:tc/w:p', 'w:tc/(w:p, w:p)'), - ('w:tc/w:tbl', 'w:tc/(w:tbl, w:p)'), - ]) + @pytest.fixture( + params=[ + ("w:tc", "w:tc/w:p"), + ("w:tc/w:p", "w:tc/(w:p, w:p)"), + ("w:tc/w:tbl", "w:tc/(w:tbl, w:p)"), + ] + ) def add_paragraph_fixture(self, request): tc_cxml, after_tc_cxml = request.param cell = _Cell(element(tc_cxml), None) @@ -416,35 +441,41 @@ def add_paragraph_fixture(self, request): @pytest.fixture def add_table_fixture(self, request): - cell = _Cell(element('w:tc/w:p'), None) - expected_xml = snippet_seq('new-tbl')[1] + cell = _Cell(element("w:tc/w:p"), None) + expected_xml = snippet_seq("new-tbl")[1] return cell, expected_xml - @pytest.fixture(params=[ - ('w:tc', None), - ('w:tc/w:tcPr', None), - ('w:tc/w:tcPr/w:vAlign{w:val=bottom}', WD_ALIGN_VERTICAL.BOTTOM), - ('w:tc/w:tcPr/w:vAlign{w:val=top}', WD_ALIGN_VERTICAL.TOP), - ]) + @pytest.fixture( + params=[ + ("w:tc", None), + ("w:tc/w:tcPr", None), + ("w:tc/w:tcPr/w:vAlign{w:val=bottom}", WD_ALIGN_VERTICAL.BOTTOM), + ("w:tc/w:tcPr/w:vAlign{w:val=top}", WD_ALIGN_VERTICAL.TOP), + ] + ) def alignment_get_fixture(self, request): tc_cxml, expected_value = request.param cell = _Cell(element(tc_cxml), None) return cell, expected_value - @pytest.fixture(params=[ - ('w:tc', WD_ALIGN_VERTICAL.TOP, - 'w:tc/w:tcPr/w:vAlign{w:val=top}'), - ('w:tc/w:tcPr', WD_ALIGN_VERTICAL.CENTER, - 'w:tc/w:tcPr/w:vAlign{w:val=center}'), - ('w:tc/w:tcPr/w:vAlign{w:val=center}', WD_ALIGN_VERTICAL.BOTTOM, - 'w:tc/w:tcPr/w:vAlign{w:val=bottom}'), - ('w:tc/w:tcPr/w:vAlign{w:val=center}', None, - 'w:tc/w:tcPr'), - ('w:tc', None, - 'w:tc/w:tcPr'), - ('w:tc/w:tcPr', None, - 'w:tc/w:tcPr'), - ]) + @pytest.fixture( + params=[ + ("w:tc", WD_ALIGN_VERTICAL.TOP, "w:tc/w:tcPr/w:vAlign{w:val=top}"), + ( + "w:tc/w:tcPr", + WD_ALIGN_VERTICAL.CENTER, + "w:tc/w:tcPr/w:vAlign{w:val=center}", + ), + ( + "w:tc/w:tcPr/w:vAlign{w:val=center}", + WD_ALIGN_VERTICAL.BOTTOM, + "w:tc/w:tcPr/w:vAlign{w:val=bottom}", + ), + ("w:tc/w:tcPr/w:vAlign{w:val=center}", None, "w:tc/w:tcPr"), + ("w:tc", None, "w:tc/w:tcPr"), + ("w:tc/w:tcPr", None, "w:tc/w:tcPr"), + ] + ) def alignment_set_fixture(self, request): cxml, new_value, expected_cxml = request.param cell = _Cell(element(cxml), None) @@ -459,64 +490,80 @@ def merge_fixture(self, tc_, tc_2_, parent_, merged_tc_): @pytest.fixture def paragraphs_fixture(self): - return _Cell(element('w:tc/(w:p, w:p)'), None) - - @pytest.fixture(params=[ - ('w:tc', 0), - ('w:tc/w:tbl', 1), - ('w:tc/(w:tbl,w:tbl)', 2), - ('w:tc/(w:p,w:tbl)', 1), - ('w:tc/(w:tbl,w:tbl,w:p)', 2), - ]) + return _Cell(element("w:tc/(w:p, w:p)"), None) + + @pytest.fixture( + params=[ + ("w:tc", 0), + ("w:tc/w:tbl", 1), + ("w:tc/(w:tbl,w:tbl)", 2), + ("w:tc/(w:p,w:tbl)", 1), + ("w:tc/(w:tbl,w:tbl,w:p)", 2), + ] + ) def tables_fixture(self, request): cell_cxml, expected_count = request.param cell = _Cell(element(cell_cxml), None) return cell, expected_count - @pytest.fixture(params=[ - ('w:tc', ''), - ('w:tc/w:p/w:r/w:t"foobar"', 'foobar'), - ('w:tc/(w:p/w:r/w:t"foo",w:p/w:r/w:t"bar")', 'foo\nbar'), - ('w:tc/(w:tcPr,w:p/w:r/w:t"foobar")', 'foobar'), - ('w:tc/w:p/w:r/(w:t"fo",w:tab,w:t"ob",w:br,w:t"ar",w:br)', - 'fo\tob\nar\n'), - ]) + @pytest.fixture( + params=[ + ("w:tc", ""), + ('w:tc/w:p/w:r/w:t"foobar"', "foobar"), + ('w:tc/(w:p/w:r/w:t"foo",w:p/w:r/w:t"bar")', "foo\nbar"), + ('w:tc/(w:tcPr,w:p/w:r/w:t"foobar")', "foobar"), + ('w:tc/w:p/w:r/(w:t"fo",w:tab,w:t"ob",w:br,w:t"ar",w:br)', "fo\tob\nar\n"), + ] + ) def text_get_fixture(self, request): tc_cxml, expected_text = request.param cell = _Cell(element(tc_cxml), None) return cell, expected_text - @pytest.fixture(params=[ - ('w:tc/w:p', 'foobar', - 'w:tc/w:p/w:r/w:t"foobar"'), - ('w:tc/w:p', 'fo\tob\rar\n', - 'w:tc/w:p/w:r/(w:t"fo",w:tab,w:t"ob",w:br,w:t"ar",w:br)'), - ('w:tc/(w:tcPr, w:p, w:tbl, w:p)', 'foobar', - 'w:tc/(w:tcPr, w:p/w:r/w:t"foobar")'), - ]) + @pytest.fixture( + params=[ + ("w:tc/w:p", "foobar", 'w:tc/w:p/w:r/w:t"foobar"'), + ( + "w:tc/w:p", + "fo\tob\rar\n", + 'w:tc/w:p/w:r/(w:t"fo",w:tab,w:t"ob",w:br,w:t"ar",w:br)', + ), + ( + "w:tc/(w:tcPr, w:p, w:tbl, w:p)", + "foobar", + 'w:tc/(w:tcPr, w:p/w:r/w:t"foobar")', + ), + ] + ) def text_set_fixture(self, request): tc_cxml, new_text, expected_cxml = request.param cell = _Cell(element(tc_cxml), None) expected_xml = xml(expected_cxml) return cell, new_text, expected_xml - @pytest.fixture(params=[ - ('w:tc', None), - ('w:tc/w:tcPr', None), - ('w:tc/w:tcPr/w:tcW{w:w=25%,w:type=pct}', None), - ('w:tc/w:tcPr/w:tcW{w:w=1440,w:type=dxa}', 914400), - ]) + @pytest.fixture( + params=[ + ("w:tc", None), + ("w:tc/w:tcPr", None), + ("w:tc/w:tcPr/w:tcW{w:w=25%,w:type=pct}", None), + ("w:tc/w:tcPr/w:tcW{w:w=1440,w:type=dxa}", 914400), + ] + ) def width_get_fixture(self, request): tc_cxml, expected_width = request.param cell = _Cell(element(tc_cxml), None) return cell, expected_width - @pytest.fixture(params=[ - ('w:tc', Inches(1), - 'w:tc/w:tcPr/w:tcW{w:w=1440,w:type=dxa}'), - ('w:tc/w:tcPr/w:tcW{w:w=25%,w:type=pct}', Inches(2), - 'w:tc/w:tcPr/w:tcW{w:w=2880,w:type=dxa}'), - ]) + @pytest.fixture( + params=[ + ("w:tc", Inches(1), "w:tc/w:tcPr/w:tcW{w:w=1440,w:type=dxa}"), + ( + "w:tc/w:tcPr/w:tcW{w:w=25%,w:type=pct}", + Inches(2), + "w:tc/w:tcPr/w:tcW{w:w=2880,w:type=dxa}", + ), + ] + ) def width_set_fixture(self, request): tc_cxml, new_value, expected_cxml = request.param cell = _Cell(element(tc_cxml), None) @@ -543,7 +590,6 @@ def tc_2_(self, request): class Describe_Column(object): - def it_provides_access_to_its_cells(self, cells_fixture): column, column_idx, expected_cells = cells_fixture cells = column.cells @@ -580,7 +626,7 @@ def cells_fixture(self, _index_, table_prop_, table_): @pytest.fixture def index_fixture(self): - tbl = element('w:tbl/w:tblGrid/(w:gridCol,w:gridCol,w:gridCol)') + tbl = element("w:tbl/w:tblGrid/(w:gridCol,w:gridCol,w:gridCol)") gridCol, expected_idx = tbl.tblGrid[1], 1 column = _Column(gridCol, None) return column, expected_idx @@ -591,25 +637,29 @@ def table_fixture(self, parent_, table_): parent_.table = table_ return column, table_ - @pytest.fixture(params=[ - ('w:gridCol{w:w=4242}', 2693670), - ('w:gridCol{w:w=1440}', 914400), - ('w:gridCol{w:w=2.54cm}', 914400), - ('w:gridCol{w:w=54mm}', 1944000), - ('w:gridCol{w:w=12.5pt}', 158750), - ('w:gridCol', None), - ]) + @pytest.fixture( + params=[ + ("w:gridCol{w:w=4242}", 2693670), + ("w:gridCol{w:w=1440}", 914400), + ("w:gridCol{w:w=2.54cm}", 914400), + ("w:gridCol{w:w=54mm}", 1944000), + ("w:gridCol{w:w=12.5pt}", 158750), + ("w:gridCol", None), + ] + ) def width_get_fixture(self, request): gridCol_cxml, expected_width = request.param column = _Column(element(gridCol_cxml), None) return column, expected_width - @pytest.fixture(params=[ - ('w:gridCol', 914400, 'w:gridCol{w:w=1440}'), - ('w:gridCol{w:w=4242}', 457200, 'w:gridCol{w:w=720}'), - ('w:gridCol{w:w=4242}', None, 'w:gridCol'), - ('w:gridCol', None, 'w:gridCol'), - ]) + @pytest.fixture( + params=[ + ("w:gridCol", 914400, "w:gridCol{w:w=1440}"), + ("w:gridCol{w:w=4242}", 457200, "w:gridCol{w:w=720}"), + ("w:gridCol{w:w=4242}", None, "w:gridCol"), + ("w:gridCol", None, "w:gridCol"), + ] + ) def width_set_fixture(self, request): gridCol_cxml, new_value, expected_cxml = request.param column = _Column(element(gridCol_cxml), None) @@ -620,7 +670,7 @@ def width_set_fixture(self, request): @pytest.fixture def _index_(self, request): - return property_mock(request, _Column, '_index') + return property_mock(request, _Column, "_index") @pytest.fixture def parent_(self, request): @@ -632,11 +682,10 @@ def table_(self, request): @pytest.fixture def table_prop_(self, request, table_): - return property_mock(request, _Column, 'table', return_value=table_) + return property_mock(request, _Column, "table", return_value=table_) class Describe_Columns(object): - def it_knows_how_many_columns_it_contains(self, columns_fixture): columns, column_count = columns_fixture assert len(columns) == column_count @@ -691,7 +740,6 @@ def table_(self, request): class Describe_Row(object): - def it_knows_its_height(self, height_get_fixture): row, expected_height = height_get_fixture assert row.height == expected_height @@ -734,74 +782,90 @@ def cells_fixture(self, _index_, table_prop_, table_): table_.row_cells.return_value = list(expected_cells) return row, row_idx, expected_cells - @pytest.fixture(params=[ - ('w:tr', None), - ('w:tr/w:trPr', None), - ('w:tr/w:trPr/w:trHeight', None), - ('w:tr/w:trPr/w:trHeight{w:val=0}', 0), - ('w:tr/w:trPr/w:trHeight{w:val=1440}', 914400), - ]) + @pytest.fixture( + params=[ + ("w:tr", None), + ("w:tr/w:trPr", None), + ("w:tr/w:trPr/w:trHeight", None), + ("w:tr/w:trPr/w:trHeight{w:val=0}", 0), + ("w:tr/w:trPr/w:trHeight{w:val=1440}", 914400), + ] + ) def height_get_fixture(self, request): tr_cxml, expected_height = request.param row = _Row(element(tr_cxml), None) return row, expected_height - @pytest.fixture(params=[ - ('w:tr', Inches(1), - 'w:tr/w:trPr/w:trHeight{w:val=1440}'), - ('w:tr/w:trPr', Inches(1), - 'w:tr/w:trPr/w:trHeight{w:val=1440}'), - ('w:tr/w:trPr/w:trHeight', Inches(1), - 'w:tr/w:trPr/w:trHeight{w:val=1440}'), - ('w:tr/w:trPr/w:trHeight{w:val=1440}', Inches(2), - 'w:tr/w:trPr/w:trHeight{w:val=2880}'), - ('w:tr/w:trPr/w:trHeight{w:val=2880}', None, - 'w:tr/w:trPr/w:trHeight'), - ('w:tr', None, 'w:tr/w:trPr'), - ('w:tr/w:trPr', None, 'w:tr/w:trPr'), - ('w:tr/w:trPr/w:trHeight', None, 'w:tr/w:trPr/w:trHeight'), - ]) + @pytest.fixture( + params=[ + ("w:tr", Inches(1), "w:tr/w:trPr/w:trHeight{w:val=1440}"), + ("w:tr/w:trPr", Inches(1), "w:tr/w:trPr/w:trHeight{w:val=1440}"), + ("w:tr/w:trPr/w:trHeight", Inches(1), "w:tr/w:trPr/w:trHeight{w:val=1440}"), + ( + "w:tr/w:trPr/w:trHeight{w:val=1440}", + Inches(2), + "w:tr/w:trPr/w:trHeight{w:val=2880}", + ), + ("w:tr/w:trPr/w:trHeight{w:val=2880}", None, "w:tr/w:trPr/w:trHeight"), + ("w:tr", None, "w:tr/w:trPr"), + ("w:tr/w:trPr", None, "w:tr/w:trPr"), + ("w:tr/w:trPr/w:trHeight", None, "w:tr/w:trPr/w:trHeight"), + ] + ) def height_set_fixture(self, request): tr_cxml, new_value, expected_cxml = request.param row = _Row(element(tr_cxml), None) expected_xml = xml(expected_cxml) return row, new_value, expected_xml - @pytest.fixture(params=[ - ('w:tr', None), - ('w:tr/w:trPr', None), - ('w:tr/w:trPr/w:trHeight{w:val=0, w:hRule=auto}', - WD_ROW_HEIGHT.AUTO), - ('w:tr/w:trPr/w:trHeight{w:val=1440, w:hRule=atLeast}', - WD_ROW_HEIGHT.AT_LEAST), - ('w:tr/w:trPr/w:trHeight{w:val=2880, w:hRule=exact}', - WD_ROW_HEIGHT.EXACTLY), - ]) + @pytest.fixture( + params=[ + ("w:tr", None), + ("w:tr/w:trPr", None), + ("w:tr/w:trPr/w:trHeight{w:val=0, w:hRule=auto}", WD_ROW_HEIGHT.AUTO), + ( + "w:tr/w:trPr/w:trHeight{w:val=1440, w:hRule=atLeast}", + WD_ROW_HEIGHT.AT_LEAST, + ), + ( + "w:tr/w:trPr/w:trHeight{w:val=2880, w:hRule=exact}", + WD_ROW_HEIGHT.EXACTLY, + ), + ] + ) def height_rule_get_fixture(self, request): tr_cxml, expected_rule = request.param row = _Row(element(tr_cxml), None) return row, expected_rule - @pytest.fixture(params=[ - ('w:tr', - WD_ROW_HEIGHT.AUTO, - 'w:tr/w:trPr/w:trHeight{w:hRule=auto}'), - ('w:tr/w:trPr', - WD_ROW_HEIGHT.AT_LEAST, - 'w:tr/w:trPr/w:trHeight{w:hRule=atLeast}'), - ('w:tr/w:trPr/w:trHeight', - WD_ROW_HEIGHT.EXACTLY, - 'w:tr/w:trPr/w:trHeight{w:hRule=exact}'), - ('w:tr/w:trPr/w:trHeight{w:val=1440, w:hRule=exact}', - WD_ROW_HEIGHT.AUTO, - 'w:tr/w:trPr/w:trHeight{w:val=1440, w:hRule=auto}'), - ('w:tr/w:trPr/w:trHeight{w:val=1440, w:hRule=auto}', - None, - 'w:tr/w:trPr/w:trHeight{w:val=1440}'), - ('w:tr', None, 'w:tr/w:trPr'), - ('w:tr/w:trPr', None, 'w:tr/w:trPr'), - ('w:tr/w:trPr/w:trHeight', None, 'w:tr/w:trPr/w:trHeight'), - ]) + @pytest.fixture( + params=[ + ("w:tr", WD_ROW_HEIGHT.AUTO, "w:tr/w:trPr/w:trHeight{w:hRule=auto}"), + ( + "w:tr/w:trPr", + WD_ROW_HEIGHT.AT_LEAST, + "w:tr/w:trPr/w:trHeight{w:hRule=atLeast}", + ), + ( + "w:tr/w:trPr/w:trHeight", + WD_ROW_HEIGHT.EXACTLY, + "w:tr/w:trPr/w:trHeight{w:hRule=exact}", + ), + ( + "w:tr/w:trPr/w:trHeight{w:val=1440, w:hRule=exact}", + WD_ROW_HEIGHT.AUTO, + "w:tr/w:trPr/w:trHeight{w:val=1440, w:hRule=auto}", + ), + ( + "w:tr/w:trPr/w:trHeight{w:val=1440, w:hRule=auto}", + None, + "w:tr/w:trPr/w:trHeight{w:val=1440}", + ), + ("w:tr", None, "w:tr/w:trPr"), + ("w:tr/w:trPr", None, "w:tr/w:trPr"), + ("w:tr/w:trPr/w:trHeight", None, "w:tr/w:trPr/w:trHeight"), + ] + ) def height_rule_set_fixture(self, request): tr_cxml, new_rule, expected_cxml = request.param row = _Row(element(tr_cxml), None) @@ -810,7 +874,7 @@ def height_rule_set_fixture(self, request): @pytest.fixture def idx_fixture(self): - tbl = element('w:tbl/(w:tr,w:tr,w:tr)') + tbl = element("w:tbl/(w:tr,w:tr,w:tr)") tr, expected_idx = tbl[1], 1 row = _Row(tr, None) return row, expected_idx @@ -825,7 +889,7 @@ def table_fixture(self, parent_, table_): @pytest.fixture def _index_(self, request): - return property_mock(request, _Row, '_index') + return property_mock(request, _Row, "_index") @pytest.fixture def parent_(self, request): @@ -837,11 +901,10 @@ def table_(self, request): @pytest.fixture def table_prop_(self, request, table_): - return property_mock(request, _Row, 'table', return_value=table_) + return property_mock(request, _Row, "table", return_value=table_) class Describe_Rows(object): - def it_knows_how_many_rows_it_contains(self, rows_fixture): rows, row_count = rows_fixture assert len(rows) == row_count @@ -891,10 +954,12 @@ def rows_fixture(self): rows = _Rows(tbl, None) return rows, row_count - @pytest.fixture(params=[ - (3, 1, 3, 2), - (3, 0, -1, 2), - ]) + @pytest.fixture( + params=[ + (3, 1, 3, 2), + (3, 0, -1, 2), + ] + ) def slice_fixture(self, request): row_count, start, end, expected_count = request.param tbl = _tbl_bldr(rows=row_count, cols=2).element @@ -916,6 +981,7 @@ def table_(self, request): # fixtures ----------------------------------------------------------- + def _tbl_bldr(rows, cols): tblGrid_bldr = a_tblGrid() for i in range(cols): diff --git a/tests/text/test_font.py b/tests/text/test_font.py index 52564b12..5b4b15eb 100644 --- a/tests/text/test_font.py +++ b/tests/text/test_font.py @@ -4,9 +4,7 @@ Test suite for the docx.text.run module """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals from docx.dml.color import ColorFormat from docx.enum.text import WD_COLOR, WD_UNDERLINE @@ -20,7 +18,6 @@ class DescribeFont(object): - def it_provides_access_to_its_color_object(self, color_fixture): font, color_, ColorFormat_ = color_fixture color = font.color @@ -92,86 +89,99 @@ def it_can_change_its_highlight_color(self, highlight_set_fixture): # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - ('w:r/w:rPr', 'all_caps', None), - ('w:r/w:rPr/w:caps', 'all_caps', True), - ('w:r/w:rPr/w:caps{w:val=on}', 'all_caps', True), - ('w:r/w:rPr/w:caps{w:val=off}', 'all_caps', False), - ('w:r/w:rPr/w:b{w:val=1}', 'bold', True), - ('w:r/w:rPr/w:i{w:val=0}', 'italic', False), - ('w:r/w:rPr/w:cs{w:val=true}', 'complex_script', True), - ('w:r/w:rPr/w:bCs{w:val=false}', 'cs_bold', False), - ('w:r/w:rPr/w:iCs{w:val=on}', 'cs_italic', True), - ('w:r/w:rPr/w:dstrike{w:val=off}', 'double_strike', False), - ('w:r/w:rPr/w:emboss{w:val=1}', 'emboss', True), - ('w:r/w:rPr/w:vanish{w:val=0}', 'hidden', False), - ('w:r/w:rPr/w:i{w:val=true}', 'italic', True), - ('w:r/w:rPr/w:imprint{w:val=false}', 'imprint', False), - ('w:r/w:rPr/w:oMath{w:val=on}', 'math', True), - ('w:r/w:rPr/w:noProof{w:val=off}', 'no_proof', False), - ('w:r/w:rPr/w:outline{w:val=1}', 'outline', True), - ('w:r/w:rPr/w:rtl{w:val=0}', 'rtl', False), - ('w:r/w:rPr/w:shadow{w:val=true}', 'shadow', True), - ('w:r/w:rPr/w:smallCaps{w:val=false}', 'small_caps', False), - ('w:r/w:rPr/w:snapToGrid{w:val=on}', 'snap_to_grid', True), - ('w:r/w:rPr/w:specVanish{w:val=off}', 'spec_vanish', False), - ('w:r/w:rPr/w:strike{w:val=1}', 'strike', True), - ('w:r/w:rPr/w:webHidden{w:val=0}', 'web_hidden', False), - ]) + @pytest.fixture( + params=[ + ("w:r/w:rPr", "all_caps", None), + ("w:r/w:rPr/w:caps", "all_caps", True), + ("w:r/w:rPr/w:caps{w:val=on}", "all_caps", True), + ("w:r/w:rPr/w:caps{w:val=off}", "all_caps", False), + ("w:r/w:rPr/w:b{w:val=1}", "bold", True), + ("w:r/w:rPr/w:i{w:val=0}", "italic", False), + ("w:r/w:rPr/w:cs{w:val=true}", "complex_script", True), + ("w:r/w:rPr/w:bCs{w:val=false}", "cs_bold", False), + ("w:r/w:rPr/w:iCs{w:val=on}", "cs_italic", True), + ("w:r/w:rPr/w:dstrike{w:val=off}", "double_strike", False), + ("w:r/w:rPr/w:emboss{w:val=1}", "emboss", True), + ("w:r/w:rPr/w:vanish{w:val=0}", "hidden", False), + ("w:r/w:rPr/w:i{w:val=true}", "italic", True), + ("w:r/w:rPr/w:imprint{w:val=false}", "imprint", False), + ("w:r/w:rPr/w:oMath{w:val=on}", "math", True), + ("w:r/w:rPr/w:noProof{w:val=off}", "no_proof", False), + ("w:r/w:rPr/w:outline{w:val=1}", "outline", True), + ("w:r/w:rPr/w:rtl{w:val=0}", "rtl", False), + ("w:r/w:rPr/w:shadow{w:val=true}", "shadow", True), + ("w:r/w:rPr/w:smallCaps{w:val=false}", "small_caps", False), + ("w:r/w:rPr/w:snapToGrid{w:val=on}", "snap_to_grid", True), + ("w:r/w:rPr/w:specVanish{w:val=off}", "spec_vanish", False), + ("w:r/w:rPr/w:strike{w:val=1}", "strike", True), + ("w:r/w:rPr/w:webHidden{w:val=0}", "web_hidden", False), + ] + ) def bool_prop_get_fixture(self, request): r_cxml, bool_prop_name, expected_value = request.param font = Font(element(r_cxml)) return font, bool_prop_name, expected_value - @pytest.fixture(params=[ - # nothing to True, False, and None --------------------------- - ('w:r', 'all_caps', True, - 'w:r/w:rPr/w:caps'), - ('w:r', 'bold', False, - 'w:r/w:rPr/w:b{w:val=0}'), - ('w:r', 'italic', None, - 'w:r/w:rPr'), - # default to True, False, and None --------------------------- - ('w:r/w:rPr/w:cs', 'complex_script', True, - 'w:r/w:rPr/w:cs'), - ('w:r/w:rPr/w:bCs', 'cs_bold', False, - 'w:r/w:rPr/w:bCs{w:val=0}'), - ('w:r/w:rPr/w:iCs', 'cs_italic', None, - 'w:r/w:rPr'), - # True to True, False, and None ------------------------------ - ('w:r/w:rPr/w:dstrike{w:val=1}', 'double_strike', True, - 'w:r/w:rPr/w:dstrike'), - ('w:r/w:rPr/w:emboss{w:val=on}', 'emboss', False, - 'w:r/w:rPr/w:emboss{w:val=0}'), - ('w:r/w:rPr/w:vanish{w:val=1}', 'hidden', None, - 'w:r/w:rPr'), - # False to True, False, and None ----------------------------- - ('w:r/w:rPr/w:i{w:val=false}', 'italic', True, - 'w:r/w:rPr/w:i'), - ('w:r/w:rPr/w:imprint{w:val=0}', 'imprint', False, - 'w:r/w:rPr/w:imprint{w:val=0}'), - ('w:r/w:rPr/w:oMath{w:val=off}', 'math', None, - 'w:r/w:rPr'), - # random mix ------------------------------------------------- - ('w:r/w:rPr/w:noProof{w:val=1}', 'no_proof', False, - 'w:r/w:rPr/w:noProof{w:val=0}'), - ('w:r/w:rPr', 'outline', True, - 'w:r/w:rPr/w:outline'), - ('w:r/w:rPr/w:rtl{w:val=true}', 'rtl', False, - 'w:r/w:rPr/w:rtl{w:val=0}'), - ('w:r/w:rPr/w:shadow{w:val=on}', 'shadow', True, - 'w:r/w:rPr/w:shadow'), - ('w:r/w:rPr/w:smallCaps', 'small_caps', False, - 'w:r/w:rPr/w:smallCaps{w:val=0}'), - ('w:r/w:rPr/w:snapToGrid', 'snap_to_grid', True, - 'w:r/w:rPr/w:snapToGrid'), - ('w:r/w:rPr/w:specVanish', 'spec_vanish', None, - 'w:r/w:rPr'), - ('w:r/w:rPr/w:strike{w:val=foo}', 'strike', True, - 'w:r/w:rPr/w:strike'), - ('w:r/w:rPr/w:webHidden', 'web_hidden', False, - 'w:r/w:rPr/w:webHidden{w:val=0}'), - ]) + @pytest.fixture( + params=[ + # nothing to True, False, and None --------------------------- + ("w:r", "all_caps", True, "w:r/w:rPr/w:caps"), + ("w:r", "bold", False, "w:r/w:rPr/w:b{w:val=0}"), + ("w:r", "italic", None, "w:r/w:rPr"), + # default to True, False, and None --------------------------- + ("w:r/w:rPr/w:cs", "complex_script", True, "w:r/w:rPr/w:cs"), + ("w:r/w:rPr/w:bCs", "cs_bold", False, "w:r/w:rPr/w:bCs{w:val=0}"), + ("w:r/w:rPr/w:iCs", "cs_italic", None, "w:r/w:rPr"), + # True to True, False, and None ------------------------------ + ( + "w:r/w:rPr/w:dstrike{w:val=1}", + "double_strike", + True, + "w:r/w:rPr/w:dstrike", + ), + ( + "w:r/w:rPr/w:emboss{w:val=on}", + "emboss", + False, + "w:r/w:rPr/w:emboss{w:val=0}", + ), + ("w:r/w:rPr/w:vanish{w:val=1}", "hidden", None, "w:r/w:rPr"), + # False to True, False, and None ----------------------------- + ("w:r/w:rPr/w:i{w:val=false}", "italic", True, "w:r/w:rPr/w:i"), + ( + "w:r/w:rPr/w:imprint{w:val=0}", + "imprint", + False, + "w:r/w:rPr/w:imprint{w:val=0}", + ), + ("w:r/w:rPr/w:oMath{w:val=off}", "math", None, "w:r/w:rPr"), + # random mix ------------------------------------------------- + ( + "w:r/w:rPr/w:noProof{w:val=1}", + "no_proof", + False, + "w:r/w:rPr/w:noProof{w:val=0}", + ), + ("w:r/w:rPr", "outline", True, "w:r/w:rPr/w:outline"), + ("w:r/w:rPr/w:rtl{w:val=true}", "rtl", False, "w:r/w:rPr/w:rtl{w:val=0}"), + ("w:r/w:rPr/w:shadow{w:val=on}", "shadow", True, "w:r/w:rPr/w:shadow"), + ( + "w:r/w:rPr/w:smallCaps", + "small_caps", + False, + "w:r/w:rPr/w:smallCaps{w:val=0}", + ), + ("w:r/w:rPr/w:snapToGrid", "snap_to_grid", True, "w:r/w:rPr/w:snapToGrid"), + ("w:r/w:rPr/w:specVanish", "spec_vanish", None, "w:r/w:rPr"), + ("w:r/w:rPr/w:strike{w:val=foo}", "strike", True, "w:r/w:rPr/w:strike"), + ( + "w:r/w:rPr/w:webHidden", + "web_hidden", + False, + "w:r/w:rPr/w:webHidden{w:val=0}", + ), + ] + ) def bool_prop_set_fixture(self, request): r_cxml, prop_name, value, expected_cxml = request.param font = Font(element(r_cxml)) @@ -180,199 +190,240 @@ def bool_prop_set_fixture(self, request): @pytest.fixture def color_fixture(self, ColorFormat_, color_): - font = Font(element('w:r')) + font = Font(element("w:r")) return font, color_, ColorFormat_ - @pytest.fixture(params=[ - ('w:r', None), - ('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), - ]) + @pytest.fixture( + params=[ + ("w:r", None), + ("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), + ] + ) def highlight_get_fixture(self, request): r_cxml, expected_value = request.param font = Font(element(r_cxml), None) return font, expected_value - @pytest.fixture(params=[ - ('w:r', WD_COLOR.AUTO, - 'w:r/w:rPr/w:highlight{w:val=default}'), - ('w:r/w:rPr', WD_COLOR.BRIGHT_GREEN, - 'w:r/w:rPr/w:highlight{w:val=green}'), - ('w:r/w:rPr/w:highlight{w:val=green}', WD_COLOR.YELLOW, - 'w:r/w:rPr/w:highlight{w:val=yellow}'), - ('w:r/w:rPr/w:highlight{w:val=yellow}', None, - 'w:r/w:rPr'), - ('w:r/w:rPr', None, - 'w:r/w:rPr'), - ('w:r', None, - 'w:r/w:rPr'), - ]) + @pytest.fixture( + params=[ + ("w:r", WD_COLOR.AUTO, "w:r/w:rPr/w:highlight{w:val=default}"), + ("w:r/w:rPr", WD_COLOR.BRIGHT_GREEN, "w:r/w:rPr/w:highlight{w:val=green}"), + ( + "w:r/w:rPr/w:highlight{w:val=green}", + WD_COLOR.YELLOW, + "w:r/w:rPr/w:highlight{w:val=yellow}", + ), + ("w:r/w:rPr/w:highlight{w:val=yellow}", None, "w:r/w:rPr"), + ("w:r/w:rPr", None, "w:r/w:rPr"), + ("w:r", None, "w:r/w:rPr"), + ] + ) def highlight_set_fixture(self, request): r_cxml, value, expected_cxml = request.param font = Font(element(r_cxml), None) expected_xml = xml(expected_cxml) return font, value, expected_xml - @pytest.fixture(params=[ - ('w:r', None), - ('w:r/w:rPr', None), - ('w:r/w:rPr/w:rFonts', None), - ('w:r/w:rPr/w:rFonts{w:ascii=Arial}', 'Arial'), - ]) + @pytest.fixture( + params=[ + ("w:r", None), + ("w:r/w:rPr", None), + ("w:r/w:rPr/w:rFonts", None), + ("w:r/w:rPr/w:rFonts{w:ascii=Arial}", "Arial"), + ] + ) def name_get_fixture(self, request): r_cxml, expected_value = request.param font = Font(element(r_cxml)) return font, expected_value - @pytest.fixture(params=[ - ('w:r', 'Foo', - 'w:r/w:rPr/w:rFonts{w:ascii=Foo,w:hAnsi=Foo}'), - ('w:r/w:rPr', 'Foo', - 'w:r/w:rPr/w:rFonts{w:ascii=Foo,w:hAnsi=Foo}'), - ('w:r/w:rPr/w:rFonts{w:hAnsi=Foo}', 'Bar', - 'w:r/w:rPr/w:rFonts{w:ascii=Bar,w:hAnsi=Bar}'), - ('w:r/w:rPr/w:rFonts{w:ascii=Foo,w:hAnsi=Foo}', 'Bar', - 'w:r/w:rPr/w:rFonts{w:ascii=Bar,w:hAnsi=Bar}'), - ]) + @pytest.fixture( + params=[ + ("w:r", "Foo", "w:r/w:rPr/w:rFonts{w:ascii=Foo,w:hAnsi=Foo}"), + ("w:r/w:rPr", "Foo", "w:r/w:rPr/w:rFonts{w:ascii=Foo,w:hAnsi=Foo}"), + ( + "w:r/w:rPr/w:rFonts{w:hAnsi=Foo}", + "Bar", + "w:r/w:rPr/w:rFonts{w:ascii=Bar,w:hAnsi=Bar}", + ), + ( + "w:r/w:rPr/w:rFonts{w:ascii=Foo,w:hAnsi=Foo}", + "Bar", + "w:r/w:rPr/w:rFonts{w:ascii=Bar,w:hAnsi=Bar}", + ), + ] + ) def name_set_fixture(self, request): r_cxml, value, expected_r_cxml = request.param font = Font(element(r_cxml)) expected_xml = xml(expected_r_cxml) return font, value, expected_xml - @pytest.fixture(params=[ - ('w:r', None), - ('w:r/w:rPr', None), - ('w:r/w:rPr/w:sz{w:val=28}', Pt(14)), - ]) + @pytest.fixture( + params=[ + ("w:r", None), + ("w:r/w:rPr", None), + ("w:r/w:rPr/w:sz{w:val=28}", Pt(14)), + ] + ) def size_get_fixture(self, request): r_cxml, expected_value = request.param font = Font(element(r_cxml)) return font, expected_value - @pytest.fixture(params=[ - ('w:r', Pt(12), 'w:r/w:rPr/w:sz{w:val=24}'), - ('w:r/w:rPr', Pt(12), 'w:r/w:rPr/w:sz{w:val=24}'), - ('w:r/w:rPr/w:sz{w:val=24}', Pt(18), 'w:r/w:rPr/w:sz{w:val=36}'), - ('w:r/w:rPr/w:sz{w:val=36}', None, 'w:r/w:rPr'), - ]) + @pytest.fixture( + params=[ + ("w:r", Pt(12), "w:r/w:rPr/w:sz{w:val=24}"), + ("w:r/w:rPr", Pt(12), "w:r/w:rPr/w:sz{w:val=24}"), + ("w:r/w:rPr/w:sz{w:val=24}", Pt(18), "w:r/w:rPr/w:sz{w:val=36}"), + ("w:r/w:rPr/w:sz{w:val=36}", None, "w:r/w:rPr"), + ] + ) def size_set_fixture(self, request): r_cxml, value, expected_r_cxml = request.param font = Font(element(r_cxml)) expected_xml = xml(expected_r_cxml) return font, value, expected_xml - @pytest.fixture(params=[ - ('w:r', None), - ('w:r/w:rPr', None), - ('w:r/w:rPr/w:vertAlign{w:val=baseline}', False), - ('w:r/w:rPr/w:vertAlign{w:val=subscript}', True), - ('w:r/w:rPr/w:vertAlign{w:val=superscript}', False), - ]) + @pytest.fixture( + params=[ + ("w:r", None), + ("w:r/w:rPr", None), + ("w:r/w:rPr/w:vertAlign{w:val=baseline}", False), + ("w:r/w:rPr/w:vertAlign{w:val=subscript}", True), + ("w:r/w:rPr/w:vertAlign{w:val=superscript}", False), + ] + ) def subscript_get_fixture(self, request): r_cxml, expected_value = request.param font = Font(element(r_cxml)) return font, expected_value - @pytest.fixture(params=[ - ('w:r', True, - 'w:r/w:rPr/w:vertAlign{w:val=subscript}'), - ('w:r', False, - 'w:r/w:rPr'), - ('w:r', None, - 'w:r/w:rPr'), - ('w:r/w:rPr/w:vertAlign{w:val=subscript}', True, - 'w:r/w:rPr/w:vertAlign{w:val=subscript}'), - ('w:r/w:rPr/w:vertAlign{w:val=subscript}', False, - 'w:r/w:rPr'), - ('w:r/w:rPr/w:vertAlign{w:val=subscript}', None, - 'w:r/w:rPr'), - ('w:r/w:rPr/w:vertAlign{w:val=superscript}', True, - 'w:r/w:rPr/w:vertAlign{w:val=subscript}'), - ('w:r/w:rPr/w:vertAlign{w:val=superscript}', False, - 'w:r/w:rPr/w:vertAlign{w:val=superscript}'), - ('w:r/w:rPr/w:vertAlign{w:val=superscript}', None, - 'w:r/w:rPr'), - ('w:r/w:rPr/w:vertAlign{w:val=baseline}', True, - 'w:r/w:rPr/w:vertAlign{w:val=subscript}'), - ]) + @pytest.fixture( + params=[ + ("w:r", True, "w:r/w:rPr/w:vertAlign{w:val=subscript}"), + ("w:r", False, "w:r/w:rPr"), + ("w:r", None, "w:r/w:rPr"), + ( + "w:r/w:rPr/w:vertAlign{w:val=subscript}", + True, + "w:r/w:rPr/w:vertAlign{w:val=subscript}", + ), + ("w:r/w:rPr/w:vertAlign{w:val=subscript}", False, "w:r/w:rPr"), + ("w:r/w:rPr/w:vertAlign{w:val=subscript}", None, "w:r/w:rPr"), + ( + "w:r/w:rPr/w:vertAlign{w:val=superscript}", + True, + "w:r/w:rPr/w:vertAlign{w:val=subscript}", + ), + ( + "w:r/w:rPr/w:vertAlign{w:val=superscript}", + False, + "w:r/w:rPr/w:vertAlign{w:val=superscript}", + ), + ("w:r/w:rPr/w:vertAlign{w:val=superscript}", None, "w:r/w:rPr"), + ( + "w:r/w:rPr/w:vertAlign{w:val=baseline}", + True, + "w:r/w:rPr/w:vertAlign{w:val=subscript}", + ), + ] + ) def subscript_set_fixture(self, request): r_cxml, value, expected_r_cxml = request.param font = Font(element(r_cxml)) expected_xml = xml(expected_r_cxml) return font, value, expected_xml - @pytest.fixture(params=[ - ('w:r', None), - ('w:r/w:rPr', None), - ('w:r/w:rPr/w:vertAlign{w:val=baseline}', False), - ('w:r/w:rPr/w:vertAlign{w:val=subscript}', False), - ('w:r/w:rPr/w:vertAlign{w:val=superscript}', True), - ]) + @pytest.fixture( + params=[ + ("w:r", None), + ("w:r/w:rPr", None), + ("w:r/w:rPr/w:vertAlign{w:val=baseline}", False), + ("w:r/w:rPr/w:vertAlign{w:val=subscript}", False), + ("w:r/w:rPr/w:vertAlign{w:val=superscript}", True), + ] + ) def superscript_get_fixture(self, request): r_cxml, expected_value = request.param font = Font(element(r_cxml)) return font, expected_value - @pytest.fixture(params=[ - ('w:r', True, - 'w:r/w:rPr/w:vertAlign{w:val=superscript}'), - ('w:r', False, - 'w:r/w:rPr'), - ('w:r', None, - 'w:r/w:rPr'), - ('w:r/w:rPr/w:vertAlign{w:val=superscript}', True, - 'w:r/w:rPr/w:vertAlign{w:val=superscript}'), - ('w:r/w:rPr/w:vertAlign{w:val=superscript}', False, - 'w:r/w:rPr'), - ('w:r/w:rPr/w:vertAlign{w:val=superscript}', None, - 'w:r/w:rPr'), - ('w:r/w:rPr/w:vertAlign{w:val=subscript}', True, - 'w:r/w:rPr/w:vertAlign{w:val=superscript}'), - ('w:r/w:rPr/w:vertAlign{w:val=subscript}', False, - 'w:r/w:rPr/w:vertAlign{w:val=subscript}'), - ('w:r/w:rPr/w:vertAlign{w:val=subscript}', None, - 'w:r/w:rPr'), - ('w:r/w:rPr/w:vertAlign{w:val=baseline}', True, - 'w:r/w:rPr/w:vertAlign{w:val=superscript}'), - ]) + @pytest.fixture( + params=[ + ("w:r", True, "w:r/w:rPr/w:vertAlign{w:val=superscript}"), + ("w:r", False, "w:r/w:rPr"), + ("w:r", None, "w:r/w:rPr"), + ( + "w:r/w:rPr/w:vertAlign{w:val=superscript}", + True, + "w:r/w:rPr/w:vertAlign{w:val=superscript}", + ), + ("w:r/w:rPr/w:vertAlign{w:val=superscript}", False, "w:r/w:rPr"), + ("w:r/w:rPr/w:vertAlign{w:val=superscript}", None, "w:r/w:rPr"), + ( + "w:r/w:rPr/w:vertAlign{w:val=subscript}", + True, + "w:r/w:rPr/w:vertAlign{w:val=superscript}", + ), + ( + "w:r/w:rPr/w:vertAlign{w:val=subscript}", + False, + "w:r/w:rPr/w:vertAlign{w:val=subscript}", + ), + ("w:r/w:rPr/w:vertAlign{w:val=subscript}", None, "w:r/w:rPr"), + ( + "w:r/w:rPr/w:vertAlign{w:val=baseline}", + True, + "w:r/w:rPr/w:vertAlign{w:val=superscript}", + ), + ] + ) def superscript_set_fixture(self, request): r_cxml, value, expected_r_cxml = request.param font = Font(element(r_cxml)) expected_xml = xml(expected_r_cxml) return font, value, expected_xml - @pytest.fixture(params=[ - ('w:r', None), - ('w:r/w:rPr/w:u', None), - ('w:r/w:rPr/w:u{w:val=single}', True), - ('w:r/w:rPr/w:u{w:val=none}', False), - ('w:r/w:rPr/w:u{w:val=double}', WD_UNDERLINE.DOUBLE), - ('w:r/w:rPr/w:u{w:val=wave}', WD_UNDERLINE.WAVY), - ]) + @pytest.fixture( + params=[ + ("w:r", None), + ("w:r/w:rPr/w:u", None), + ("w:r/w:rPr/w:u{w:val=single}", True), + ("w:r/w:rPr/w:u{w:val=none}", False), + ("w:r/w:rPr/w:u{w:val=double}", WD_UNDERLINE.DOUBLE), + ("w:r/w:rPr/w:u{w:val=wave}", WD_UNDERLINE.WAVY), + ] + ) def underline_get_fixture(self, request): r_cxml, expected_value = request.param run = Font(element(r_cxml), None) return run, expected_value - @pytest.fixture(params=[ - ('w:r', True, 'w:r/w:rPr/w:u{w:val=single}'), - ('w:r', False, 'w:r/w:rPr/w:u{w:val=none}'), - ('w:r', None, 'w:r/w:rPr'), - ('w:r', WD_UNDERLINE.SINGLE, 'w:r/w:rPr/w:u{w:val=single}'), - ('w:r', WD_UNDERLINE.THICK, 'w:r/w:rPr/w:u{w:val=thick}'), - ('w:r/w:rPr/w:u{w:val=single}', True, - 'w:r/w:rPr/w:u{w:val=single}'), - ('w:r/w:rPr/w:u{w:val=single}', False, - 'w:r/w:rPr/w:u{w:val=none}'), - ('w:r/w:rPr/w:u{w:val=single}', None, - 'w:r/w:rPr'), - ('w:r/w:rPr/w:u{w:val=single}', WD_UNDERLINE.SINGLE, - 'w:r/w:rPr/w:u{w:val=single}'), - ('w:r/w:rPr/w:u{w:val=single}', WD_UNDERLINE.DOTTED, - 'w:r/w:rPr/w:u{w:val=dotted}'), - ]) + @pytest.fixture( + params=[ + ("w:r", True, "w:r/w:rPr/w:u{w:val=single}"), + ("w:r", False, "w:r/w:rPr/w:u{w:val=none}"), + ("w:r", None, "w:r/w:rPr"), + ("w:r", WD_UNDERLINE.SINGLE, "w:r/w:rPr/w:u{w:val=single}"), + ("w:r", WD_UNDERLINE.THICK, "w:r/w:rPr/w:u{w:val=thick}"), + ("w:r/w:rPr/w:u{w:val=single}", True, "w:r/w:rPr/w:u{w:val=single}"), + ("w:r/w:rPr/w:u{w:val=single}", False, "w:r/w:rPr/w:u{w:val=none}"), + ("w:r/w:rPr/w:u{w:val=single}", None, "w:r/w:rPr"), + ( + "w:r/w:rPr/w:u{w:val=single}", + WD_UNDERLINE.SINGLE, + "w:r/w:rPr/w:u{w:val=single}", + ), + ( + "w:r/w:rPr/w:u{w:val=single}", + WD_UNDERLINE.DOTTED, + "w:r/w:rPr/w:u{w:val=dotted}", + ), + ] + ) def underline_set_fixture(self, request): initial_r_cxml, value, expected_cxml = request.param run = Font(element(initial_r_cxml), None) @@ -387,6 +438,4 @@ def color_(self, request): @pytest.fixture def ColorFormat_(self, request, color_): - return class_mock( - request, 'docx.text.font.ColorFormat', return_value=color_ - ) + return class_mock(request, "docx.text.font.ColorFormat", return_value=color_) diff --git a/tests/text/test_paragraph.py b/tests/text/test_paragraph.py index b8313e61..e394334e 100644 --- a/tests/text/test_paragraph.py +++ b/tests/text/test_paragraph.py @@ -16,13 +16,10 @@ import pytest from ..unitutil.cxml import element, xml -from ..unitutil.mock import ( - call, class_mock, instance_mock, method_mock, property_mock -) +from ..unitutil.mock import call, class_mock, instance_mock, method_mock, property_mock class DescribeParagraph(object): - def it_knows_its_paragraph_style(self, style_get_fixture): paragraph, style_id_, style_ = style_get_fixture style = paragraph.style @@ -68,9 +65,7 @@ def it_provides_access_to_its_paragraph_format(self, parfmt_fixture): def it_provides_access_to_the_runs_it_contains(self, runs_fixture): paragraph, Run_, r_, r_2_, run_, run_2_ = runs_fixture runs = paragraph.runs - assert Run_.mock_calls == [ - call(r_, paragraph), call(r_2_, paragraph) - ] + assert Run_.mock_calls == [call(r_, paragraph), call(r_2_, paragraph)] assert runs == [run_, run_2_] def it_can_add_a_run_to_itself(self, add_run_fixture): @@ -93,8 +88,7 @@ def it_can_insert_a_paragraph_before_itself(self, insert_before_fixture): assert new_paragraph.style == style assert new_paragraph is paragraph_ - def it_can_remove_its_content_while_preserving_formatting( - self, clear_fixture): + def it_can_remove_its_content_while_preserving_formatting(self, clear_fixture): paragraph, expected_xml = clear_fixture _paragraph = paragraph.clear() assert paragraph._p.xml == expected_xml @@ -108,60 +102,71 @@ def it_inserts_a_paragraph_before_to_help(self, _insert_before_fixture): # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - ('w:p', None, None, 'w:p/w:r'), - ('w:p', 'foobar', None, 'w:p/w:r/w:t"foobar"'), - ('w:p', None, 'Strong', 'w:p/w:r'), - ('w:p', 'foobar', 'Strong', 'w:p/w:r/w:t"foobar"'), - ]) + @pytest.fixture( + params=[ + ("w:p", None, None, "w:p/w:r"), + ("w:p", "foobar", None, 'w:p/w:r/w:t"foobar"'), + ("w:p", None, "Strong", "w:p/w:r"), + ("w:p", "foobar", "Strong", 'w:p/w:r/w:t"foobar"'), + ] + ) def add_run_fixture(self, request, run_style_prop_): before_cxml, text, style, after_cxml = request.param paragraph = Paragraph(element(before_cxml), None) expected_xml = xml(after_cxml) return paragraph, text, style, run_style_prop_, expected_xml - @pytest.fixture(params=[ - ('w:p/w:pPr/w:jc{w:val=center}', WD_ALIGN_PARAGRAPH.CENTER), - ('w:p', None), - ]) + @pytest.fixture( + params=[ + ("w:p/w:pPr/w:jc{w:val=center}", WD_ALIGN_PARAGRAPH.CENTER), + ("w:p", None), + ] + ) def alignment_get_fixture(self, request): cxml, expected_alignment_value = request.param paragraph = Paragraph(element(cxml), None) return paragraph, expected_alignment_value - @pytest.fixture(params=[ - ('w:p', WD_ALIGN_PARAGRAPH.LEFT, - 'w:p/w:pPr/w:jc{w:val=left}'), - ('w:p/w:pPr/w:jc{w:val=left}', WD_ALIGN_PARAGRAPH.CENTER, - 'w:p/w:pPr/w:jc{w:val=center}'), - ('w:p/w:pPr/w:jc{w:val=left}', None, - 'w:p/w:pPr'), - ('w:p', None, 'w:p/w:pPr'), - ]) + @pytest.fixture( + params=[ + ("w:p", WD_ALIGN_PARAGRAPH.LEFT, "w:p/w:pPr/w:jc{w:val=left}"), + ( + "w:p/w:pPr/w:jc{w:val=left}", + WD_ALIGN_PARAGRAPH.CENTER, + "w:p/w:pPr/w:jc{w:val=center}", + ), + ("w:p/w:pPr/w:jc{w:val=left}", None, "w:p/w:pPr"), + ("w:p", None, "w:p/w:pPr"), + ] + ) def alignment_set_fixture(self, request): initial_cxml, new_alignment_value, expected_cxml = request.param paragraph = Paragraph(element(initial_cxml), None) expected_xml = xml(expected_cxml) return paragraph, new_alignment_value, expected_xml - @pytest.fixture(params=[ - ('w:p', 'w:p'), - ('w:p/w:pPr', 'w:p/w:pPr'), - ('w:p/w:r/w:t"foobar"', 'w:p'), - ('w:p/(w:pPr, w:r/w:t"foobar")', 'w:p/w:pPr'), - ]) + @pytest.fixture( + params=[ + ("w:p", "w:p"), + ("w:p/w:pPr", "w:p/w:pPr"), + ('w:p/w:r/w:t"foobar"', "w:p"), + ('w:p/(w:pPr, w:r/w:t"foobar")', "w:p/w:pPr"), + ] + ) def clear_fixture(self, request): initial_cxml, expected_cxml = request.param paragraph = Paragraph(element(initial_cxml), None) expected_xml = xml(expected_cxml) return paragraph, expected_xml - @pytest.fixture(params=[ - (None, None), - ('Foo', None), - (None, 'Bar'), - ('Foo', 'Bar'), - ]) + @pytest.fixture( + params=[ + (None, None), + ("Foo", None), + (None, "Bar"), + ("Foo", "Bar"), + ] + ) def insert_before_fixture(self, request, _insert_paragraph_before_, add_run_): text, style = request.param paragraph_ = _insert_paragraph_before_.return_value @@ -169,9 +174,7 @@ def insert_before_fixture(self, request, _insert_paragraph_before_, add_run_): paragraph_.style = None return text, style, paragraph_, add_run_calls - @pytest.fixture(params=[ - ('w:body/w:p{id=42}', 'w:body/(w:p,w:p{id=42})') - ]) + @pytest.fixture(params=[("w:body/w:p{id=42}", "w:body/(w:p,w:p{id=42})")]) def _insert_before_fixture(self, request): body_cxml, expected_cxml = request.param body = element(body_cxml) @@ -181,7 +184,7 @@ def _insert_before_fixture(self, request): @pytest.fixture def parfmt_fixture(self, ParagraphFormat_, paragraph_format_): - paragraph = Paragraph(element('w:p'), None) + paragraph = Paragraph(element("w:p"), None) return paragraph, ParagraphFormat_, paragraph_format_ @pytest.fixture @@ -192,24 +195,31 @@ def runs_fixture(self, p_, Run_, r_, r_2_, runs_): @pytest.fixture def style_get_fixture(self, part_prop_): - style_id = 'Foobar' - p_cxml = 'w:p/w:pPr/w:pStyle{w:val=%s}' % style_id + style_id = "Foobar" + p_cxml = "w:p/w:pPr/w:pStyle{w:val=%s}" % style_id paragraph = Paragraph(element(p_cxml), None) style_ = part_prop_.return_value.get_style.return_value return paragraph, style_id, style_ - @pytest.fixture(params=[ - ('w:p', 'Heading 1', 'Heading1', - 'w:p/w:pPr/w:pStyle{w:val=Heading1}'), - ('w:p/w:pPr', 'Heading 1', 'Heading1', - 'w:p/w:pPr/w:pStyle{w:val=Heading1}'), - ('w:p/w:pPr/w:pStyle{w:val=Heading1}', 'Heading 2', 'Heading2', - 'w:p/w:pPr/w:pStyle{w:val=Heading2}'), - ('w:p/w:pPr/w:pStyle{w:val=Heading1}', 'Normal', None, - 'w:p/w:pPr'), - ('w:p', None, None, - 'w:p/w:pPr'), - ]) + @pytest.fixture( + params=[ + ("w:p", "Heading 1", "Heading1", "w:p/w:pPr/w:pStyle{w:val=Heading1}"), + ( + "w:p/w:pPr", + "Heading 1", + "Heading1", + "w:p/w:pPr/w:pStyle{w:val=Heading1}", + ), + ( + "w:p/w:pPr/w:pStyle{w:val=Heading1}", + "Heading 2", + "Heading2", + "w:p/w:pPr/w:pStyle{w:val=Heading2}", + ), + ("w:p/w:pPr/w:pStyle{w:val=Heading1}", "Normal", None, "w:p/w:pPr"), + ("w:p", None, None, "w:p/w:pPr"), + ] + ) def style_set_fixture(self, request, part_prop_): p_cxml, value, style_id, expected_cxml = request.param paragraph = Paragraph(element(p_cxml), None) @@ -217,17 +227,19 @@ def style_set_fixture(self, request, part_prop_): expected_xml = xml(expected_cxml) return paragraph, value, expected_xml - @pytest.fixture(params=[ - ('w:p', ''), - ('w:p/w:r', ''), - ('w:p/w:r/w:t', ''), - ('w:p/w:r/w:t"foo"', 'foo'), - ('w:p/w:r/(w:t"foo", w:t"bar")', 'foobar'), - ('w:p/w:r/(w:t"fo ", w:t"bar")', 'fo bar'), - ('w:p/w:r/(w:t"foo", w:tab, w:t"bar")', 'foo\tbar'), - ('w:p/w:r/(w:t"foo", w:br, w:t"bar")', 'foo\nbar'), - ('w:p/w:r/(w:t"foo", w:cr, w:t"bar")', 'foo\nbar'), - ]) + @pytest.fixture( + params=[ + ("w:p", ""), + ("w:p/w:r", ""), + ("w:p/w:r/w:t", ""), + ('w:p/w:r/w:t"foo"', "foo"), + ('w:p/w:r/(w:t"foo", w:t"bar")', "foobar"), + ('w:p/w:r/(w:t"fo ", w:t"bar")', "fo bar"), + ('w:p/w:r/(w:t"foo", w:tab, w:t"bar")', "foo\tbar"), + ('w:p/w:r/(w:t"foo", w:br, w:t"bar")', "foo\nbar"), + ('w:p/w:r/(w:t"foo", w:cr, w:t"bar")', "foo\nbar"), + ] + ) def text_get_fixture(self, request): p_cxml, expected_text_value = request.param paragraph = Paragraph(element(p_cxml), None) @@ -235,17 +247,17 @@ def text_get_fixture(self, request): @pytest.fixture def text_set_fixture(self): - paragraph = Paragraph(element('w:p'), None) - paragraph.add_run('must not appear in result') - new_text_value = 'foo\tbar\rbaz\n' - expected_text_value = 'foo\tbar\nbaz\n' + paragraph = Paragraph(element("w:p"), None) + paragraph.add_run("must not appear in result") + new_text_value = "foo\tbar\rbaz\n" + expected_text_value = "foo\tbar\nbaz\n" return paragraph, new_text_value, expected_text_value # fixture components --------------------------------------------- @pytest.fixture def add_run_(self, request): - return method_mock(request, Paragraph, 'add_run') + return method_mock(request, Paragraph, "add_run") @pytest.fixture def document_part_(self, request): @@ -253,7 +265,7 @@ def document_part_(self, request): @pytest.fixture def _insert_paragraph_before_(self, request): - return method_mock(request, Paragraph, '_insert_paragraph_before') + return method_mock(request, Paragraph, "_insert_paragraph_before") @pytest.fixture def p_(self, request, r_, r_2_): @@ -262,8 +274,9 @@ def p_(self, request, r_, r_2_): @pytest.fixture def ParagraphFormat_(self, request, paragraph_format_): return class_mock( - request, 'docx.text.paragraph.ParagraphFormat', - return_value=paragraph_format_ + request, + "docx.text.paragraph.ParagraphFormat", + return_value=paragraph_format_, ) @pytest.fixture @@ -272,15 +285,13 @@ def paragraph_format_(self, request): @pytest.fixture def part_prop_(self, request, document_part_): - return property_mock( - request, Paragraph, 'part', return_value=document_part_ - ) + return property_mock(request, Paragraph, "part", return_value=document_part_) @pytest.fixture def Run_(self, request, runs_): run_, run_2_ = runs_ return class_mock( - request, 'docx.text.paragraph.Run', side_effect=[run_, run_2_] + request, "docx.text.paragraph.Run", side_effect=[run_, run_2_] ) @pytest.fixture @@ -293,10 +304,10 @@ def r_2_(self, request): @pytest.fixture def run_style_prop_(self, request): - return property_mock(request, Run, 'style') + return property_mock(request, Run, "style") @pytest.fixture def runs_(self, request): - run_ = instance_mock(request, Run, name='run_') - run_2_ = instance_mock(request, Run, name='run_2_') + run_ = instance_mock(request, Run, name="run_") + run_2_ = instance_mock(request, Run, name="run_2_") return run_, run_2_ diff --git a/tests/text/test_parfmt.py b/tests/text/test_parfmt.py index 9e7bb4d5..ce992779 100644 --- a/tests/text/test_parfmt.py +++ b/tests/text/test_parfmt.py @@ -5,9 +5,7 @@ object. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_LINE_SPACING from docx.shared import Pt @@ -21,7 +19,6 @@ class DescribeParagraphFormat(object): - def it_knows_its_alignment_value(self, alignment_get_fixture): paragraph_format, expected_value = alignment_get_fixture assert paragraph_format.alignment == expected_value @@ -62,8 +59,7 @@ def it_knows_its_line_spacing_rule(self, line_spacing_rule_get_fixture): paragraph_format, expected_value = line_spacing_rule_get_fixture assert paragraph_format.line_spacing_rule == expected_value - def it_can_change_its_line_spacing_rule(self, - line_spacing_rule_set_fixture): + def it_can_change_its_line_spacing_rule(self, line_spacing_rule_set_fixture): paragraph_format, value, expected_xml = line_spacing_rule_set_fixture paragraph_format.line_spacing_rule = value assert paragraph_format._element.xml == expected_xml @@ -112,290 +108,367 @@ def it_provides_access_to_its_tab_stops(self, tab_stops_fixture): # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - ('w:p', None), - ('w:p/w:pPr', None), - ('w:p/w:pPr/w:jc{w:val=center}', WD_ALIGN_PARAGRAPH.CENTER), - ]) + @pytest.fixture( + params=[ + ("w:p", None), + ("w:p/w:pPr", None), + ("w:p/w:pPr/w:jc{w:val=center}", WD_ALIGN_PARAGRAPH.CENTER), + ] + ) def alignment_get_fixture(self, request): p_cxml, expected_value = request.param paragraph_format = ParagraphFormat(element(p_cxml)) return paragraph_format, expected_value - @pytest.fixture(params=[ - ('w:p', WD_ALIGN_PARAGRAPH.LEFT, - 'w:p/w:pPr/w:jc{w:val=left}'), - ('w:p/w:pPr', WD_ALIGN_PARAGRAPH.CENTER, - 'w:p/w:pPr/w:jc{w:val=center}'), - ('w:p/w:pPr/w:jc{w:val=center}', WD_ALIGN_PARAGRAPH.RIGHT, - 'w:p/w:pPr/w:jc{w:val=right}'), - ('w:p/w:pPr/w:jc{w:val=right}', None, - 'w:p/w:pPr'), - ('w:p', None, - 'w:p/w:pPr'), - ]) + @pytest.fixture( + params=[ + ("w:p", WD_ALIGN_PARAGRAPH.LEFT, "w:p/w:pPr/w:jc{w:val=left}"), + ("w:p/w:pPr", WD_ALIGN_PARAGRAPH.CENTER, "w:p/w:pPr/w:jc{w:val=center}"), + ( + "w:p/w:pPr/w:jc{w:val=center}", + WD_ALIGN_PARAGRAPH.RIGHT, + "w:p/w:pPr/w:jc{w:val=right}", + ), + ("w:p/w:pPr/w:jc{w:val=right}", None, "w:p/w:pPr"), + ("w:p", None, "w:p/w:pPr"), + ] + ) def alignment_set_fixture(self, request): p_cxml, value, expected_cxml = request.param paragraph_format = ParagraphFormat(element(p_cxml)) expected_xml = xml(expected_cxml) return paragraph_format, value, expected_xml - @pytest.fixture(params=[ - ('w:p', None), - ('w:p/w:pPr', None), - ('w:p/w:pPr/w:ind', None), - ('w:p/w:pPr/w:ind{w:firstLine=240}', Pt(12)), - ('w:p/w:pPr/w:ind{w:hanging=240}', Pt(-12)), - ]) + @pytest.fixture( + params=[ + ("w:p", None), + ("w:p/w:pPr", None), + ("w:p/w:pPr/w:ind", None), + ("w:p/w:pPr/w:ind{w:firstLine=240}", Pt(12)), + ("w:p/w:pPr/w:ind{w:hanging=240}", Pt(-12)), + ] + ) def first_indent_get_fixture(self, request): p_cxml, expected_value = request.param paragraph_format = ParagraphFormat(element(p_cxml)) return paragraph_format, expected_value - @pytest.fixture(params=[ - ('w:p', Pt(36), 'w:p/w:pPr/w:ind{w:firstLine=720}'), - ('w:p', Pt(-36), 'w:p/w:pPr/w:ind{w:hanging=720}'), - ('w:p', 0, 'w:p/w:pPr/w:ind{w:firstLine=0}'), - ('w:p', None, 'w:p/w:pPr'), - ('w:p/w:pPr/w:ind{w:firstLine=240}', None, - 'w:p/w:pPr/w:ind'), - ('w:p/w:pPr/w:ind{w:firstLine=240}', Pt(-18), - 'w:p/w:pPr/w:ind{w:hanging=360}'), - ('w:p/w:pPr/w:ind{w:hanging=240}', Pt(18), - 'w:p/w:pPr/w:ind{w:firstLine=360}'), - ]) + @pytest.fixture( + params=[ + ("w:p", Pt(36), "w:p/w:pPr/w:ind{w:firstLine=720}"), + ("w:p", Pt(-36), "w:p/w:pPr/w:ind{w:hanging=720}"), + ("w:p", 0, "w:p/w:pPr/w:ind{w:firstLine=0}"), + ("w:p", None, "w:p/w:pPr"), + ("w:p/w:pPr/w:ind{w:firstLine=240}", None, "w:p/w:pPr/w:ind"), + ( + "w:p/w:pPr/w:ind{w:firstLine=240}", + Pt(-18), + "w:p/w:pPr/w:ind{w:hanging=360}", + ), + ( + "w:p/w:pPr/w:ind{w:hanging=240}", + Pt(18), + "w:p/w:pPr/w:ind{w:firstLine=360}", + ), + ] + ) def first_indent_set_fixture(self, request): p_cxml, value, expected_p_cxml = request.param paragraph_format = ParagraphFormat(element(p_cxml)) expected_xml = xml(expected_p_cxml) return paragraph_format, value, expected_xml - @pytest.fixture(params=[ - ('w:p', None), - ('w:p/w:pPr', None), - ('w:p/w:pPr/w:ind', None), - ('w:p/w:pPr/w:ind{w:left=120}', Pt(6)), - ('w:p/w:pPr/w:ind{w:left=-06.3pt}', Pt(-6.3)), - ]) + @pytest.fixture( + params=[ + ("w:p", None), + ("w:p/w:pPr", None), + ("w:p/w:pPr/w:ind", None), + ("w:p/w:pPr/w:ind{w:left=120}", Pt(6)), + ("w:p/w:pPr/w:ind{w:left=-06.3pt}", Pt(-6.3)), + ] + ) def left_indent_get_fixture(self, request): p_cxml, expected_value = request.param paragraph_format = ParagraphFormat(element(p_cxml)) return paragraph_format, expected_value - @pytest.fixture(params=[ - ('w:p', Pt(36), 'w:p/w:pPr/w:ind{w:left=720}'), - ('w:p', Pt(-3), 'w:p/w:pPr/w:ind{w:left=-60}'), - ('w:p', 0, 'w:p/w:pPr/w:ind{w:left=0}'), - ('w:p', None, 'w:p/w:pPr'), - ('w:p/w:pPr/w:ind{w:left=240}', None, 'w:p/w:pPr/w:ind'), - ]) + @pytest.fixture( + params=[ + ("w:p", Pt(36), "w:p/w:pPr/w:ind{w:left=720}"), + ("w:p", Pt(-3), "w:p/w:pPr/w:ind{w:left=-60}"), + ("w:p", 0, "w:p/w:pPr/w:ind{w:left=0}"), + ("w:p", None, "w:p/w:pPr"), + ("w:p/w:pPr/w:ind{w:left=240}", None, "w:p/w:pPr/w:ind"), + ] + ) def left_indent_set_fixture(self, request): p_cxml, value, expected_p_cxml = request.param paragraph_format = ParagraphFormat(element(p_cxml)) expected_xml = xml(expected_p_cxml) return paragraph_format, value, expected_xml - @pytest.fixture(params=[ - ('w:p', None), - ('w:p/w:pPr', None), - ('w:p/w:pPr/w:spacing', None), - ('w:p/w:pPr/w:spacing{w:line=420}', 1.75), - ('w:p/w:pPr/w:spacing{w:line=840,w:lineRule=exact}', Pt(42)), - ('w:p/w:pPr/w:spacing{w:line=840,w:lineRule=atLeast}', Pt(42)), - ]) + @pytest.fixture( + params=[ + ("w:p", None), + ("w:p/w:pPr", None), + ("w:p/w:pPr/w:spacing", None), + ("w:p/w:pPr/w:spacing{w:line=420}", 1.75), + ("w:p/w:pPr/w:spacing{w:line=840,w:lineRule=exact}", Pt(42)), + ("w:p/w:pPr/w:spacing{w:line=840,w:lineRule=atLeast}", Pt(42)), + ] + ) def line_spacing_get_fixture(self, request): p_cxml, expected_value = request.param paragraph_format = ParagraphFormat(element(p_cxml)) return paragraph_format, expected_value - @pytest.fixture(params=[ - ('w:p', 1, 'w:p/w:pPr/w:spacing{w:line=240,w:lineRule=auto}'), - ('w:p', 2.0, 'w:p/w:pPr/w:spacing{w:line=480,w:lineRule=auto}'), - ('w:p', Pt(42), 'w:p/w:pPr/w:spacing{w:line=840,w:lineRule=exact}'), - ('w:p/w:pPr', 2, - 'w:p/w:pPr/w:spacing{w:line=480,w:lineRule=auto}'), - ('w:p/w:pPr/w:spacing{w:line=360}', 1, - 'w:p/w:pPr/w:spacing{w:line=240,w:lineRule=auto}'), - ('w:p/w:pPr/w:spacing{w:line=240,w:lineRule=exact}', 1.75, - 'w:p/w:pPr/w:spacing{w:line=420,w:lineRule=auto}'), - ('w:p/w:pPr/w:spacing{w:line=240,w:lineRule=atLeast}', Pt(42), - 'w:p/w:pPr/w:spacing{w:line=840,w:lineRule=atLeast}'), - ('w:p/w:pPr/w:spacing{w:line=240,w:lineRule=exact}', None, - 'w:p/w:pPr/w:spacing'), - ('w:p/w:pPr', None, - 'w:p/w:pPr'), - ]) + @pytest.fixture( + params=[ + ("w:p", 1, "w:p/w:pPr/w:spacing{w:line=240,w:lineRule=auto}"), + ("w:p", 2.0, "w:p/w:pPr/w:spacing{w:line=480,w:lineRule=auto}"), + ("w:p", Pt(42), "w:p/w:pPr/w:spacing{w:line=840,w:lineRule=exact}"), + ("w:p/w:pPr", 2, "w:p/w:pPr/w:spacing{w:line=480,w:lineRule=auto}"), + ( + "w:p/w:pPr/w:spacing{w:line=360}", + 1, + "w:p/w:pPr/w:spacing{w:line=240,w:lineRule=auto}", + ), + ( + "w:p/w:pPr/w:spacing{w:line=240,w:lineRule=exact}", + 1.75, + "w:p/w:pPr/w:spacing{w:line=420,w:lineRule=auto}", + ), + ( + "w:p/w:pPr/w:spacing{w:line=240,w:lineRule=atLeast}", + Pt(42), + "w:p/w:pPr/w:spacing{w:line=840,w:lineRule=atLeast}", + ), + ( + "w:p/w:pPr/w:spacing{w:line=240,w:lineRule=exact}", + None, + "w:p/w:pPr/w:spacing", + ), + ("w:p/w:pPr", None, "w:p/w:pPr"), + ] + ) def line_spacing_set_fixture(self, request): p_cxml, value, expected_p_cxml = request.param paragraph_format = ParagraphFormat(element(p_cxml)) expected_xml = xml(expected_p_cxml) return paragraph_format, value, expected_xml - @pytest.fixture(params=[ - ('w:p', None), - ('w:p/w:pPr', None), - ('w:p/w:pPr/w:spacing', None), - ('w:p/w:pPr/w:spacing{w:line=240}', WD_LINE_SPACING.SINGLE), - ('w:p/w:pPr/w:spacing{w:line=360}', WD_LINE_SPACING.ONE_POINT_FIVE), - ('w:p/w:pPr/w:spacing{w:line=480}', WD_LINE_SPACING.DOUBLE), - ('w:p/w:pPr/w:spacing{w:line=420}', WD_LINE_SPACING.MULTIPLE), - ('w:p/w:pPr/w:spacing{w:lineRule=auto}', - WD_LINE_SPACING.MULTIPLE), - ('w:p/w:pPr/w:spacing{w:lineRule=exact}', - WD_LINE_SPACING.EXACTLY), - ('w:p/w:pPr/w:spacing{w:lineRule=atLeast}', - WD_LINE_SPACING.AT_LEAST), - ]) + @pytest.fixture( + params=[ + ("w:p", None), + ("w:p/w:pPr", None), + ("w:p/w:pPr/w:spacing", None), + ("w:p/w:pPr/w:spacing{w:line=240}", WD_LINE_SPACING.SINGLE), + ("w:p/w:pPr/w:spacing{w:line=360}", WD_LINE_SPACING.ONE_POINT_FIVE), + ("w:p/w:pPr/w:spacing{w:line=480}", WD_LINE_SPACING.DOUBLE), + ("w:p/w:pPr/w:spacing{w:line=420}", WD_LINE_SPACING.MULTIPLE), + ("w:p/w:pPr/w:spacing{w:lineRule=auto}", WD_LINE_SPACING.MULTIPLE), + ("w:p/w:pPr/w:spacing{w:lineRule=exact}", WD_LINE_SPACING.EXACTLY), + ("w:p/w:pPr/w:spacing{w:lineRule=atLeast}", WD_LINE_SPACING.AT_LEAST), + ] + ) def line_spacing_rule_get_fixture(self, request): p_cxml, expected_value = request.param paragraph_format = ParagraphFormat(element(p_cxml)) return paragraph_format, expected_value - @pytest.fixture(params=[ - ('w:p', WD_LINE_SPACING.SINGLE, - 'w:p/w:pPr/w:spacing{w:line=240,w:lineRule=auto}'), - ('w:p', WD_LINE_SPACING.ONE_POINT_FIVE, - 'w:p/w:pPr/w:spacing{w:line=360,w:lineRule=auto}'), - ('w:p', WD_LINE_SPACING.DOUBLE, - 'w:p/w:pPr/w:spacing{w:line=480,w:lineRule=auto}'), - ('w:p', WD_LINE_SPACING.MULTIPLE, - 'w:p/w:pPr/w:spacing{w:lineRule=auto}'), - ('w:p', WD_LINE_SPACING.EXACTLY, - 'w:p/w:pPr/w:spacing{w:lineRule=exact}'), - ('w:p/w:pPr/w:spacing{w:line=280,w:lineRule=exact}', - WD_LINE_SPACING.AT_LEAST, - 'w:p/w:pPr/w:spacing{w:line=280,w:lineRule=atLeast}'), - ]) + @pytest.fixture( + params=[ + ( + "w:p", + WD_LINE_SPACING.SINGLE, + "w:p/w:pPr/w:spacing{w:line=240,w:lineRule=auto}", + ), + ( + "w:p", + WD_LINE_SPACING.ONE_POINT_FIVE, + "w:p/w:pPr/w:spacing{w:line=360,w:lineRule=auto}", + ), + ( + "w:p", + WD_LINE_SPACING.DOUBLE, + "w:p/w:pPr/w:spacing{w:line=480,w:lineRule=auto}", + ), + ("w:p", WD_LINE_SPACING.MULTIPLE, "w:p/w:pPr/w:spacing{w:lineRule=auto}"), + ("w:p", WD_LINE_SPACING.EXACTLY, "w:p/w:pPr/w:spacing{w:lineRule=exact}"), + ( + "w:p/w:pPr/w:spacing{w:line=280,w:lineRule=exact}", + WD_LINE_SPACING.AT_LEAST, + "w:p/w:pPr/w:spacing{w:line=280,w:lineRule=atLeast}", + ), + ] + ) def line_spacing_rule_set_fixture(self, request): p_cxml, value, expected_p_cxml = request.param paragraph_format = ParagraphFormat(element(p_cxml)) expected_xml = xml(expected_p_cxml) return paragraph_format, value, expected_xml - @pytest.fixture(params=[ - ('w:p', 'keep_together', None), - ('w:p/w:pPr/w:keepLines{w:val=on}', 'keep_together', True), - ('w:p/w:pPr/w:keepLines{w:val=0}', 'keep_together', False), - ('w:p', 'keep_with_next', None), - ('w:p/w:pPr/w:keepNext{w:val=1}', 'keep_with_next', True), - ('w:p/w:pPr/w:keepNext{w:val=false}', 'keep_with_next', False), - ('w:p', 'page_break_before', None), - ('w:p/w:pPr/w:pageBreakBefore', 'page_break_before', True), - ('w:p/w:pPr/w:pageBreakBefore{w:val=0}', 'page_break_before', False), - ('w:p', 'widow_control', None), - ('w:p/w:pPr/w:widowControl{w:val=true}', 'widow_control', True), - ('w:p/w:pPr/w:widowControl{w:val=off}', 'widow_control', False), - ]) + @pytest.fixture( + params=[ + ("w:p", "keep_together", None), + ("w:p/w:pPr/w:keepLines{w:val=on}", "keep_together", True), + ("w:p/w:pPr/w:keepLines{w:val=0}", "keep_together", False), + ("w:p", "keep_with_next", None), + ("w:p/w:pPr/w:keepNext{w:val=1}", "keep_with_next", True), + ("w:p/w:pPr/w:keepNext{w:val=false}", "keep_with_next", False), + ("w:p", "page_break_before", None), + ("w:p/w:pPr/w:pageBreakBefore", "page_break_before", True), + ("w:p/w:pPr/w:pageBreakBefore{w:val=0}", "page_break_before", False), + ("w:p", "widow_control", None), + ("w:p/w:pPr/w:widowControl{w:val=true}", "widow_control", True), + ("w:p/w:pPr/w:widowControl{w:val=off}", "widow_control", False), + ] + ) def on_off_get_fixture(self, request): p_cxml, prop_name, expected_value = request.param paragraph_format = ParagraphFormat(element(p_cxml)) return paragraph_format, prop_name, expected_value - @pytest.fixture(params=[ - ('w:p', 'keep_together', True, 'w:p/w:pPr/w:keepLines'), - ('w:p', 'keep_with_next', True, 'w:p/w:pPr/w:keepNext'), - ('w:p', 'page_break_before', True, 'w:p/w:pPr/w:pageBreakBefore'), - ('w:p', 'widow_control', True, 'w:p/w:pPr/w:widowControl'), - ('w:p/w:pPr/w:keepLines', 'keep_together', False, - 'w:p/w:pPr/w:keepLines{w:val=0}'), - ('w:p/w:pPr/w:keepNext', 'keep_with_next', False, - 'w:p/w:pPr/w:keepNext{w:val=0}'), - ('w:p/w:pPr/w:pageBreakBefore', 'page_break_before', False, - 'w:p/w:pPr/w:pageBreakBefore{w:val=0}'), - ('w:p/w:pPr/w:widowControl', 'widow_control', False, - 'w:p/w:pPr/w:widowControl{w:val=0}'), - ('w:p/w:pPr/w:keepLines{w:val=0}', 'keep_together', None, - 'w:p/w:pPr'), - ('w:p/w:pPr/w:keepNext{w:val=0}', 'keep_with_next', None, - 'w:p/w:pPr'), - ('w:p/w:pPr/w:pageBreakBefore{w:val=0}', 'page_break_before', None, - 'w:p/w:pPr'), - ('w:p/w:pPr/w:widowControl{w:val=0}', 'widow_control', None, - 'w:p/w:pPr'), - ]) + @pytest.fixture( + params=[ + ("w:p", "keep_together", True, "w:p/w:pPr/w:keepLines"), + ("w:p", "keep_with_next", True, "w:p/w:pPr/w:keepNext"), + ("w:p", "page_break_before", True, "w:p/w:pPr/w:pageBreakBefore"), + ("w:p", "widow_control", True, "w:p/w:pPr/w:widowControl"), + ( + "w:p/w:pPr/w:keepLines", + "keep_together", + False, + "w:p/w:pPr/w:keepLines{w:val=0}", + ), + ( + "w:p/w:pPr/w:keepNext", + "keep_with_next", + False, + "w:p/w:pPr/w:keepNext{w:val=0}", + ), + ( + "w:p/w:pPr/w:pageBreakBefore", + "page_break_before", + False, + "w:p/w:pPr/w:pageBreakBefore{w:val=0}", + ), + ( + "w:p/w:pPr/w:widowControl", + "widow_control", + False, + "w:p/w:pPr/w:widowControl{w:val=0}", + ), + ("w:p/w:pPr/w:keepLines{w:val=0}", "keep_together", None, "w:p/w:pPr"), + ("w:p/w:pPr/w:keepNext{w:val=0}", "keep_with_next", None, "w:p/w:pPr"), + ( + "w:p/w:pPr/w:pageBreakBefore{w:val=0}", + "page_break_before", + None, + "w:p/w:pPr", + ), + ("w:p/w:pPr/w:widowControl{w:val=0}", "widow_control", None, "w:p/w:pPr"), + ] + ) def on_off_set_fixture(self, request): p_cxml, prop_name, value, expected_cxml = request.param paragraph_format = ParagraphFormat(element(p_cxml)) expected_xml = xml(expected_cxml) return paragraph_format, prop_name, value, expected_xml - @pytest.fixture(params=[ - ('w:p', None), - ('w:p/w:pPr', None), - ('w:p/w:pPr/w:ind', None), - ('w:p/w:pPr/w:ind{w:right=160}', Pt(8)), - ('w:p/w:pPr/w:ind{w:right=-4.2pt}', Pt(-4.2)), - ]) + @pytest.fixture( + params=[ + ("w:p", None), + ("w:p/w:pPr", None), + ("w:p/w:pPr/w:ind", None), + ("w:p/w:pPr/w:ind{w:right=160}", Pt(8)), + ("w:p/w:pPr/w:ind{w:right=-4.2pt}", Pt(-4.2)), + ] + ) def right_indent_get_fixture(self, request): p_cxml, expected_value = request.param paragraph_format = ParagraphFormat(element(p_cxml)) return paragraph_format, expected_value - @pytest.fixture(params=[ - ('w:p', Pt(36), 'w:p/w:pPr/w:ind{w:right=720}'), - ('w:p', Pt(-3), 'w:p/w:pPr/w:ind{w:right=-60}'), - ('w:p', 0, 'w:p/w:pPr/w:ind{w:right=0}'), - ('w:p', None, 'w:p/w:pPr'), - ('w:p/w:pPr/w:ind{w:right=240}', None, 'w:p/w:pPr/w:ind'), - ]) + @pytest.fixture( + params=[ + ("w:p", Pt(36), "w:p/w:pPr/w:ind{w:right=720}"), + ("w:p", Pt(-3), "w:p/w:pPr/w:ind{w:right=-60}"), + ("w:p", 0, "w:p/w:pPr/w:ind{w:right=0}"), + ("w:p", None, "w:p/w:pPr"), + ("w:p/w:pPr/w:ind{w:right=240}", None, "w:p/w:pPr/w:ind"), + ] + ) def right_indent_set_fixture(self, request): p_cxml, value, expected_p_cxml = request.param paragraph_format = ParagraphFormat(element(p_cxml)) expected_xml = xml(expected_p_cxml) return paragraph_format, value, expected_xml - @pytest.fixture(params=[ - ('w:p', None), - ('w:p/w:pPr', None), - ('w:p/w:pPr/w:spacing', None), - ('w:p/w:pPr/w:spacing{w:after=240}', Pt(12)), - ]) + @pytest.fixture( + params=[ + ("w:p", None), + ("w:p/w:pPr", None), + ("w:p/w:pPr/w:spacing", None), + ("w:p/w:pPr/w:spacing{w:after=240}", Pt(12)), + ] + ) def space_after_get_fixture(self, request): p_cxml, expected_value = request.param paragraph_format = ParagraphFormat(element(p_cxml)) return paragraph_format, expected_value - @pytest.fixture(params=[ - ('w:p', Pt(12), 'w:p/w:pPr/w:spacing{w:after=240}'), - ('w:p', None, 'w:p/w:pPr'), - ('w:p/w:pPr', Pt(12), 'w:p/w:pPr/w:spacing{w:after=240}'), - ('w:p/w:pPr', None, 'w:p/w:pPr'), - ('w:p/w:pPr/w:spacing', Pt(12), 'w:p/w:pPr/w:spacing{w:after=240}'), - ('w:p/w:pPr/w:spacing', None, 'w:p/w:pPr/w:spacing'), - ('w:p/w:pPr/w:spacing{w:after=240}', Pt(42), - 'w:p/w:pPr/w:spacing{w:after=840}'), - ('w:p/w:pPr/w:spacing{w:after=840}', None, - 'w:p/w:pPr/w:spacing'), - ]) + @pytest.fixture( + params=[ + ("w:p", Pt(12), "w:p/w:pPr/w:spacing{w:after=240}"), + ("w:p", None, "w:p/w:pPr"), + ("w:p/w:pPr", Pt(12), "w:p/w:pPr/w:spacing{w:after=240}"), + ("w:p/w:pPr", None, "w:p/w:pPr"), + ("w:p/w:pPr/w:spacing", Pt(12), "w:p/w:pPr/w:spacing{w:after=240}"), + ("w:p/w:pPr/w:spacing", None, "w:p/w:pPr/w:spacing"), + ( + "w:p/w:pPr/w:spacing{w:after=240}", + Pt(42), + "w:p/w:pPr/w:spacing{w:after=840}", + ), + ("w:p/w:pPr/w:spacing{w:after=840}", None, "w:p/w:pPr/w:spacing"), + ] + ) def space_after_set_fixture(self, request): p_cxml, value, expected_p_cxml = request.param paragraph_format = ParagraphFormat(element(p_cxml)) expected_xml = xml(expected_p_cxml) return paragraph_format, value, expected_xml - @pytest.fixture(params=[ - ('w:p', None), - ('w:p/w:pPr', None), - ('w:p/w:pPr/w:spacing', None), - ('w:p/w:pPr/w:spacing{w:before=420}', Pt(21)), - ]) + @pytest.fixture( + params=[ + ("w:p", None), + ("w:p/w:pPr", None), + ("w:p/w:pPr/w:spacing", None), + ("w:p/w:pPr/w:spacing{w:before=420}", Pt(21)), + ] + ) def space_before_get_fixture(self, request): p_cxml, expected_value = request.param paragraph_format = ParagraphFormat(element(p_cxml)) return paragraph_format, expected_value - @pytest.fixture(params=[ - ('w:p', Pt(12), 'w:p/w:pPr/w:spacing{w:before=240}'), - ('w:p', None, 'w:p/w:pPr'), - ('w:p/w:pPr', Pt(12), 'w:p/w:pPr/w:spacing{w:before=240}'), - ('w:p/w:pPr', None, 'w:p/w:pPr'), - ('w:p/w:pPr/w:spacing', Pt(12), 'w:p/w:pPr/w:spacing{w:before=240}'), - ('w:p/w:pPr/w:spacing', None, 'w:p/w:pPr/w:spacing'), - ('w:p/w:pPr/w:spacing{w:before=240}', Pt(42), - 'w:p/w:pPr/w:spacing{w:before=840}'), - ('w:p/w:pPr/w:spacing{w:before=840}', None, - 'w:p/w:pPr/w:spacing'), - ]) + @pytest.fixture( + params=[ + ("w:p", Pt(12), "w:p/w:pPr/w:spacing{w:before=240}"), + ("w:p", None, "w:p/w:pPr"), + ("w:p/w:pPr", Pt(12), "w:p/w:pPr/w:spacing{w:before=240}"), + ("w:p/w:pPr", None, "w:p/w:pPr"), + ("w:p/w:pPr/w:spacing", Pt(12), "w:p/w:pPr/w:spacing{w:before=240}"), + ("w:p/w:pPr/w:spacing", None, "w:p/w:pPr/w:spacing"), + ( + "w:p/w:pPr/w:spacing{w:before=240}", + Pt(42), + "w:p/w:pPr/w:spacing{w:before=840}", + ), + ("w:p/w:pPr/w:spacing{w:before=840}", None, "w:p/w:pPr/w:spacing"), + ] + ) def space_before_set_fixture(self, request): p_cxml, value, expected_p_cxml = request.param paragraph_format = ParagraphFormat(element(p_cxml)) @@ -404,7 +477,7 @@ def space_before_set_fixture(self, request): @pytest.fixture def tab_stops_fixture(self, TabStops_, tab_stops_): - p = element('w:p/w:pPr') + p = element("w:p/w:pPr") pPr = p.pPr paragraph_format = ParagraphFormat(p, None) return paragraph_format, TabStops_, pPr, tab_stops_ @@ -413,9 +486,7 @@ def tab_stops_fixture(self, TabStops_, tab_stops_): @pytest.fixture def TabStops_(self, request, tab_stops_): - return class_mock( - request, 'docx.text.parfmt.TabStops', return_value=tab_stops_ - ) + return class_mock(request, "docx.text.parfmt.TabStops", return_value=tab_stops_) @pytest.fixture def tab_stops_(self, request): diff --git a/tests/text/test_run.py b/tests/text/test_run.py index ae23c641..02cb8741 100644 --- a/tests/text/test_run.py +++ b/tests/text/test_run.py @@ -18,7 +18,6 @@ class DescribeRun(object): - def it_knows_its_bool_prop_states(self, bool_prop_get_fixture): run, prop_name, expected_state = bool_prop_get_fixture assert getattr(run, prop_name) == expected_state @@ -31,17 +30,13 @@ def it_can_change_its_bool_prop_settings(self, bool_prop_set_fixture): def it_knows_its_character_style(self, style_get_fixture): run, style_id_, style_ = style_get_fixture style = run.style - run.part.get_style.assert_called_once_with( - style_id_, WD_STYLE_TYPE.CHARACTER - ) + run.part.get_style.assert_called_once_with(style_id_, WD_STYLE_TYPE.CHARACTER) assert style is style_ def it_can_change_its_character_style(self, style_set_fixture): run, value, expected_xml = style_set_fixture run.style = value - run.part.get_style_id.assert_called_once_with( - value, WD_STYLE_TYPE.CHARACTER - ) + run.part.get_style_id.assert_called_once_with(value, WD_STYLE_TYPE.CHARACTER) assert run._r.xml == expected_xml def it_knows_its_underline_type(self, underline_get_fixture): @@ -53,8 +48,7 @@ def it_can_change_its_underline_type(self, underline_set_fixture): run.underline = underline assert run._r.xml == expected_xml - def it_raises_on_assign_invalid_underline_type( - self, underline_raise_fixture): + def it_raises_on_assign_invalid_underline_type(self, underline_raise_fixture): run, underline = underline_raise_fixture with pytest.raises(ValueError): run.underline = underline @@ -112,105 +106,111 @@ def it_can_replace_the_text_it_contains(self, text_set_fixture): # fixtures ------------------------------------------------------- - @pytest.fixture(params=[ - (WD_BREAK.LINE, 'w:r/w:br'), - (WD_BREAK.PAGE, 'w:r/w:br{w:type=page}'), - (WD_BREAK.COLUMN, 'w:r/w:br{w:type=column}'), - (WD_BREAK.LINE_CLEAR_LEFT, - 'w:r/w:br{w:type=textWrapping, w:clear=left}'), - (WD_BREAK.LINE_CLEAR_RIGHT, - 'w:r/w:br{w:type=textWrapping, w:clear=right}'), - (WD_BREAK.LINE_CLEAR_ALL, - 'w:r/w:br{w:type=textWrapping, w:clear=all}'), - ]) + @pytest.fixture( + params=[ + (WD_BREAK.LINE, "w:r/w:br"), + (WD_BREAK.PAGE, "w:r/w:br{w:type=page}"), + (WD_BREAK.COLUMN, "w:r/w:br{w:type=column}"), + (WD_BREAK.LINE_CLEAR_LEFT, "w:r/w:br{w:type=textWrapping, w:clear=left}"), + (WD_BREAK.LINE_CLEAR_RIGHT, "w:r/w:br{w:type=textWrapping, w:clear=right}"), + (WD_BREAK.LINE_CLEAR_ALL, "w:r/w:br{w:type=textWrapping, w:clear=all}"), + ] + ) def add_break_fixture(self, request): break_type, expected_cxml = request.param - run = Run(element('w:r'), None) + run = Run(element("w:r"), None) expected_xml = xml(expected_cxml) return run, break_type, expected_xml @pytest.fixture - def add_picture_fixture(self, part_prop_, document_part_, InlineShape_, - picture_): - run = Run(element('w:r/wp:x'), None) - image = 'foobar.png' - width, height, inline = 1111, 2222, element('wp:inline{id=42}') - expected_xml = xml('w:r/(wp:x,w:drawing/wp:inline{id=42})') + def add_picture_fixture(self, part_prop_, document_part_, InlineShape_, picture_): + run = Run(element("w:r/wp:x"), None) + image = "foobar.png" + width, height, inline = 1111, 2222, element("wp:inline{id=42}") + expected_xml = xml("w:r/(wp:x,w:drawing/wp:inline{id=42})") document_part_.new_pic_inline.return_value = inline InlineShape_.return_value = picture_ - return ( - run, image, width, height, inline, expected_xml, InlineShape_, - picture_ - ) - - @pytest.fixture(params=[ - ('w:r/w:t"foo"', 'w:r/(w:t"foo", w:tab)'), - ]) + return (run, image, width, height, inline, expected_xml, InlineShape_, picture_) + + @pytest.fixture( + params=[ + ('w:r/w:t"foo"', 'w:r/(w:t"foo", w:tab)'), + ] + ) def add_tab_fixture(self, request): r_cxml, expected_cxml = request.param run = Run(element(r_cxml), None) expected_xml = xml(expected_cxml) return run, expected_xml - @pytest.fixture(params=[ - ('w:r', 'foo', 'w:r/w:t"foo"'), - ('w:r/w:t"foo"', 'bar', 'w:r/(w:t"foo", w:t"bar")'), - ('w:r', 'fo ', 'w:r/w:t{xml:space=preserve}"fo "'), - ('w:r', 'f o', 'w:r/w:t"f o"'), - ]) + @pytest.fixture( + params=[ + ("w:r", "foo", 'w:r/w:t"foo"'), + ('w:r/w:t"foo"', "bar", 'w:r/(w:t"foo", w:t"bar")'), + ("w:r", "fo ", 'w:r/w:t{xml:space=preserve}"fo "'), + ("w:r", "f o", 'w:r/w:t"f o"'), + ] + ) def add_text_fixture(self, request): r_cxml, text, expected_cxml = request.param r = element(r_cxml) expected_xml = xml(expected_cxml) return r, text, expected_xml - @pytest.fixture(params=[ - ('w:r/w:rPr', 'bold', None), - ('w:r/w:rPr/w:b', 'bold', True), - ('w:r/w:rPr/w:b{w:val=on}', 'bold', True), - ('w:r/w:rPr/w:b{w:val=off}', 'bold', False), - ('w:r/w:rPr/w:b{w:val=1}', 'bold', True), - ('w:r/w:rPr/w:i{w:val=0}', 'italic', False), - ]) + @pytest.fixture( + params=[ + ("w:r/w:rPr", "bold", None), + ("w:r/w:rPr/w:b", "bold", True), + ("w:r/w:rPr/w:b{w:val=on}", "bold", True), + ("w:r/w:rPr/w:b{w:val=off}", "bold", False), + ("w:r/w:rPr/w:b{w:val=1}", "bold", True), + ("w:r/w:rPr/w:i{w:val=0}", "italic", False), + ] + ) def bool_prop_get_fixture(self, request): r_cxml, bool_prop_name, expected_value = request.param run = Run(element(r_cxml), None) return run, bool_prop_name, expected_value - @pytest.fixture(params=[ - # nothing to True, False, and None --------------------------- - ('w:r', 'bold', True, 'w:r/w:rPr/w:b'), - ('w:r', 'bold', False, 'w:r/w:rPr/w:b{w:val=0}'), - ('w:r', 'italic', None, 'w:r/w:rPr'), - # default to True, False, and None --------------------------- - ('w:r/w:rPr/w:b', 'bold', True, 'w:r/w:rPr/w:b'), - ('w:r/w:rPr/w:b', 'bold', False, 'w:r/w:rPr/w:b{w:val=0}'), - ('w:r/w:rPr/w:i', 'italic', None, 'w:r/w:rPr'), - # True to True, False, and None ------------------------------ - ('w:r/w:rPr/w:b{w:val=on}', 'bold', True, 'w:r/w:rPr/w:b'), - ('w:r/w:rPr/w:b{w:val=1}', 'bold', False, 'w:r/w:rPr/w:b{w:val=0}'), - ('w:r/w:rPr/w:b{w:val=1}', 'bold', None, 'w:r/w:rPr'), - # False to True, False, and None ----------------------------- - ('w:r/w:rPr/w:i{w:val=false}', 'italic', True, 'w:r/w:rPr/w:i'), - ('w:r/w:rPr/w:i{w:val=0}', 'italic', False, - 'w:r/w:rPr/w:i{w:val=0}'), - ('w:r/w:rPr/w:i{w:val=off}', 'italic', None, 'w:r/w:rPr'), - ]) + @pytest.fixture( + params=[ + # nothing to True, False, and None --------------------------- + ("w:r", "bold", True, "w:r/w:rPr/w:b"), + ("w:r", "bold", False, "w:r/w:rPr/w:b{w:val=0}"), + ("w:r", "italic", None, "w:r/w:rPr"), + # default to True, False, and None --------------------------- + ("w:r/w:rPr/w:b", "bold", True, "w:r/w:rPr/w:b"), + ("w:r/w:rPr/w:b", "bold", False, "w:r/w:rPr/w:b{w:val=0}"), + ("w:r/w:rPr/w:i", "italic", None, "w:r/w:rPr"), + # True to True, False, and None ------------------------------ + ("w:r/w:rPr/w:b{w:val=on}", "bold", True, "w:r/w:rPr/w:b"), + ("w:r/w:rPr/w:b{w:val=1}", "bold", False, "w:r/w:rPr/w:b{w:val=0}"), + ("w:r/w:rPr/w:b{w:val=1}", "bold", None, "w:r/w:rPr"), + # False to True, False, and None ----------------------------- + ("w:r/w:rPr/w:i{w:val=false}", "italic", True, "w:r/w:rPr/w:i"), + ("w:r/w:rPr/w:i{w:val=0}", "italic", False, "w:r/w:rPr/w:i{w:val=0}"), + ("w:r/w:rPr/w:i{w:val=off}", "italic", None, "w:r/w:rPr"), + ] + ) def bool_prop_set_fixture(self, request): initial_r_cxml, bool_prop_name, value, expected_cxml = request.param run = Run(element(initial_r_cxml), None) expected_xml = xml(expected_cxml) return run, bool_prop_name, value, expected_xml - @pytest.fixture(params=[ - ('w:r', 'w:r'), - ('w:r/w:t"foo"', 'w:r'), - ('w:r/w:br', 'w:r'), - ('w:r/w:rPr', 'w:r/w:rPr'), - ('w:r/(w:rPr, w:t"foo")', 'w:r/w:rPr'), - ('w:r/(w:rPr/(w:b, w:i), w:t"foo", w:cr, w:t"bar")', - 'w:r/w:rPr/(w:b, w:i)'), - ]) + @pytest.fixture( + params=[ + ("w:r", "w:r"), + ('w:r/w:t"foo"', "w:r"), + ("w:r/w:br", "w:r"), + ("w:r/w:rPr", "w:r/w:rPr"), + ('w:r/(w:rPr, w:t"foo")', "w:r/w:rPr"), + ( + 'w:r/(w:rPr/(w:b, w:i), w:t"foo", w:cr, w:t"bar")', + "w:r/w:rPr/(w:b, w:i)", + ), + ] + ) def clear_fixture(self, request): initial_r_cxml, expected_cxml = request.param run = Run(element(initial_r_cxml), None) @@ -219,29 +219,31 @@ def clear_fixture(self, request): @pytest.fixture def font_fixture(self, Font_, font_): - run = Run(element('w:r'), None) + run = Run(element("w:r"), None) return run, Font_, font_ @pytest.fixture def style_get_fixture(self, part_prop_): - style_id = 'Barfoo' - r_cxml = 'w:r/w:rPr/w:rStyle{w:val=%s}' % style_id + style_id = "Barfoo" + r_cxml = "w:r/w:rPr/w:rStyle{w:val=%s}" % style_id run = Run(element(r_cxml), None) style_ = part_prop_.return_value.get_style.return_value return run, style_id, style_ - @pytest.fixture(params=[ - ('w:r', 'Foo Font', 'FooFont', - 'w:r/w:rPr/w:rStyle{w:val=FooFont}'), - ('w:r/w:rPr', 'Foo Font', 'FooFont', - 'w:r/w:rPr/w:rStyle{w:val=FooFont}'), - ('w:r/w:rPr/w:rStyle{w:val=FooFont}', 'Bar Font', 'BarFont', - 'w:r/w:rPr/w:rStyle{w:val=BarFont}'), - ('w:r/w:rPr/w:rStyle{w:val=FooFont}', None, None, - 'w:r/w:rPr'), - ('w:r', None, None, - 'w:r/w:rPr'), - ]) + @pytest.fixture( + params=[ + ("w:r", "Foo Font", "FooFont", "w:r/w:rPr/w:rStyle{w:val=FooFont}"), + ("w:r/w:rPr", "Foo Font", "FooFont", "w:r/w:rPr/w:rStyle{w:val=FooFont}"), + ( + "w:r/w:rPr/w:rStyle{w:val=FooFont}", + "Bar Font", + "BarFont", + "w:r/w:rPr/w:rStyle{w:val=BarFont}", + ), + ("w:r/w:rPr/w:rStyle{w:val=FooFont}", None, None, "w:r/w:rPr"), + ("w:r", None, None, "w:r/w:rPr"), + ] + ) def style_set_fixture(self, request, part_prop_): r_cxml, value, style_id, expected_cxml = request.param run = Run(element(r_cxml), None) @@ -249,23 +251,27 @@ def style_set_fixture(self, request, part_prop_): expected_xml = xml(expected_cxml) return run, value, expected_xml - @pytest.fixture(params=[ - ('w:r', ''), - ('w:r/w:t"foobar"', 'foobar'), - ('w:r/(w:t"abc", w:tab, w:t"def", w:cr)', 'abc\tdef\n'), - ('w:r/(w:br{w:type=page}, w:t"abc", w:t"def", w:tab)', '\nabcdef\t'), - ]) + @pytest.fixture( + params=[ + ("w:r", ""), + ('w:r/w:t"foobar"', "foobar"), + ('w:r/(w:t"abc", w:tab, w:t"def", w:cr)', "abc\tdef\n"), + ('w:r/(w:br{w:type=page}, w:t"abc", w:t"def", w:tab)', "\nabcdef\t"), + ] + ) def text_get_fixture(self, request): r_cxml, expected_text = request.param run = Run(element(r_cxml), None) return run, expected_text - @pytest.fixture(params=[ - ('abc def', 'w:r/w:t"abc def"'), - ('abc\tdef', 'w:r/(w:t"abc", w:tab, w:t"def")'), - ('abc\ndef', 'w:r/(w:t"abc", w:br, w:t"def")'), - ('abc\rdef', 'w:r/(w:t"abc", w:br, w:t"def")'), - ]) + @pytest.fixture( + params=[ + ("abc def", 'w:r/w:t"abc def"'), + ("abc\tdef", 'w:r/(w:t"abc", w:tab, w:t"def")'), + ("abc\ndef", 'w:r/(w:t"abc", w:br, w:t"def")'), + ("abc\rdef", 'w:r/(w:t"abc", w:br, w:t"def")'), + ] + ) def text_set_fixture(self, request): new_text, expected_cxml = request.param initial_r_cxml = 'w:r/w:t"should get deleted"' @@ -273,46 +279,53 @@ def text_set_fixture(self, request): expected_xml = xml(expected_cxml) return run, new_text, expected_xml - @pytest.fixture(params=[ - ('w:r', None), - ('w:r/w:rPr/w:u', None), - ('w:r/w:rPr/w:u{w:val=single}', True), - ('w:r/w:rPr/w:u{w:val=none}', False), - ('w:r/w:rPr/w:u{w:val=double}', WD_UNDERLINE.DOUBLE), - ('w:r/w:rPr/w:u{w:val=wave}', WD_UNDERLINE.WAVY), - ]) + @pytest.fixture( + params=[ + ("w:r", None), + ("w:r/w:rPr/w:u", None), + ("w:r/w:rPr/w:u{w:val=single}", True), + ("w:r/w:rPr/w:u{w:val=none}", False), + ("w:r/w:rPr/w:u{w:val=double}", WD_UNDERLINE.DOUBLE), + ("w:r/w:rPr/w:u{w:val=wave}", WD_UNDERLINE.WAVY), + ] + ) def underline_get_fixture(self, request): r_cxml, expected_underline = request.param run = Run(element(r_cxml), None) return run, expected_underline - @pytest.fixture(params=[ - ('w:r', True, 'w:r/w:rPr/w:u{w:val=single}'), - ('w:r', False, 'w:r/w:rPr/w:u{w:val=none}'), - ('w:r', None, 'w:r/w:rPr'), - ('w:r', WD_UNDERLINE.SINGLE, 'w:r/w:rPr/w:u{w:val=single}'), - ('w:r', WD_UNDERLINE.THICK, 'w:r/w:rPr/w:u{w:val=thick}'), - ('w:r/w:rPr/w:u{w:val=single}', True, - 'w:r/w:rPr/w:u{w:val=single}'), - ('w:r/w:rPr/w:u{w:val=single}', False, - 'w:r/w:rPr/w:u{w:val=none}'), - ('w:r/w:rPr/w:u{w:val=single}', None, - 'w:r/w:rPr'), - ('w:r/w:rPr/w:u{w:val=single}', WD_UNDERLINE.SINGLE, - 'w:r/w:rPr/w:u{w:val=single}'), - ('w:r/w:rPr/w:u{w:val=single}', WD_UNDERLINE.DOTTED, - 'w:r/w:rPr/w:u{w:val=dotted}'), - ]) + @pytest.fixture( + params=[ + ("w:r", True, "w:r/w:rPr/w:u{w:val=single}"), + ("w:r", False, "w:r/w:rPr/w:u{w:val=none}"), + ("w:r", None, "w:r/w:rPr"), + ("w:r", WD_UNDERLINE.SINGLE, "w:r/w:rPr/w:u{w:val=single}"), + ("w:r", WD_UNDERLINE.THICK, "w:r/w:rPr/w:u{w:val=thick}"), + ("w:r/w:rPr/w:u{w:val=single}", True, "w:r/w:rPr/w:u{w:val=single}"), + ("w:r/w:rPr/w:u{w:val=single}", False, "w:r/w:rPr/w:u{w:val=none}"), + ("w:r/w:rPr/w:u{w:val=single}", None, "w:r/w:rPr"), + ( + "w:r/w:rPr/w:u{w:val=single}", + WD_UNDERLINE.SINGLE, + "w:r/w:rPr/w:u{w:val=single}", + ), + ( + "w:r/w:rPr/w:u{w:val=single}", + WD_UNDERLINE.DOTTED, + "w:r/w:rPr/w:u{w:val=dotted}", + ), + ] + ) def underline_set_fixture(self, request): initial_r_cxml, new_underline, expected_cxml = request.param run = Run(element(initial_r_cxml), None) expected_xml = xml(expected_cxml) return run, new_underline, expected_xml - @pytest.fixture(params=['foobar', 42, 'single']) + @pytest.fixture(params=["foobar", 42, "single"]) def underline_raise_fixture(self, request): invalid_underline_setting = request.param - run = Run(element('w:r/w:rPr'), None) + run = Run(element("w:r/w:rPr"), None) return run, invalid_underline_setting # fixture components --------------------------------------------- @@ -323,7 +336,7 @@ def document_part_(self, request): @pytest.fixture def Font_(self, request, font_): - return class_mock(request, 'docx.text.run.Font', return_value=font_) + return class_mock(request, "docx.text.run.Font", return_value=font_) @pytest.fixture def font_(self, request): @@ -331,13 +344,11 @@ def font_(self, request): @pytest.fixture def InlineShape_(self, request): - return class_mock(request, 'docx.text.run.InlineShape') + return class_mock(request, "docx.text.run.InlineShape") @pytest.fixture def part_prop_(self, request, document_part_): - return property_mock( - request, Run, 'part', return_value=document_part_ - ) + return property_mock(request, Run, "part", return_value=document_part_) @pytest.fixture def picture_(self, request): @@ -345,4 +356,4 @@ def picture_(self, request): @pytest.fixture def Text_(self, request): - return class_mock(request, 'docx.text.run._Text') + return class_mock(request, "docx.text.run._Text") diff --git a/tests/text/test_tabstops.py b/tests/text/test_tabstops.py index 0ca10e62..29627fcb 100644 --- a/tests/text/test_tabstops.py +++ b/tests/text/test_tabstops.py @@ -5,9 +5,7 @@ TabStop objects. """ -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) +from __future__ import absolute_import, division, print_function, unicode_literals from docx.enum.text import WD_TAB_ALIGNMENT, WD_TAB_LEADER from docx.shared import Twips @@ -20,7 +18,6 @@ class DescribeTabStop(object): - def it_knows_its_position(self, position_get_fixture): tab_stop, expected_value = position_get_fixture assert tab_stop.position == expected_value @@ -51,20 +48,24 @@ def it_can_change_its_leader(self, leader_set_fixture): # fixture -------------------------------------------------------- - @pytest.fixture(params=[ - ('w:tab{w:val=left}', 'LEFT'), - ('w:tab{w:val=right}', 'RIGHT'), - ]) + @pytest.fixture( + params=[ + ("w:tab{w:val=left}", "LEFT"), + ("w:tab{w:val=right}", "RIGHT"), + ] + ) def alignment_get_fixture(self, request): tab_stop_cxml, member = request.param tab_stop = TabStop(element(tab_stop_cxml)) expected_value = getattr(WD_TAB_ALIGNMENT, member) return tab_stop, expected_value - @pytest.fixture(params=[ - ('w:tab{w:val=left}', 'RIGHT', 'w:tab{w:val=right}'), - ('w:tab{w:val=right}', 'LEFT', 'w:tab{w:val=left}'), - ]) + @pytest.fixture( + params=[ + ("w:tab{w:val=left}", "RIGHT", "w:tab{w:val=right}"), + ("w:tab{w:val=right}", "LEFT", "w:tab{w:val=left}"), + ] + ) def alignment_set_fixture(self, request): tab_stop_cxml, member, expected_cxml = request.param tab_stop = TabStop(element(tab_stop_cxml)) @@ -72,56 +73,75 @@ def alignment_set_fixture(self, request): value = getattr(WD_TAB_ALIGNMENT, member) return tab_stop, value, expected_xml - @pytest.fixture(params=[ - ('w:tab', 'SPACES'), - ('w:tab{w:leader=none}', 'SPACES'), - ('w:tab{w:leader=dot}', 'DOTS'), - ]) + @pytest.fixture( + params=[ + ("w:tab", "SPACES"), + ("w:tab{w:leader=none}", "SPACES"), + ("w:tab{w:leader=dot}", "DOTS"), + ] + ) def leader_get_fixture(self, request): tab_stop_cxml, member = request.param tab_stop = TabStop(element(tab_stop_cxml)) expected_value = getattr(WD_TAB_LEADER, member) return tab_stop, expected_value - @pytest.fixture(params=[ - ('w:tab', 'DOTS', 'w:tab{w:leader=dot}'), - ('w:tab{w:leader=dot}', 'DASHES', 'w:tab{w:leader=hyphen}'), - ('w:tab{w:leader=hyphen}', 'SPACES', 'w:tab'), - ('w:tab{w:leader=hyphen}', None, 'w:tab'), - ('w:tab', 'SPACES', 'w:tab'), - ('w:tab', None, 'w:tab'), - ]) + @pytest.fixture( + params=[ + ("w:tab", "DOTS", "w:tab{w:leader=dot}"), + ("w:tab{w:leader=dot}", "DASHES", "w:tab{w:leader=hyphen}"), + ("w:tab{w:leader=hyphen}", "SPACES", "w:tab"), + ("w:tab{w:leader=hyphen}", None, "w:tab"), + ("w:tab", "SPACES", "w:tab"), + ("w:tab", None, "w:tab"), + ] + ) def leader_set_fixture(self, request): tab_stop_cxml, new_value, expected_cxml = request.param tab_stop = TabStop(element(tab_stop_cxml)) - value = ( - None if new_value is None else getattr(WD_TAB_LEADER, new_value) - ) + value = None if new_value is None else getattr(WD_TAB_LEADER, new_value) expected_xml = xml(expected_cxml) return tab_stop, value, expected_xml @pytest.fixture def position_get_fixture(self, request): - tab_stop = TabStop(element('w:tab{w:pos=720}')) + tab_stop = TabStop(element("w:tab{w:pos=720}")) return tab_stop, Twips(720) - @pytest.fixture(params=[ - ('w:tabs/w:tab{w:pos=360,w:val=left}', - Twips(720), 0, - 'w:tabs/w:tab{w:pos=720,w:val=left}'), - ('w:tabs/(w:tab{w:pos=360,w:val=left},w:tab{w:pos=720,w:val=left})', - Twips(180), 0, - 'w:tabs/(w:tab{w:pos=180,w:val=left},w:tab{w:pos=720,w:val=left})'), - ('w:tabs/(w:tab{w:pos=360,w:val=left},w:tab{w:pos=720,w:val=left})', - Twips(960), 1, - 'w:tabs/(w:tab{w:pos=720,w:val=left},w:tab{w:pos=960,w:val=left})'), - ('w:tabs/(w:tab{w:pos=-72,w:val=left},w:tab{w:pos=-36,w:val=left})', - Twips(-48), 0, - 'w:tabs/(w:tab{w:pos=-48,w:val=left},w:tab{w:pos=-36,w:val=left})'), - ('w:tabs/(w:tab{w:pos=-72,w:val=left},w:tab{w:pos=-36,w:val=left})', - Twips(-16), 1, - 'w:tabs/(w:tab{w:pos=-36,w:val=left},w:tab{w:pos=-16,w:val=left})'), - ]) + @pytest.fixture( + params=[ + ( + "w:tabs/w:tab{w:pos=360,w:val=left}", + Twips(720), + 0, + "w:tabs/w:tab{w:pos=720,w:val=left}", + ), + ( + "w:tabs/(w:tab{w:pos=360,w:val=left},w:tab{w:pos=720,w:val=left})", + Twips(180), + 0, + "w:tabs/(w:tab{w:pos=180,w:val=left},w:tab{w:pos=720,w:val=left})", + ), + ( + "w:tabs/(w:tab{w:pos=360,w:val=left},w:tab{w:pos=720,w:val=left})", + Twips(960), + 1, + "w:tabs/(w:tab{w:pos=720,w:val=left},w:tab{w:pos=960,w:val=left})", + ), + ( + "w:tabs/(w:tab{w:pos=-72,w:val=left},w:tab{w:pos=-36,w:val=left})", + Twips(-48), + 0, + "w:tabs/(w:tab{w:pos=-48,w:val=left},w:tab{w:pos=-36,w:val=left})", + ), + ( + "w:tabs/(w:tab{w:pos=-72,w:val=left},w:tab{w:pos=-36,w:val=left})", + Twips(-16), + 1, + "w:tabs/(w:tab{w:pos=-36,w:val=left},w:tab{w:pos=-16,w:val=left})", + ), + ] + ) def position_set_fixture(self, request): tabs_cxml, value, new_idx, expected_cxml = request.param tabs = element(tabs_cxml) @@ -132,15 +152,12 @@ def position_set_fixture(self, request): class DescribeTabStops(object): - def it_knows_its_length(self, len_fixture): tab_stops, expected_value = len_fixture assert len(tab_stops) == expected_value def it_can_iterate_over_its_tab_stops(self, iter_fixture): - tab_stops, expected_count, tab_stop_, TabStop_, expected_calls = ( - iter_fixture - ) + tab_stops, expected_count, tab_stop_, TabStop_, expected_calls = iter_fixture count = 0 for tab_stop in tab_stops: assert tab_stop is tab_stop_ @@ -155,7 +172,7 @@ def it_can_get_a_tab_stop_by_index(self, index_fixture): assert tab_stop is tab_stop_ def it_raises_on_indexed_access_when_empty(self): - tab_stops = TabStops(element('w:pPr')) + tab_stops = TabStops(element("w:pPr")) with pytest.raises(IndexError): tab_stops[0] @@ -173,7 +190,7 @@ def it_raises_on_del_idx_invalid(self, del_raises_fixture): tab_stops, idx = del_raises_fixture with pytest.raises(IndexError) as exc: del tab_stops[idx] - assert exc.value.args[0] == 'tab index out of range' + assert exc.value.args[0] == "tab index out of range" def it_can_clear_all_its_tab_stops(self, clear_all_fixture): tab_stops, expected_xml = clear_all_fixture @@ -182,91 +199,127 @@ def it_can_clear_all_its_tab_stops(self, clear_all_fixture): # fixture -------------------------------------------------------- - @pytest.fixture(params=[ - 'w:pPr', - 'w:pPr/w:tabs/w:tab{w:pos=42}', - 'w:pPr/w:tabs/(w:tab{w:pos=24},w:tab{w:pos=42})', - ]) + @pytest.fixture( + params=[ + "w:pPr", + "w:pPr/w:tabs/w:tab{w:pos=42}", + "w:pPr/w:tabs/(w:tab{w:pos=24},w:tab{w:pos=42})", + ] + ) def clear_all_fixture(self, request): pPr_cxml = request.param tab_stops = TabStops(element(pPr_cxml)) - expected_xml = xml('w:pPr') + expected_xml = xml("w:pPr") return tab_stops, expected_xml - @pytest.fixture(params=[ - ('w:pPr/w:tabs/w:tab{w:pos=42}', 0, - 'w:pPr'), - ('w:pPr/w:tabs/(w:tab{w:pos=24},w:tab{w:pos=42})', 0, - 'w:pPr/w:tabs/w:tab{w:pos=42}'), - ('w:pPr/w:tabs/(w:tab{w:pos=24},w:tab{w:pos=42})', 1, - 'w:pPr/w:tabs/w:tab{w:pos=24}'), - ]) + @pytest.fixture( + params=[ + ("w:pPr/w:tabs/w:tab{w:pos=42}", 0, "w:pPr"), + ( + "w:pPr/w:tabs/(w:tab{w:pos=24},w:tab{w:pos=42})", + 0, + "w:pPr/w:tabs/w:tab{w:pos=42}", + ), + ( + "w:pPr/w:tabs/(w:tab{w:pos=24},w:tab{w:pos=42})", + 1, + "w:pPr/w:tabs/w:tab{w:pos=24}", + ), + ] + ) def del_fixture(self, request): pPr_cxml, idx, expected_cxml = request.param tab_stops = TabStops(element(pPr_cxml)) expected_xml = xml(expected_cxml) return tab_stops, idx, expected_xml - @pytest.fixture(params=[ - ('w:pPr', 0), - ('w:pPr/w:tabs/w:tab{w:pos=42}', 1), - ]) + @pytest.fixture( + params=[ + ("w:pPr", 0), + ("w:pPr/w:tabs/w:tab{w:pos=42}", 1), + ] + ) def del_raises_fixture(self, request): tab_stops_cxml, idx = request.param tab_stops = TabStops(element(tab_stops_cxml)) return tab_stops, idx - @pytest.fixture(params=[ - ('w:pPr', Twips(42), {}, - 'w:pPr/w:tabs/w:tab{w:pos=42,w:val=left}'), - ('w:pPr', Twips(72), {'alignment': WD_TAB_ALIGNMENT.RIGHT}, - 'w:pPr/w:tabs/w:tab{w:pos=72,w:val=right}'), - ('w:pPr', Twips(24), - {'alignment': WD_TAB_ALIGNMENT.CENTER, - 'leader': WD_TAB_LEADER.DOTS}, - 'w:pPr/w:tabs/w:tab{w:pos=24,w:val=center,w:leader=dot}'), - ('w:pPr/w:tabs/w:tab{w:pos=42}', Twips(72), {}, - 'w:pPr/w:tabs/(w:tab{w:pos=42},w:tab{w:pos=72,w:val=left})'), - ('w:pPr/w:tabs/w:tab{w:pos=42}', Twips(24), {}, - 'w:pPr/w:tabs/(w:tab{w:pos=24,w:val=left},w:tab{w:pos=42})'), - ('w:pPr/w:tabs/w:tab{w:pos=42}', Twips(42), {}, - 'w:pPr/w:tabs/(w:tab{w:pos=42},w:tab{w:pos=42,w:val=left})'), - ]) + @pytest.fixture( + params=[ + ("w:pPr", Twips(42), {}, "w:pPr/w:tabs/w:tab{w:pos=42,w:val=left}"), + ( + "w:pPr", + Twips(72), + {"alignment": WD_TAB_ALIGNMENT.RIGHT}, + "w:pPr/w:tabs/w:tab{w:pos=72,w:val=right}", + ), + ( + "w:pPr", + Twips(24), + {"alignment": WD_TAB_ALIGNMENT.CENTER, "leader": WD_TAB_LEADER.DOTS}, + "w:pPr/w:tabs/w:tab{w:pos=24,w:val=center,w:leader=dot}", + ), + ( + "w:pPr/w:tabs/w:tab{w:pos=42}", + Twips(72), + {}, + "w:pPr/w:tabs/(w:tab{w:pos=42},w:tab{w:pos=72,w:val=left})", + ), + ( + "w:pPr/w:tabs/w:tab{w:pos=42}", + Twips(24), + {}, + "w:pPr/w:tabs/(w:tab{w:pos=24,w:val=left},w:tab{w:pos=42})", + ), + ( + "w:pPr/w:tabs/w:tab{w:pos=42}", + Twips(42), + {}, + "w:pPr/w:tabs/(w:tab{w:pos=42},w:tab{w:pos=42,w:val=left})", + ), + ] + ) def add_tab_fixture(self, request): pPr_cxml, position, kwargs, expected_cxml = request.param tab_stops = TabStops(element(pPr_cxml)) expected_xml = xml(expected_cxml) return tab_stops, position, kwargs, expected_xml - @pytest.fixture(params=[ - ('w:pPr/w:tabs/w:tab{w:pos=0}', 0), - ('w:pPr/w:tabs/(w:tab{w:pos=1},w:tab{w:pos=2},w:tab{w:pos=3})', 1), - ('w:pPr/w:tabs/(w:tab{w:pos=4},w:tab{w:pos=5},w:tab{w:pos=6})', 2), - ]) + @pytest.fixture( + params=[ + ("w:pPr/w:tabs/w:tab{w:pos=0}", 0), + ("w:pPr/w:tabs/(w:tab{w:pos=1},w:tab{w:pos=2},w:tab{w:pos=3})", 1), + ("w:pPr/w:tabs/(w:tab{w:pos=4},w:tab{w:pos=5},w:tab{w:pos=6})", 2), + ] + ) def index_fixture(self, request, TabStop_, tab_stop_): pPr_cxml, idx = request.param pPr = element(pPr_cxml) - tab = pPr.xpath('./w:tabs/w:tab')[idx] + tab = pPr.xpath("./w:tabs/w:tab")[idx] tab_stops = TabStops(pPr) return tab_stops, idx, TabStop_, tab, tab_stop_ - @pytest.fixture(params=[ - ('w:pPr', 0), - ('w:pPr/w:tabs/w:tab{w:pos=2880}', 1), - ('w:pPr/w:tabs/(w:tab{w:pos=2880},w:tab{w:pos=5760})', 2), - ]) + @pytest.fixture( + params=[ + ("w:pPr", 0), + ("w:pPr/w:tabs/w:tab{w:pos=2880}", 1), + ("w:pPr/w:tabs/(w:tab{w:pos=2880},w:tab{w:pos=5760})", 2), + ] + ) def iter_fixture(self, request, TabStop_, tab_stop_): pPr_cxml, expected_count = request.param pPr = element(pPr_cxml) - tab_elms = pPr.xpath('//w:tab') + tab_elms = pPr.xpath("//w:tab") tab_stops = TabStops(pPr) expected_calls = [call(tab) for tab in tab_elms] return tab_stops, expected_count, tab_stop_, TabStop_, expected_calls - @pytest.fixture(params=[ - ('w:pPr', 0), - ('w:pPr/w:tabs/w:tab{w:pos=2880}', 1), - ]) + @pytest.fixture( + params=[ + ("w:pPr", 0), + ("w:pPr/w:tabs/w:tab{w:pos=2880}", 1), + ] + ) def len_fixture(self, request): tab_stops_cxml, expected_value = request.param tab_stops = TabStops(element(tab_stops_cxml)) @@ -276,9 +329,7 @@ def len_fixture(self, request): @pytest.fixture def TabStop_(self, request, tab_stop_): - return class_mock( - request, 'docx.text.tabstops.TabStop', return_value=tab_stop_ - ) + return class_mock(request, "docx.text.tabstops.TabStop", return_value=tab_stop_) @pytest.fixture def tab_stop_(self, request): diff --git a/tests/unitdata.py b/tests/unitdata.py index 208be48d..7fe0a7c1 100644 --- a/tests/unitdata.py +++ b/tests/unitdata.py @@ -14,17 +14,16 @@ class BaseBuilder(object): """ Provides common behavior for all data builders. """ + def __init__(self): self._empty = False - self._nsdecls = '' - self._text = '' + self._nsdecls = "" + self._text = "" self._xmlattrs = [] self._xmlattr_method_map = {} for attr_name in self.__attrs__: - base_name = ( - attr_name.split(':')[1] if ':' in attr_name else attr_name - ) - method_name = 'with_%s' % base_name + base_name = attr_name.split(":")[1] if ":" in attr_name else attr_name + method_name = "with_%s" % base_name self._xmlattr_method_map[method_name] = attr_name self._child_bldrs = [] @@ -34,10 +33,12 @@ def __getattr__(self, name): methods. """ if name in self._xmlattr_method_map: + def with_xmlattr(value): xmlattr_name = self._xmlattr_method_map[name] self._set_xmlattr(xmlattr_name, value) return self + return with_xmlattr else: tmpl = "'%s' object has no attribute '%s'" @@ -85,45 +86,44 @@ def with_nsdecls(self, *nspfxs): """ if not nspfxs: nspfxs = self.__nspfxs__ - self._nsdecls = ' %s' % nsdecls(*nspfxs) + self._nsdecls = " %s" % nsdecls(*nspfxs) return self def xml(self, indent=0): """ Return element XML based on attribute settings """ - indent_str = ' ' * indent + indent_str = " " * indent if self._is_empty: - xml = '%s%s\n' % (indent_str, self._empty_element_tag) + xml = "%s%s\n" % (indent_str, self._empty_element_tag) else: - xml = '%s\n' % self._non_empty_element_xml(indent) + xml = "%s\n" % self._non_empty_element_xml(indent) return xml def xml_bytes(self, indent=0): - return self.xml(indent=indent).encode('utf-8') + return self.xml(indent=indent).encode("utf-8") @property def _empty_element_tag(self): - return '<%s%s%s/>' % (self.__tag__, self._nsdecls, self._xmlattrs_str) + return "<%s%s%s/>" % (self.__tag__, self._nsdecls, self._xmlattrs_str) @property def _end_tag(self): - return '' % self.__tag__ + return "" % self.__tag__ @property def _is_empty(self): return len(self._child_bldrs) == 0 and len(self._text) == 0 def _non_empty_element_xml(self, indent): - indent_str = ' ' * indent + indent_str = " " * indent if self._text: - xml = ('%s%s%s%s' % - (indent_str, self._start_tag, self._text, self._end_tag)) + xml = "%s%s%s%s" % (indent_str, self._start_tag, self._text, self._end_tag) else: - xml = '%s%s\n' % (indent_str, self._start_tag) + xml = "%s%s\n" % (indent_str, self._start_tag) for child_bldr in self._child_bldrs: - xml += child_bldr.xml(indent+2) - xml += '%s%s' % (indent_str, self._end_tag) + xml += child_bldr.xml(indent + 2) + xml += "%s%s" % (indent_str, self._end_tag) return xml def _set_xmlattr(self, xmlattr_name, value): @@ -132,11 +132,11 @@ def _set_xmlattr(self, xmlattr_name, value): @property def _start_tag(self): - return '<%s%s%s>' % (self.__tag__, self._nsdecls, self._xmlattrs_str) + return "<%s%s%s>" % (self.__tag__, self._nsdecls, self._xmlattrs_str) @property def _xmlattrs_str(self): """ Return all element attributes as a string, like ' foo="bar" x="1"'. """ - return ''.join(self._xmlattrs) + return "".join(self._xmlattrs) diff --git a/tests/unitutil/cxml.py b/tests/unitutil/cxml.py index f583a3c9..3029eda7 100644 --- a/tests/unitutil/cxml.py +++ b/tests/unitutil/cxml.py @@ -32,6 +32,7 @@ # api functions # ==================================================================== + def element(cxel_str): """ Return an oxml element parsed from the XML generated from *cxel_str*. @@ -59,7 +60,7 @@ def nsdecls(*nspfxs): Return a string containing a namespace declaration for each of *nspfxs*, in the order they are specified. """ - nsdecls = '' + nsdecls = "" for nspfx in nspfxs: nsdecls += ' xmlns:%s="%s"' % (nspfx, nsmap[nspfx]) return nsdecls @@ -70,6 +71,7 @@ class Element(object): Represents an XML element, having a namespace, tagname, attributes, and may contain either text or children (but not both) or may be empty. """ + def __init__(self, tagname, attrs, text): self._tagname = tagname self._attrs = attrs @@ -122,10 +124,11 @@ def local_nspfxs(self): all of its attributes. An empty string (``''``) is used to represent the default namespace for an element tag having no prefix. """ + def nspfx(name, is_element=False): - idx = name.find(':') + idx = name.find(":") if idx == -1: - return '' if is_element else None + return "" if is_element else None return name[:idx] nspfxs = [nspfx(self._tagname, True)] @@ -143,6 +146,7 @@ def nspfxs(self): this tree. Each prefix appears once and only once, and in document order. """ + def merge(seq, seq_2): for item in seq_2: if item in seq: @@ -168,10 +172,10 @@ def _xml(self, indent): Return a string containing the XML of this element and all its children with a starting indent of *indent* spaces. """ - self._indent_str = ' ' * indent + self._indent_str = " " * indent xml = self._start_tag for child in self._children: - xml += child._xml(indent+2) + xml += child._xml(indent + 2) xml += self._end_tag return xml @@ -187,17 +191,17 @@ def _start_tag(self): a newline. The tag is indented by this element's indent value in all cases. """ - _nsdecls = nsdecls(*self.nspfxs) if self.is_root else '' - tag = '%s<%s%s' % (self._indent_str, self._tagname, _nsdecls) + _nsdecls = nsdecls(*self.nspfxs) if self.is_root else "" + tag = "%s<%s%s" % (self._indent_str, self._tagname, _nsdecls) for attr in self._attrs: name, value = attr tag += ' %s="%s"' % (name, value) if self._text: - tag += '>%s' % self._text + tag += ">%s" % self._text elif self._children: - tag += '>\n' + tag += ">\n" else: - tag += '/>\n' + tag += "/>\n" return tag @property @@ -207,11 +211,11 @@ def _end_tag(self): element contains text, no leading indentation is included. """ if self._text: - tag = '\n' % self._tagname + tag = "\n" % self._tagname elif self._children: - tag = '%s\n' % (self._indent_str, self._tagname) + tag = "%s\n" % (self._indent_str, self._tagname) else: - tag = '' + tag = "" return tag @@ -221,6 +225,7 @@ def _end_tag(self): # parse actions ---------------------------------- + def connect_node_children(s, loc, tokens): node = tokens[0] node.element.connect_children(node.child_node_list) @@ -233,13 +238,13 @@ def connect_root_node_children(root_node): def grammar(): # terminals ---------------------------------- - colon = Literal(':') - equal = Suppress('=') - slash = Suppress('/') - open_paren = Suppress('(') - close_paren = Suppress(')') - open_brace = Suppress('{') - close_brace = Suppress('}') + colon = Literal(":") + equal = Suppress("=") + slash = Suppress("/") + open_paren = Suppress("(") + close_paren = Suppress(")") + open_brace = Suppress("{") + close_brace = Suppress("}") # np:tagName --------------------------------- nspfx = Word(alphas) @@ -247,8 +252,8 @@ def grammar(): tagname = Combine(nspfx + colon + local_name) # np:attr_name=attr_val ---------------------- - attr_name = Word(alphas + ':') - attr_val = Word(alphanums + ' %-./:_') + attr_name = Word(alphas + ":") + attr_val = Word(alphanums + " %-./:_") attr_def = Group(attr_name + equal + attr_val) attr_list = open_brace + delimitedList(attr_def) + close_brace @@ -256,26 +261,22 @@ def grammar(): # w:jc{val=right} ---------------------------- element = ( - tagname('tagname') - + Group(Optional(attr_list))('attr_list') - + Optional(text, default='')('text') + tagname("tagname") + + Group(Optional(attr_list))("attr_list") + + Optional(text, default="")("text") ).setParseAction(Element.from_token) child_node_list = Forward() node = Group( - element('element') - + Group(Optional(slash + child_node_list))('child_node_list') + element("element") + Group(Optional(slash + child_node_list))("child_node_list") ).setParseAction(connect_node_children) - child_node_list << ( - open_paren + delimitedList(node) + close_paren - | node - ) + child_node_list << (open_paren + delimitedList(node) + close_paren | node) root_node = ( - element('element') - + Group(Optional(slash + child_node_list))('child_node_list') + element("element") + + Group(Optional(slash + child_node_list))("child_node_list") + stringEnd ).setParseAction(connect_root_node_children) diff --git a/tests/unitutil/mock.py b/tests/unitutil/mock.py index 828382e7..4bd1fdcc 100644 --- a/tests/unitutil/mock.py +++ b/tests/unitutil/mock.py @@ -70,9 +70,7 @@ def instance_mock(request, cls, name=None, spec_set=True, **kwargs): the Mock() call that creates the mock. """ name = name if name is not None else request.fixturename - return create_autospec( - cls, _name=name, spec_set=spec_set, instance=True, **kwargs - ) + return create_autospec(cls, _name=name, spec_set=spec_set, instance=True, **kwargs) def loose_mock(request, name=None, **kwargs): @@ -100,7 +98,7 @@ def open_mock(request, module_name, **kwargs): """ Return a mock for the builtin `open()` method in *module_name*. """ - target = '%s.open' % module_name + target = "%s.open" % module_name _patch = patch(target, mock_open(), create=True, **kwargs) request.addfinalizer(_patch.stop) return _patch.start() From 6b9c6f96cc376994dd96dc65ce4af32ef7dd6beb Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 27 Jun 2022 15:06:20 +0800 Subject: [PATCH 020/115] test custom xml (#13) --- tests/parts/test_customxml.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 tests/parts/test_customxml.py diff --git a/tests/parts/test_customxml.py b/tests/parts/test_customxml.py new file mode 100644 index 00000000..335fef4a --- /dev/null +++ b/tests/parts/test_customxml.py @@ -0,0 +1,34 @@ +import pytest + +from docx.opc.constants import CONTENT_TYPE as CT +from docx.parts.customxml import CustomXmlPart + + +class TestCustomXml: + def test_custom_xml(self, custom_xml_part): + assert custom_xml_part.tag == "python-docx-oss" + assert custom_xml_part.attrib["version"] == "1" + assert len(custom_xml_part.items) == 2 + assert custom_xml_part.items[1].text == "some texts" + + def test_add_item(self, custom_xml_part): + custom_xml_part.add_item("my-tag", "my-text", my_attrib="my_attrib_value") + assert len(custom_xml_part.items) == 3 + assert custom_xml_part.items[2].tag == "my-tag" + assert custom_xml_part.items[2].text == "my-text" + assert custom_xml_part.items[2].attrib["my_attrib"] == "my_attrib_value" + + @pytest.fixture + def custom_xml_part(self, mocker, default_xml): + return CustomXmlPart.default( + "default_file", CT.XML, default_xml, mocker.MagicMock() + ) + + @pytest.fixture + def default_xml(self): + return """ + + + some texts + + """ From f0ed79dce4314a68abe4245b95d40de06e51b310 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 30 Jun 2022 14:19:36 +0800 Subject: [PATCH 021/115] change method text to texts in CT_R (#14) * change-text-to-texts-in-CT_R * load_params --- docx/oxml/text/run.py | 9 +++------ docx/table.py | 9 ++------- docx/text/run.py | 11 +++-------- tests/oxml/text/test_run.py | 38 ++++++++++++++++++++++++++++++++----- 4 files changed, 41 insertions(+), 26 deletions(-) diff --git a/docx/oxml/text/run.py b/docx/oxml/text/run.py index 3d3d3cdf..a2667c6b 100644 --- a/docx/oxml/text/run.py +++ b/docx/oxml/text/run.py @@ -1,9 +1,6 @@ -# encoding: utf-8 - """ Custom element classes related to text runs (CT_R). """ - from ..ns import qn from ..simpletypes import ST_BrClear, ST_BrType from ..xmlchemy import BaseOxmlElement, OptionalAttribute, ZeroOrMore, ZeroOrOne @@ -81,7 +78,7 @@ def style(self, style): rPr.style = style @property - def text(self): + def texts(self): """ A string representing the textual content of this run, with content child elements like ```` translated to their Python @@ -98,8 +95,8 @@ def text(self): text += "\n" return text - @text.setter - def text(self, text): + @texts.setter + def texts(self, text): self.clear_content() _RunContentAppender.append_to_run_from_text(self, text) diff --git a/docx/table.py b/docx/table.py index bd4e1e27..4afb0ea0 100644 --- a/docx/table.py +++ b/docx/table.py @@ -1,15 +1,10 @@ -# encoding: utf-8 - """ The |Table| object and related proxy classes. """ - -from __future__ import absolute_import, print_function, unicode_literals - from .blkcntnr import BlockItemContainer from .enum.style import WD_STYLE_TYPE from .oxml.simpletypes import ST_Merge -from .shared import Inches, lazyproperty, Parented +from .shared import Inches, Parented, lazyproperty class Table(Parented): @@ -266,7 +261,7 @@ def text(self, text): tc.clear_content() p = tc.add_p() r = p.add_r() - r.text = text + r.texts = text @property def vertical_alignment(self): diff --git a/docx/text/run.py b/docx/text/run.py index 88c37fa3..51926d87 100644 --- a/docx/text/run.py +++ b/docx/text/run.py @@ -1,16 +1,11 @@ -# encoding: utf-8 - """ Run-related proxy objects for python-docx, Run in particular. """ - -from __future__ import absolute_import, print_function, unicode_literals - from ..enum.style import WD_STYLE_TYPE from ..enum.text import WD_BREAK -from .font import Font from ..shape import InlineShape from ..shared import Parented +from .font import Font class Run(Parented): @@ -155,11 +150,11 @@ def text(self): ``\\r`` character to a ```` element. Any existing run content is replaced. Run formatting is preserved. """ - return self._r.text + return self._r.texts @text.setter def text(self, text): - self._r.text = text + self._r.texts = text @property def underline(self): diff --git a/tests/oxml/text/test_run.py b/tests/oxml/text/test_run.py index 0dc091b2..4d1a8c15 100644 --- a/tests/oxml/text/test_run.py +++ b/tests/oxml/text/test_run.py @@ -1,11 +1,6 @@ -# encoding: utf-8 - """ Test suite for the docx.oxml.text.run module. """ - -from __future__ import absolute_import, division, print_function, unicode_literals - import pytest from ...unitutil.cxml import element, xml @@ -35,3 +30,36 @@ def add_t_fixture(self, request): r = element(initial_cxml) expected_xml = xml(expected_cxml) return r, text, expected_xml + + +class TestCT_R: + def test_texts(self, texts_item): + element, ret = texts_item + assert element.texts == ret + + def test_itertext(self, itertext_item): + element, ret = itertext_item + assert "".join(element.itertext()) == ret + + def load_params(self, request): + xml, expected_text = request.param + ctr = element(xml) + return ctr, expected_text + + @pytest.fixture( + params=[ + ('w:r/w:t"foobar"', "foobar"), + ('w:r/(w:t"abc", w:tab, w:t"def", w:cr)', "abcdef"), + ] + ) + def itertext_item(self, request): + return self.load_params(request) + + @pytest.fixture( + params=[ + ('w:r/w:t"foobar"', "foobar"), + ('w:r/(w:t"abc", w:tab, w:t"def", w:cr)', "abc\tdef\n"), + ] + ) + def texts_item(self, request): + return self.load_params(request) From 6c5ef51bd0df0d18e77b574dc473123c73c9e803 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 30 Jun 2022 14:45:00 +0800 Subject: [PATCH 022/115] 0.0.3 --- HISTORY.rst | 19 +++++++++++++------ docx/__init__.py | 2 +- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 31500c2f..d567bfd8 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -3,10 +3,17 @@ Release History --------------- +0.0.3 (2022-7-01) ++++++++++++++++++++ + +- Change method text to texts in CT_R. PR-14 +- Blacken all Python files. + + 0.0.2 (2022-06-24) +++++++++++++++++++ -- Add custom xml support. PR-#10 +- Add custom xml support. PR-10 - Add Part __eq__. - Add Part element setter. - Add Relationships parts_with_reltype. @@ -16,9 +23,9 @@ Release History +++++++++++++++++++ - Only support Python3.8, 3.9 and 3.10. -- Add custom properties support. PR-#2 -- Add drop_rels in Package. PR-#5 -- Add drop_rels in Part. PR-#5 -- Add default NumberingPart. PR-#4 -- Fix Python3.8+ __dict__ TypeError. PR-#6 +- Add custom properties support. PR-2 +- Add drop_rels in Package. PR-5 +- Add drop_rels in Part. PR-5 +- Add default NumberingPart. PR-4 +- Fix Python3.8+ __dict__ TypeError. PR-6 - Add some typehint. diff --git a/docx/__init__.py b/docx/__init__.py index 0eb4fdd3..95949849 100644 --- a/docx/__init__.py +++ b/docx/__init__.py @@ -1,6 +1,6 @@ from docx.api import Document # noqa -__version__ = "0.0.2" +__version__ = "0.0.3" # register custom Part classes with opc package reader From 4d51901427fb82ae3fa1592593185f056405cb84 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 30 Jun 2022 17:14:27 +0800 Subject: [PATCH 023/115] external target_ref setter (#15) --- docx/opc/rel.py | 6 ++++++ tests/opc/test_rel.py | 25 ++++++++++++++++--------- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/docx/opc/rel.py b/docx/opc/rel.py index 3386d1d9..ab3c5c13 100644 --- a/docx/opc/rel.py +++ b/docx/opc/rel.py @@ -173,3 +173,9 @@ def target_ref(self): return self._target else: return self._target.partname.relative_ref(self._baseURI) + + @target_ref.setter + def target_ref(self, ref: str): + if not self._is_external: + raise ValueError("can not set internal target_ref") + self._target = ref diff --git a/tests/opc/test_rel.py b/tests/opc/test_rel.py index f6d040a4..9f11b3f6 100644 --- a/tests/opc/test_rel.py +++ b/tests/opc/test_rel.py @@ -1,19 +1,15 @@ -# encoding: utf-8 - """ Unit test suite for the docx.opc.rel module """ - -from __future__ import absolute_import, division, print_function, unicode_literals - import pytest from docx.opc.oxml import CT_Relationships from docx.opc.packuri import PackURI from docx.opc.part import Part -from docx.opc.rel import _Relationship, Relationships +from docx.opc.rel import Relationships, _Relationship -from ..unitutil.mock import call, class_mock, instance_mock, Mock, patch, PropertyMock +from ..unitutil.mock import (Mock, PropertyMock, call, class_mock, + instance_mock, patch) class Describe_Relationship(object): @@ -40,6 +36,17 @@ def it_should_have_target_ref_for_external_rel(self): rel = _Relationship(None, None, "target", None, external=True) assert rel.target_ref == "target" + def it_should_change_target_ref_for_external_rel(self): + rel = _Relationship(None, None, "external_target1", None, external=True) + new_target = "external_target2" + rel.target_ref = new_target + assert rel.target_ref == new_target + + def it_raises_on_chaged_internal_rel(self): + rel = _Relationship(None, None, "internal_target1", None, external=False) + with pytest.raises(ValueError): + rel.target_ref = "t2" + def it_should_have_relative_ref_for_internal_rel(self): """ Internal relationships (TargetMode == 'Internal' in the XML) should @@ -139,7 +146,7 @@ def add_ext_rel_fixture_(self, reltype, url): return rels, reltype, url @pytest.fixture - def add_matching_ext_rel_fixture_(self, request, reltype, url): + def add_matching_ext_rel_fixture_(self, reltype, url): rId = "rId369" rels = Relationships(None) rels.add_relationship(reltype, url, rId, is_external=True) @@ -203,7 +210,7 @@ def _rel_with_known_target_part(self, _rId, reltype, _target_part, _baseURI): @pytest.fixture def rels_with_known_target_part(self, rels, _rel_with_known_target_part): - rel, rId, target_part = _rel_with_known_target_part + _, rId, target_part = _rel_with_known_target_part rels.add_relationship(None, target_part, rId) return rels, rId, target_part From 127c57b7ed0a24a328f4d9728e6287b3d27e1acb Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 30 Jun 2022 18:01:30 +0800 Subject: [PATCH 024/115] HISTORY.rst --- HISTORY.rst | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index d567bfd8..e8189cde 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -6,14 +6,15 @@ Release History 0.0.3 (2022-7-01) +++++++++++++++++++ -- Change method text to texts in CT_R. PR-14 +- Change method text to texts in CT_R. #14 +- Add external target_ref setter. #15 - Blacken all Python files. 0.0.2 (2022-06-24) +++++++++++++++++++ -- Add custom xml support. PR-10 +- Add custom xml support. #10 - Add Part __eq__. - Add Part element setter. - Add Relationships parts_with_reltype. @@ -23,9 +24,9 @@ Release History +++++++++++++++++++ - Only support Python3.8, 3.9 and 3.10. -- Add custom properties support. PR-2 -- Add drop_rels in Package. PR-5 -- Add drop_rels in Part. PR-5 -- Add default NumberingPart. PR-4 -- Fix Python3.8+ __dict__ TypeError. PR-6 +- Add custom properties support. #2 +- Add drop_rels in Package. #5 +- Add drop_rels in Part. #5 +- Add default NumberingPart. #4 +- Fix Python3.8+ __dict__ TypeError. #6 - Add some typehint. From 2af1a14bc7811c7aa7f9de3c723fe425dfb967bc Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 1 Jul 2022 10:31:26 +0800 Subject: [PATCH 025/115] README --- README.rst | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 82d1f0bd..21f4e6bc 100644 --- a/README.rst +++ b/README.rst @@ -1,8 +1,19 @@ .. image:: https://travis-ci.org/python-openxml/python-docx.svg?branch=master :target: https://travis-ci.org/python-openxml/python-docx -*python-docx* is a Python library for creating and updating Microsoft Word -(.docx) files. +*python-docx-oss* is a Python library for CRUD Microsoft Word (.docx) files. + + +Requirements +------------ + +- Python3.8+. +- lxml>=4.6.5 + + +FAQ +--- + More information is available in the `python-docx documentation`_. From c8bec9d5af2b9dc89c4584f53bcc32354b3ee8fe Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 1 Jul 2022 10:54:48 +0800 Subject: [PATCH 026/115] change readme format to markdown --- README.rst | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 README.rst diff --git a/README.rst b/README.rst deleted file mode 100644 index 21f4e6bc..00000000 --- a/README.rst +++ /dev/null @@ -1,21 +0,0 @@ -.. image:: https://travis-ci.org/python-openxml/python-docx.svg?branch=master - :target: https://travis-ci.org/python-openxml/python-docx - -*python-docx-oss* is a Python library for CRUD Microsoft Word (.docx) files. - - -Requirements ------------- - -- Python3.8+. -- lxml>=4.6.5 - - -FAQ ---- - - -More information is available in the `python-docx documentation`_. - -.. _`python-docx documentation`: - https://python-docx.readthedocs.org/en/latest/ From 6c1889d009d2b6e4221f2f6c915ac8645902940b Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 1 Jul 2022 10:55:40 +0800 Subject: [PATCH 027/115] change readme format to markdown --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..37527129 --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +.. image:: https://travis-ci.org/python-openxml/python-docx.svg?branch=master + :target: https://travis-ci.org/python-openxml/python-docx + +*python-docx-oss* is a Python library for CRUD Microsoft Word (.docx) files. + + +[![Supported Versions](https://img.shields.io/pypi/pyversions/requests.svg)](https://pypi.org/project/requests) + + +FAQ +--- + + +More information is available in the `python-docx documentation`_. + +.. _`python-docx documentation`: + https://python-docx.readthedocs.org/en/latest/ From baed52cfeb5746daf8171423e301371566a80dbd Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 1 Jul 2022 11:23:05 +0800 Subject: [PATCH 028/115] README --- README.md | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 37527129..99169dba 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,12 @@ -.. image:: https://travis-ci.org/python-openxml/python-docx.svg?branch=master - :target: https://travis-ci.org/python-openxml/python-docx *python-docx-oss* is a Python library for CRUD Microsoft Word (.docx) files. -[![Supported Versions](https://img.shields.io/pypi/pyversions/requests.svg)](https://pypi.org/project/requests) +[![Supported Versions](https://img.shields.io/pypi/pyversions/python-docx-oss.svg)](https://pypi.org/project/python-docx-oss) FAQ --- -More information is available in the `python-docx documentation`_. - -.. _`python-docx documentation`: - https://python-docx.readthedocs.org/en/latest/ +More information is available in the [python-docx documentation](https://python-docx.readthedocs.org/en/latest/) From b8187e73a516d73ab197c9ec2cafe15123364390 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 1 Jul 2022 11:44:14 +0800 Subject: [PATCH 029/115] README --- README.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 99169dba..65934109 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,19 @@ *python-docx-oss* is a Python library for CRUD Microsoft Word (.docx) files. -[![Supported Versions](https://img.shields.io/pypi/pyversions/python-docx-oss.svg)](https://pypi.org/project/python-docx-oss) +

+ PyPI + + Code style: black + License: MIT +

-FAQ +## FAQ --- +**Q: What's New?** + +**A:** [HISTORY](https://github.com/lsaint/python-docx-oss/blob/master/HISTORY.rst) More information is available in the [python-docx documentation](https://python-docx.readthedocs.org/en/latest/) From 506083547bff4d2f69c3b3b8058ad522af625b2c Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 1 Jul 2022 11:50:04 +0800 Subject: [PATCH 030/115] Update README.md --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 65934109..c0e777ad 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ - -*python-docx-oss* is a Python library for CRUD Microsoft Word (.docx) files. +**_python-docx-oss_** is a Python library for CRUD Microsoft Word (.docx) files.

@@ -9,12 +8,14 @@ License: MIT

- -## FAQ --- + +### FAQ + **Q: What's New?** **A:** [HISTORY](https://github.com/lsaint/python-docx-oss/blob/master/HISTORY.rst) +--- More information is available in the [python-docx documentation](https://python-docx.readthedocs.org/en/latest/) From b0849fb5c42b652ae30d8c0b9d4f81ed66b3c9fc Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 1 Jul 2022 12:00:04 +0800 Subject: [PATCH 031/115] README.md & HISTORY.md --- HISTORY.rst => HISTORY.md | 13 +++++-------- MANIFEST.in | 2 +- README.md | 4 ++-- 3 files changed, 8 insertions(+), 11 deletions(-) rename HISTORY.rst => HISTORY.md (79%) diff --git a/HISTORY.rst b/HISTORY.md similarity index 79% rename from HISTORY.rst rename to HISTORY.md index e8189cde..c1a9134f 100644 --- a/HISTORY.rst +++ b/HISTORY.md @@ -1,18 +1,16 @@ -.. :changelog: - Release History --------------- -0.0.3 (2022-7-01) -+++++++++++++++++++ + + +**0.0.3 (2022-7-01)** - Change method text to texts in CT_R. #14 - Add external target_ref setter. #15 - Blacken all Python files. -0.0.2 (2022-06-24) -+++++++++++++++++++ +**0.0.2 (2022-06-24)** - Add custom xml support. #10 - Add Part __eq__. @@ -20,8 +18,7 @@ Release History - Add Relationships parts_with_reltype. -0.0.1 (2022-06-16) -+++++++++++++++++++ +**0.0.1 (2022-06-16)** - Only support Python3.8, 3.9 and 3.10. - Add custom properties support. #2 diff --git a/MANIFEST.in b/MANIFEST.in index 90c2f9fd..eb96f5e2 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,4 @@ -include HISTORY.rst LICENSE README.rst tox.ini +include HISTORY.md LICENSE README.md tox.ini graft docx/templates graft features graft tests diff --git a/README.md b/README.md index c0e777ad..afcad358 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ License: MIT

---- ++++++++++++++++++++ ### FAQ @@ -16,6 +16,6 @@ **A:** [HISTORY](https://github.com/lsaint/python-docx-oss/blob/master/HISTORY.rst) ---- ++++++++++++++++++++ More information is available in the [python-docx documentation](https://python-docx.readthedocs.org/en/latest/) From f86ff5c8772f7e3197a31242b004ffb7939ba5fb Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 1 Jul 2022 12:01:07 +0800 Subject: [PATCH 032/115] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index afcad358..c0e777ad 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ License: MIT

-+++++++++++++++++++ +--- ### FAQ @@ -16,6 +16,6 @@ **A:** [HISTORY](https://github.com/lsaint/python-docx-oss/blob/master/HISTORY.rst) -+++++++++++++++++++ +--- More information is available in the [python-docx documentation](https://python-docx.readthedocs.org/en/latest/) From 8b7dc9862b37bfc675e010da6694e550f0df1d15 Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 4 Jul 2022 09:55:05 +0800 Subject: [PATCH 033/115] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c0e777ad..286c7c44 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ **Q: What's New?** -**A:** [HISTORY](https://github.com/lsaint/python-docx-oss/blob/master/HISTORY.rst) +**A:** [HISTORY](https://github.com/lsaint/python-docx-oss/blob/master/HISTORY.md) --- From 606aea5c95681fd7987938d9b6c5626a174edf73 Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 4 Jul 2022 09:58:48 +0800 Subject: [PATCH 034/115] Update LICENSE --- LICENSE | 1 + 1 file changed, 1 insertion(+) diff --git a/LICENSE b/LICENSE index 67ebe716..1d15a3f5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,6 @@ The MIT License (MIT) Copyright (c) 2013 Steve Canny, https://github.com/scanny +Copyright (c) 2022 Ethan St. Lee, https://github.com/lsaint Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 673429ef9d2bb270007e521f49c49cff97305c16 Mon Sep 17 00:00:00 2001 From: Ethan Date: Wed, 20 Jul 2022 17:06:04 +0800 Subject: [PATCH 035/115] Document (#16) * sphinx_rtd_theme * install * docx * sphinx_book_theme * doc --- docs/_templates/layout.html | 8 + docs/_templates/sidebarlinks.html | 6 +- docs/conf.py | 261 ++++------------------- docs/dev/analysis/features/coreprops.rst | 6 +- docs/index.rst | 13 +- docs/user/hdrftr.rst | 2 +- docs/user/install.rst | 28 +-- 7 files changed, 71 insertions(+), 253 deletions(-) create mode 100644 docs/_templates/layout.html diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html new file mode 100644 index 00000000..cf2b2cd0 --- /dev/null +++ b/docs/_templates/layout.html @@ -0,0 +1,8 @@ +{% extends "!layout.html" %} + {% block footer %} {{ super() }} + + + +{% endblock %} diff --git a/docs/_templates/sidebarlinks.html b/docs/_templates/sidebarlinks.html index 7f261bd7..a8d96dfb 100644 --- a/docs/_templates/sidebarlinks.html +++ b/docs/_templates/sidebarlinks.html @@ -1,6 +1,6 @@

Useful Links

diff --git a/docs/conf.py b/docs/conf.py index ceea9809..cd002151 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,16 +1,10 @@ -# -*- coding: utf-8 -*- +# Configuration file for the Sphinx documentation builder. # -# python-docx documentation build configuration file, created by -# sphinx-quickstart on Sat Jun 29 17:34:36 2013. -# -# This file is execfile()d with the current directory set to its containing -# dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- import os import sys @@ -18,49 +12,18 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. +# sys.path.insert(0, os.path.abspath("..")) from docx import __version__ # noqa +# -- Project information ----------------------------------------------------- -# -- General configuration --------------------------------------------------- - -# If your documentation needs a minimal Sphinx version, state it here. -# needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = [ - "sphinx.ext.autodoc", - "sphinx.ext.intersphinx", - "sphinx.ext.todo", - "sphinx.ext.coverage", - "sphinx.ext.viewcode", -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# The suffix of source filenames. -source_suffix = ".rst" - -# The encoding of source files. -# source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = "index" +project = "python-docx-oss" +copyright = "2022, Ethan St. Lee" +author = "Ethan St. Lee" -# General information about the project. -project = "python-docx" -copyright = "2013, Steve Canny" - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = __version__ -# The full version, including alpha/beta/rc tags. +# The full version, including alpha/beta/rc tags release = __version__ # A string of reStructuredText that will be included at the end of every source @@ -91,13 +54,15 @@ .. |CoreProperties| replace:: :class:`.CoreProperties` +.. |CustomProperties| replace:: :class:`.CustomProperties` + .. |datetime| replace:: :class:`.datetime.datetime` .. |Document| replace:: :class:`.Document` .. |DocumentPart| replace:: :class:`.DocumentPart` -.. |docx| replace:: ``python-docx`` +.. |docx| replace:: ``python-docx-oss`` .. |Emu| replace:: :class:`.Emu` @@ -190,194 +155,44 @@ .. |ValueError| replace:: :class:`ValueError` """ +# -- General configuration --------------------------------------------------- -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = [".build"] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -# default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -# add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -# add_module_names = True +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.intersphinx", + "sphinx.ext.todo", + "sphinx.ext.coverage", + "sphinx.ext.viewcode", +] -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -# show_authors = False +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = "sphinx" +# The root document. +root_doc = "index" -# A list of ignored prefixes for module index sorting. -# modindex_common_prefix = [] +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", ".build"] -# -- Options for HTML output ------------------------------------------------ +# -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = "armstrong" - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -html_theme_path = ["_themes"] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -# html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -# html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -# html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -# html_favicon = None +# +html_theme = "sphinx_book_theme" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ["_static"] -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -# html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -# html_use_smartypants = True - # Custom sidebar templates, maps document names to template names. -# html_sidebars = {} html_sidebars = { - "**": ["localtoc.html", "relations.html", "sidebarlinks.html", "searchbox.html"] -} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -# html_additional_pages = {} - -# If false, no module index is generated. -# html_domain_indices = True - -# If false, no index is generated. -# html_use_index = True - -# If true, the index is split into individual pages for each letter. -# html_split_index = False - -# If true, links to the reST sources are added to the pages. -# html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -# html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -# html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -# html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -# html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = "python-docxdoc" - - -# -- Options for LaTeX output ----------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # 'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). - # 'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. - # 'preamble': '', + "**": ["searchbox.html", "globaltoc.html", "sidebarlinks.html"], } - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, -# target name, -# title, -# author, -# documentclass [howto/manual]). -latex_documents = [ - ("index", "python-docx.tex", "python-docx Documentation", "Steve Canny", "manual"), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -# latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -# latex_use_parts = False - -# If true, show page references after internal links. -# latex_show_pagerefs = False - -# If true, show URL addresses after external links. -# latex_show_urls = False - -# Documents to append as an appendix to all manuals. -# latex_appendices = [] - -# If false, no module index is generated. -# latex_domain_indices = True - - -# -- Options for manual page output ----------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [("index", "python-docx", "python-docx Documentation", ["Steve Canny"], 1)] - -# If true, show URL addresses after external links. -# man_show_urls = False - - -# -- Options for Texinfo output --------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ( - "index", - "python-docx", - "python-docx Documentation", - "Steve Canny", - "python-docx", - "One line description of project.", - "Miscellaneous", - ), -] - -# Documents to append as an appendix to all manuals. -# texinfo_appendices = [] - -# If false, no module index is generated. -# texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -# texinfo_show_urls = 'footnote' - - -# Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {"http://docs.python.org/3/": None} diff --git a/docs/dev/analysis/features/coreprops.rst b/docs/dev/analysis/features/coreprops.rst index d4100864..0bc4ac32 100644 --- a/docs/dev/analysis/features/coreprops.rst +++ b/docs/dev/analysis/features/coreprops.rst @@ -25,10 +25,10 @@ Candidate Protocol >>> document = Document() >>> core_properties = document.core_properties >>> core_properties.author - 'python-docx' - >>> core_properties.author = 'Brian' + 'python-docx-oss' + >>> core_properties.author = 'lsaint' >>> core_properties.author - 'Brian' + 'lsaint' Properties diff --git a/docs/index.rst b/docs/index.rst index cdb8b545..6de7593a 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,11 +1,14 @@ +.. python-docx-oss documentation master file, created by + sphinx-quickstart on Wed Jul 6 15:38:29 2022. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. -python-docx -=========== +Welcome to python-docx-oss's documentation! +=========================================== -Release v\ |version| (:ref:`Installation `) +Release v\ |release| (:ref:`Installation `) -*python-docx* is a Python library for creating and updating Microsoft Word -(.docx) files. +*python-docx-oss* is a Python library for CRUD Microsoft Word (.docx) files. What it can do diff --git a/docs/user/hdrftr.rst b/docs/user/hdrftr.rst index 040da7ad..95d77cec 100644 --- a/docs/user/hdrftr.rst +++ b/docs/user/hdrftr.rst @@ -80,7 +80,7 @@ A header with multiple "zones" is often accomplished using carefully placed tab The required tab-stops for a center and right-aligned "zone" are part of the ``Header`` and ``Footer`` styles in Word. If you're using a custom template rather than the -`python-docx` default, it probably makes sense to define that style in your template. +`python-docx-oss` default, it probably makes sense to define that style in your template. Inserted tab characters (``"\t"``) are used to separate left, center, and right-aligned header content:: diff --git a/docs/user/install.rst b/docs/user/install.rst index 49bbed0a..ea11dc81 100644 --- a/docs/user/install.rst +++ b/docs/user/install.rst @@ -3,36 +3,28 @@ Installing ========== -.. note:: python-docx versions 0.3.0 and later are not API-compatible with - prior versions. - -|docx| is hosted on PyPI, so installation is relatively simple, and just +|docx| is hosted on `PyPI `_, +so installation is relatively simple, and just depends on what installation utilities you have installed. |docx| may be installed with ``pip`` if you have it available:: - pip install python-docx - -|docx| can also be installed using ``easy_install``, although this is -discouraged:: - - easy_install python-docx + pip install python-docx-oss -If neither ``pip`` nor ``easy_install`` is available, it can be installed -manually by downloading the distribution from PyPI, unpacking the tarball, +It can be installed manually by downloading the distribution from PyPI, unpacking the tarball, and running ``setup.py``:: tar xvzf python-docx-{version}.tar.gz - cd python-docx-{version} + cd python-docx-oss-{version} python setup.py install -|docx| depends on the ``lxml`` package. Both ``pip`` and ``easy_install`` -will take care of satisfying those dependencies for you, but if you use this -last method you will need to install those yourself. +|docx| depends on the ``lxml`` package. +``pip`` will take care of satisfying those dependencies for you, +but if you use this last method you will need to install those yourself. Dependencies ------------ -* Python 2.6, 2.7, 3.3, or 3.4 -* lxml >= 2.3.2 +* Python 3.8, 3.9 or 3.10 +* lxml >= 4.6.5 From 1bfd838b5832c31a32febf323a24f22ec9a4d897 Mon Sep 17 00:00:00 2001 From: Ethan Date: Wed, 20 Jul 2022 17:11:47 +0800 Subject: [PATCH 036/115] Create .readthedocs.yaml --- .readthedocs.yaml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .readthedocs.yaml diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 00000000..05b3adc4 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,6 @@ +version: 2 + +build: + os: "ubuntu-20.04" + tools: + python: "3.10" From 2ddec66f1593e7cf8e4362e71c6b76a0328ca0b3 Mon Sep 17 00:00:00 2001 From: Ethan Date: Wed, 20 Jul 2022 17:18:33 +0800 Subject: [PATCH 037/115] Update .readthedocs.yaml --- .readthedocs.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 05b3adc4..666c1cca 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -4,3 +4,7 @@ build: os: "ubuntu-20.04" tools: python: "3.10" + +python: + install: + - requirements: requirements.txt From 0266bd7a2bdf3b7da8ec140fcd61d11373cafb3e Mon Sep 17 00:00:00 2001 From: Ethan Date: Wed, 20 Jul 2022 17:22:46 +0800 Subject: [PATCH 038/115] readthedocs requirements.txt --- .readthedocs.yaml | 4 ++-- docs/requirements.txt | 2 ++ requirements.txt | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 docs/requirements.txt diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 666c1cca..eb50d101 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -4,7 +4,7 @@ build: os: "ubuntu-20.04" tools: python: "3.10" - + python: install: - - requirements: requirements.txt + - requirements: docs/requirements.txt diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 00000000..a05f1071 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,2 @@ +lxml>=4.6.5 +sphinx-book-theme diff --git a/requirements.txt b/requirements.txt index dd248962..e88bfbe5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ behave>=1.2.6 flake8>=4.0.1 -lxml>=4.9.0 +lxml>=4.6.5 mock>=4.0.3 pyparsing>=2.4.7 pytest>=6.2.5 From c4499928cd64c39c3018fe562821a18997ed944d Mon Sep 17 00:00:00 2001 From: Ethan Date: Wed, 20 Jul 2022 17:27:43 +0800 Subject: [PATCH 039/115] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 286c7c44..83a49144 100644 --- a/README.md +++ b/README.md @@ -18,4 +18,4 @@ --- -More information is available in the [python-docx documentation](https://python-docx.readthedocs.org/en/latest/) +More information is available in the [python-docx-oss documentation](https://python-docx-oss.readthedocs.io/en/latest/) From c965a78eb49157047a504fd942e4cdc1c116eb3c Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 21 Jul 2022 10:22:45 +0800 Subject: [PATCH 040/115] delete item & docs (#17) * delete item & docs * add user/install.rst * test_delete_item --- docs/index.rst | 1 + docs/user/custom-xml.rst | 60 +++++++++++++++++++++++++++++++++++ docx/parts/customxml.py | 6 ++++ tests/parts/test_customxml.py | 9 ++++-- 4 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 docs/user/custom-xml.rst diff --git a/docs/index.rst b/docs/index.rst index 6de7593a..c983effe 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -84,6 +84,7 @@ User Guide user/styles-understanding user/styles-using user/shapes + user/custom-xml API Documentation diff --git a/docs/user/custom-xml.rst b/docs/user/custom-xml.rst new file mode 100644 index 00000000..0ca5f41c --- /dev/null +++ b/docs/user/custom-xml.rst @@ -0,0 +1,60 @@ +.. _custom-xml: + +Working with customXml +======================= + +As we know, Word documents are .zip files under the hook. +Can we add any file in a docx file? Literally yes. +After we unzip a docx file, We can add a ``customXml`` folder at the root of it, +which contains any XML files. Files in other formats and paths are invalid. +But it's enough for us to store custom data. +It can not be seen or modified in Word like ``CustomProperties``. + +python-docx-oss will create a default XML file in the folder if there are not. +Then developer can add/delete/modify items in it. + +eg:: + + from docx import Document + + document = Document() + cx = document.part.custom_xml_parts[0] + + cx.add_item("my_tag", "some_texts", foo="foo_attrib_value") + cx.add_item("your_tag", "a_word", bar="bar_attrib_value") + +2 new xml elements:: + + some_texts + a_word + +will be add to ``customXml/item1.xml`` + +you can retrieve it:: + + >>> cx.items[0].tag + my_tag + + >>> cx.items[0].text) + some_texts + + >>> cx.items[0].attrib["foo"] + foo_attrib_value + + >>> cx.items[1].tag + your_tag + + >>> cx.items[1].text) + a_word + + >>> cx.items[1].attrib["bar2"] + value2 + +or delete it:: + + >>> cx.delete_item(cx.items[0]) + +Be careful. Items are stored as a list, the index may change after deletion:: + + >>> cx.items[0].tag + your_tag diff --git a/docx/parts/customxml.py b/docx/parts/customxml.py index 944e8ca9..5597d4fa 100644 --- a/docx/parts/customxml.py +++ b/docx/parts/customxml.py @@ -59,3 +59,9 @@ def add_item(self, tag: str, text: str = "", **attrib): Add a child element to root. """ etree.SubElement(self.element, tag, **attrib).text = text + + def delete_item(self, item_element: etree._Element): + """ + Delete a item element. other nodes index may change after deletion. + """ + self.element.remove(item_element) diff --git a/tests/parts/test_customxml.py b/tests/parts/test_customxml.py index 335fef4a..9edb486b 100644 --- a/tests/parts/test_customxml.py +++ b/tests/parts/test_customxml.py @@ -18,11 +18,14 @@ def test_add_item(self, custom_xml_part): assert custom_xml_part.items[2].text == "my-text" assert custom_xml_part.items[2].attrib["my_attrib"] == "my_attrib_value" + def test_delete_item(self, custom_xml_part): + custom_xml_part.delete_item(custom_xml_part.items[0]) + assert custom_xml_part.items[0].tag == "bar" + assert len(custom_xml_part.items) == 1 + @pytest.fixture def custom_xml_part(self, mocker, default_xml): - return CustomXmlPart.default( - "default_file", CT.XML, default_xml, mocker.MagicMock() - ) + return CustomXmlPart.default("default_file", CT.XML, default_xml, mocker.MagicMock()) @pytest.fixture def default_xml(self): From e33c47c75f953506634bbcf6ac2c5fa46ed90fba Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 21 Jul 2022 10:47:41 +0800 Subject: [PATCH 041/115] 0.0.4 --- HISTORY.md | 4 ++++ Makefile | 2 +- docx/__init__.py | 2 +- setup.py | 3 ++- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index c1a9134f..6c5b1b79 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,10 @@ Release History --------------- +**0.0.4 (2022-7-21)** + +- public python-docx-oss docs @ readthedocs. +- add delete_item in CustomXmlPart. #17 **0.0.3 (2022-7-01)** diff --git a/Makefile b/Makefile index 99f6c4bc..69b1eb2a 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ cleandocs: $(MAKE) -C docs clean coverage: - py.test --cov-report term-missing --cov=docx tests/ + pytest --cov-report term-missing --cov=docx tests/ docs: $(MAKE) -C docs html diff --git a/docx/__init__.py b/docx/__init__.py index 95949849..9be9de2f 100644 --- a/docx/__init__.py +++ b/docx/__init__.py @@ -1,6 +1,6 @@ from docx.api import Document # noqa -__version__ = "0.0.3" +__version__ = "0.0.4" # register custom Part classes with opc package reader diff --git a/setup.py b/setup.py index b26f40c2..9e38746a 100644 --- a/setup.py +++ b/setup.py @@ -52,7 +52,7 @@ def text_of(relpath): "Topic :: Software Development :: Libraries", ] -LONG_DESCRIPTION = text_of("README.rst") + "\n\n" + text_of("HISTORY.rst") +LONG_DESCRIPTION = text_of("README.md") + "\n\n" + text_of("HISTORY.md") ZIP_SAFE = False @@ -62,6 +62,7 @@ def text_of(relpath): "description": DESCRIPTION, "keywords": KEYWORDS, "long_description": LONG_DESCRIPTION, + "long_description_content_type": "text/markdown", "author": AUTHOR, "author_email": AUTHOR_EMAIL, "url": URL, From 58851a0a9e4e799916c98e48db90669191cee3ab Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 21 Jul 2022 19:00:06 +0800 Subject: [PATCH 042/115] custom-properties.rst --- docs/index.rst | 1 + docs/user/custom-properties.rst | 31 +++++++++++++++++++++++++++++++ docs/user/custom-xml.rst | 7 ++++--- 3 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 docs/user/custom-properties.rst diff --git a/docs/index.rst b/docs/index.rst index c983effe..1270a643 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -84,6 +84,7 @@ User Guide user/styles-understanding user/styles-using user/shapes + user/custom-properties user/custom-xml diff --git a/docs/user/custom-properties.rst b/docs/user/custom-properties.rst new file mode 100644 index 00000000..5c45934a --- /dev/null +++ b/docs/user/custom-properties.rst @@ -0,0 +1,31 @@ + +.. _custom_properties: + +Working with custom properties +============================== +The custom properties can be accessed/modified by navigating to +File menu --> Properties --> Advanced properties --> Customization in Word. +These properties are stored in the ``/docProps/custom.xml`` file. + +we can CRUD them via python-docx-oss:: + + from docx import Document + document = Document() + + >>> print(document.custom_properties["not-exist-key"]) + None + + >>> document.custom_properties["bjj"] = "oss" + >>> print(document.custom_properties["bjj"]) + oss + + >>> document.custom_properties["bjj"] = "rnc" + >>> print(document.custom_properties["bjj"]) + rnc + + >>> document.custom_properties["bjj"] = None + >>> print(document.custom_properties["bjj"]) + None + +Be careful, users also can see & modify these properties in Word. +Use :ref:`customXml` if you need them hidden. diff --git a/docs/user/custom-xml.rst b/docs/user/custom-xml.rst index 0ca5f41c..adac9ad9 100644 --- a/docs/user/custom-xml.rst +++ b/docs/user/custom-xml.rst @@ -1,4 +1,4 @@ -.. _custom-xml: +.. _custom_xml: Working with customXml ======================= @@ -6,9 +6,10 @@ Working with customXml As we know, Word documents are .zip files under the hook. Can we add any file in a docx file? Literally yes. After we unzip a docx file, We can add a ``customXml`` folder at the root of it, -which contains any XML files. Files in other formats and paths are invalid. +which contains any .xml files. +Files with other extension and paths are invalid. But it's enough for us to store custom data. -It can not be seen or modified in Word like ``CustomProperties``. +It can not be seen or modified in Word like :ref:`CustomProperties`. python-docx-oss will create a default XML file in the folder if there are not. Then developer can add/delete/modify items in it. From 2b6aafafd5f6758f93128c76c8721320072e6c09 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 21 Jul 2022 19:11:50 +0800 Subject: [PATCH 043/115] custom_xml --- docs/user/custom-properties.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/user/custom-properties.rst b/docs/user/custom-properties.rst index 5c45934a..96972002 100644 --- a/docs/user/custom-properties.rst +++ b/docs/user/custom-properties.rst @@ -1,4 +1,3 @@ - .. _custom_properties: Working with custom properties @@ -28,4 +27,4 @@ we can CRUD them via python-docx-oss:: None Be careful, users also can see & modify these properties in Word. -Use :ref:`customXml` if you need them hidden. +Use :ref:`customXml` if you need them hidden. From 7fc03a4c7a8996e326bc2622f9f16f8249ab9bc2 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 22 Jul 2022 11:04:01 +0800 Subject: [PATCH 044/115] pyhton-docx-oss docs ref --- docs/conf.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/conf.py b/docs/conf.py index cd002151..07819c16 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -64,6 +64,8 @@ .. |docx| replace:: ``python-docx-oss`` +.. |python-docx-oss| replace:: ``python-docx-oss`` + .. |Emu| replace:: :class:`.Emu` .. |False| replace:: :class:`False` From 4ab84e7ce5c8e306404de87fbce74d8d6c7ab567 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 4 Aug 2022 15:56:30 +0800 Subject: [PATCH 045/115] fix-pr-custom-properties (#20) * fix-pr-custom-properties * remove useless codes --- docx/opc/customprops.py | 10 +++------- docx/opc/parts/customprops.py | 3 +-- docx/oxml/customprops.py | 17 ++++------------- tests/opc/test_customprops.py | 13 ++----------- 4 files changed, 10 insertions(+), 33 deletions(-) diff --git a/docx/opc/customprops.py b/docx/opc/customprops.py index 965bf255..8b1c6fe4 100644 --- a/docx/opc/customprops.py +++ b/docx/opc/customprops.py @@ -21,7 +21,7 @@ def __getitem__(self, item): if elm.tag == "{%s}i4" % NS_VT: try: return int(elm.text) - except Exception: + except ValueError: return elm.text elif elm.tag == "{%s}bool" % NS_VT: return elm.text == "1" @@ -38,9 +38,7 @@ def __setitem__(self, key, value): elmType = "i4" value = str(int(value)) prop = etree.SubElement(self._element, "property") - elm = etree.SubElement( - prop, "{%s}%s" % (NS_VT, elmType), nsmap={"vt": NS_VT} - ) + elm = etree.SubElement(prop, "{%s}%s" % (NS_VT, elmType), nsmap={"vt": NS_VT}) elm.text = value prop.set("name", key) prop.set("fmtid", "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}") @@ -58,6 +56,4 @@ def __len__(self): return len(self._element) def lookup(self, item): - return next( - (child for child in self._element if child.get("name") == item), None - ) + return next((child for child in self._element if child.get("name") == item), None) diff --git a/docx/opc/parts/customprops.py b/docx/opc/parts/customprops.py index d1e1f5f8..46ed44d1 100644 --- a/docx/opc/parts/customprops.py +++ b/docx/opc/parts/customprops.py @@ -58,5 +58,4 @@ def load(cls, partname, content_type, blob, package): def _new(cls, package): partname = PackURI("/docProps/custom.xml") content_type = CT.OPC_CUSTOM_PROPERTIES - customProperties = CT_CustomProperties.new() - return CustomPropertiesPart(partname, content_type, customProperties, package) + return CustomPropertiesPart(partname, content_type, CT_CustomProperties.new(), package) diff --git a/docx/oxml/customprops.py b/docx/oxml/customprops.py index 34b9f011..6e3c3c41 100644 --- a/docx/oxml/customprops.py +++ b/docx/oxml/customprops.py @@ -1,19 +1,12 @@ -# encoding: utf-8 - """ lxml custom element classes for core properties-related XML elements. """ - -from __future__ import absolute_import, division, print_function, unicode_literals - import re from datetime import datetime, timedelta -from lxml import etree - from . import parse_xml from .ns import nsdecls, qn -from .xmlchemy import BaseOxmlElement, ZeroOrOne +from .xmlchemy import BaseOxmlElement class CT_CustomProperties(BaseOxmlElement): @@ -34,8 +27,7 @@ def new(cls): Return a new ```` element """ xml = cls._customProperties_tmpl - customProperties = parse_xml(xml) - return customProperties + return parse_xml(xml) def _datetime_of_element(self, property_name): element = getattr(self, property_name) @@ -52,10 +44,9 @@ def _get_or_add(self, prop_name): """ Return element returned by 'get_or_add_' method for *prop_name*. """ - get_or_add_method_name = "get_or_add_%s" % prop_name + get_or_add_method_name = f"get_or_add_{prop_name}" get_or_add_method = getattr(self, get_or_add_method_name) - element = get_or_add_method() - return element + return get_or_add_method() @classmethod def _offset_dt(cls, dt, offset_str): diff --git a/tests/opc/test_customprops.py b/tests/opc/test_customprops.py index 1efae96e..e9c5c256 100644 --- a/tests/opc/test_customprops.py +++ b/tests/opc/test_customprops.py @@ -1,19 +1,10 @@ -# encoding: utf-8 - """ Unit test suite for the docx.opc.customprops module """ - -from __future__ import absolute_import, division, print_function, unicode_literals - import pytest -from datetime import datetime - from docx.opc.customprops import CustomProperties -from docx.oxml.customprops import CT_CustomProperties from docx.oxml import parse_xml -from lxml import etree class DescribeCustomProperties(object): @@ -53,12 +44,12 @@ def prop_get_fixture(self, request, custom_properties_default): ) def prop_set_fixture(self, request, custom_properties_blank): prop_name, str_type, str_value, value = request.param - expected_xml = self.customProperties(prop_name, str_type, str_value) + expected_xml = self.custom_properties(prop_name, str_type, str_value) return custom_properties_blank, prop_name, value, expected_xml # fixture components --------------------------------------------- - def customProperties(self, prop_name, str_type, str_value): + def custom_properties(self, prop_name, str_type, str_value): tmpl = ( '\n' From 9797cf1c080622ca4c2cbf7c4ccff5f84369ad76 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 4 Aug 2022 17:52:56 +0800 Subject: [PATCH 046/115] README.md oss --- README.md | 5 ++++- docs/_static/img/oss.png | Bin 0 -> 319228 bytes 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 docs/_static/img/oss.png diff --git a/README.md b/README.md index 83a49144..95f46545 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ -**_python-docx-oss_** is a Python library for CRUD Microsoft Word (.docx) files. +oss + +**As a Brazilian jiu-jitsu player, OSS means anything and everything. It’s a term used in BJJ that is a way of greeting and demonstrating respect to others.** +**_python-docx-oss_** is a Python library for CRUD Microsoft Word (.docx) files.

PyPI diff --git a/docs/_static/img/oss.png b/docs/_static/img/oss.png new file mode 100644 index 0000000000000000000000000000000000000000..462e3c4975675ba2321ec44759ecc6c2f2906563 GIT binary patch literal 319228 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

L{xCZ2N<>OE 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 VT?8TT?f_m!24- literal 0 HcmV?d00001 From ea8040795845aa2ad82c46b940416c719d3e903b Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 4 Aug 2022 18:02:41 +0800 Subject: [PATCH 047/115] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 95f46545..f8b889f8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ -oss +

+oss +

-**As a Brazilian jiu-jitsu player, OSS means anything and everything. It’s a term used in BJJ that is a way of greeting and demonstrating respect to others.** +*As a Brazilian jiu-jitsu player, OSS means anything and everything. It’s a term used in BJJ that is a way of greeting and demonstrating respect to others.* **_python-docx-oss_** is a Python library for CRUD Microsoft Word (.docx) files. From 515e11fc8ba36bb5d18e7c9fe05706c6730385e8 Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 8 Aug 2022 10:15:29 +0800 Subject: [PATCH 048/115] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f8b889f8..30ed1ef6 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ *As a Brazilian jiu-jitsu player, OSS means anything and everything. It’s a term used in BJJ that is a way of greeting and demonstrating respect to others.* -**_python-docx-oss_** is a Python library for CRUD Microsoft Word (.docx) files. +**_python-docx-oss_** is a Python library for CRUD Microsoft Word (.docx) files. It fork from [python-docx](https://github.com/python-openxml/python-docx). +

PyPI From c97dbb8b4589d3c78c0e70bedc155e1c5964ecdb Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 8 Aug 2022 11:27:32 +0800 Subject: [PATCH 049/115] add float picture (#21) * add float picture * black * test it_can_add_a_float_picture --- docx/document.py | 12 +++++--- docx/oxml/__init__.py | 2 ++ docx/oxml/shape.py | 70 ++++++++++++++++++++++++++++++++++++++++-- docx/parts/story.py | 19 ++++++++---- docx/text/run.py | 6 ++++ tests/test_document.py | 38 ++++++++++++++++++----- 6 files changed, 126 insertions(+), 21 deletions(-) diff --git a/docx/document.py b/docx/document.py index 8bdd5da1..aeb3370b 100644 --- a/docx/document.py +++ b/docx/document.py @@ -1,9 +1,4 @@ -# encoding: utf-8 - """|Document| and closely related objects""" - -from __future__ import absolute_import, division, print_function, unicode_literals - from docx.blkcntnr import BlockItemContainer from docx.enum.section import WD_SECTION from docx.enum.text import WD_BREAK @@ -71,6 +66,13 @@ def add_picture(self, image_path_or_stream, width=None, height=None): run = self.add_paragraph().add_run() return run.add_picture(image_path_or_stream, width, height) + def add_float_picture(self, image_path_or_stream, width=None, height=None, pos_x=0, pos_y=0): + """ + Add float picture at fixed position `pos_x` and `pos_y` to the top-left point of page. + """ + run = self.add_paragraph().add_run() + return run.add_float_picture(image_path_or_stream, width, height, pos_x, pos_y) + def add_section(self, start_type=WD_SECTION.NEW_PAGE): """ Return a |Section| object representing a new section added at the end diff --git a/docx/oxml/__init__.py b/docx/oxml/__init__.py index 25994bf4..62043fa7 100644 --- a/docx/oxml/__init__.py +++ b/docx/oxml/__init__.py @@ -117,6 +117,7 @@ def OxmlElement(nsptag_str, attrs=None, nsdecls=None): from .shape import CT_GraphicalObject # noqa from .shape import ( + CT_Anchor, CT_Blip, CT_BlipFillProperties, CT_GraphicalObjectData, @@ -144,6 +145,7 @@ def OxmlElement(nsptag_str, attrs=None, nsdecls=None): register_element_cls("wp:docPr", CT_NonVisualDrawingProps) register_element_cls("wp:extent", CT_PositiveSize2D) register_element_cls("wp:inline", CT_Inline) +register_element_cls("wp:anchor", CT_Anchor) from .styles import CT_LatentStyles, CT_LsdException, CT_Style, CT_Styles # noqa diff --git a/docx/oxml/shape.py b/docx/oxml/shape.py index 885535c7..b195210a 100644 --- a/docx/oxml/shape.py +++ b/docx/oxml/shape.py @@ -1,10 +1,10 @@ -# encoding: utf-8 - """ Custom element classes for shape-related elements like ```` """ +from docx.oxml import parse_xml +from docx.oxml.ns import nsdecls +from docx.oxml.xmlchemy import BaseOxmlElement, OneAndOnlyOne -from . import parse_xml from .ns import nsdecls from .simpletypes import ( ST_Coordinate, @@ -308,3 +308,67 @@ def cy(self): def cy(self, value): ext = self.get_or_add_ext() ext.cy = value + + +class CT_Anchor(BaseOxmlElement): + """ + ```` element, container for a floating image. + """ + + extent = OneAndOnlyOne("wp:extent") + docPr = OneAndOnlyOne("wp:docPr") + graphic = OneAndOnlyOne("a:graphic") + + @classmethod + def new(cls, cx, cy, shape_id, pic, pos_x, pos_y): + """ + Return a new ```` element populated with the values passed + as parameters. + """ + anchor = parse_xml(cls._anchor_xml(pos_x, pos_y)) + anchor.extent.cx = cx + anchor.extent.cy = cy + anchor.docPr.id = shape_id + anchor.docPr.name = "Picture %d" % shape_id + anchor.graphic.graphicData.uri = ( + "http://schemas.openxmlformats.org/drawingml/2006/picture" + ) + anchor.graphic.graphicData._insert_pic(pic) + return anchor + + @classmethod + def new_pic_anchor(cls, shape_id, rId, filename, cx, cy, pos_x, pos_y): + """ + Return a new `wp:anchor` element containing the `pic:pic` element + specified by the argument values. + """ + pic_id = 0 # Word doesn't seem to use this, but does not omit it + pic = CT_Picture.new(pic_id, filename, rId, cx, cy) + anchor = cls.new(cx, cy, shape_id, pic, pos_x, pos_y) + anchor.graphic.graphicData._insert_pic(pic) + return anchor + + @classmethod + def _anchor_xml(cls, pos_x, pos_y): + return ( + '\n" + ' \n' + ' \n' + " %d\n" + " \n" + ' \n' + " %d\n" + " \n" + ' \n' + " \n" + ' \n' + " \n" + ' \n' + " \n" + " \n" + ' \n' + " \n" + "" % (nsdecls("wp", "a", "pic", "r"), int(pos_x), int(pos_y)) + ) diff --git a/docx/parts/story.py b/docx/parts/story.py index 49cfa396..8d48ec70 100644 --- a/docx/parts/story.py +++ b/docx/parts/story.py @@ -1,12 +1,7 @@ -# encoding: utf-8 - """|BaseStoryPart| and related objects""" - -from __future__ import absolute_import, division, print_function, unicode_literals - from docx.opc.constants import RELATIONSHIP_TYPE as RT from docx.opc.part import XmlPart -from docx.oxml.shape import CT_Inline +from docx.oxml.shape import CT_Anchor, CT_Inline from docx.shared import lazyproperty @@ -58,6 +53,18 @@ def new_pic_inline(self, image_descriptor, width, height): shape_id, filename = self.next_id, image.filename return CT_Inline.new_pic_inline(shape_id, rId, filename, cx, cy) + def new_pic_anchor(self, image_descriptor, width, height, pos_x, pos_y): + """Return a newly-created `w:anchor` element. + + The element contains the image specified by *image_descriptor* and is scaled + based on the values of *width* and *height*. + """ + rId, image = self.get_or_add_image(image_descriptor) + cx, cy = image.scaled_dimensions(width, height) + print(width, height, cx, cy) + shape_id, filename = self.next_id, image.filename + return CT_Anchor.new_pic_anchor(shape_id, rId, filename, cx, cy, pos_x, pos_y) + @property def next_id(self): """Next available positive integer id value in this story XML document. diff --git a/docx/text/run.py b/docx/text/run.py index 51926d87..10b58bd9 100644 --- a/docx/text/run.py +++ b/docx/text/run.py @@ -59,6 +59,12 @@ def add_picture(self, image_path_or_stream, width=None, height=None): self._r.add_drawing(inline) return InlineShape(inline) + def add_float_picture(self, image_path_or_stream, width=None, height=None, pos_x=0, pos_y=0): + """Add float picture at fixed position `pos_x` and `pos_y` to the top-left point of page.""" + anchor = self.part.new_pic_anchor(image_path_or_stream, width, height, pos_x, pos_y) + self._r.add_drawing(anchor) + return anchor + def add_tab(self): """ Add a ```` element at the end of the run, which Word diff --git a/tests/test_document.py b/tests/test_document.py index 27f17f97..3e61d943 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -1,15 +1,11 @@ -# encoding: utf-8 - """Unit test suite for the docx.document module""" - -from __future__ import absolute_import, division, print_function, unicode_literals - import pytest -from docx.document import _Body, Document +from docx.document import Document, _Body from docx.enum.section import WD_SECTION from docx.enum.text import WD_BREAK from docx.opc.coreprops import CoreProperties +from docx.oxml.shape import CT_Anchor from docx.parts.document import DocumentPart from docx.section import Section, Sections from docx.settings import Settings @@ -21,7 +17,8 @@ from docx.text.run import Run from .unitutil.cxml import element, xml -from .unitutil.mock import class_mock, instance_mock, method_mock, property_mock +from .unitutil.mock import (class_mock, instance_mock, method_mock, + property_mock) class DescribeDocument(object): @@ -66,6 +63,21 @@ def it_can_add_a_picture(self, add_picture_fixture): run_.add_picture.assert_called_once_with(path, width, height) assert picture is picture_ + def it_can_add_a_float_picture(self, add_float_picture_fixture): + ( + document, + path, + width, + height, + pos_x, + pos_y, + run_, + float_picture_, + ) = add_float_picture_fixture + anchor = document.add_float_picture(path, width, height, pos_x, pos_y) + run_.add_float_picture.assert_called_once_with(path, width, height, pos_x, pos_y) + assert anchor is float_picture_ + def it_can_add_a_section( self, add_section_fixture, Section_, section_, document_part_ ): @@ -180,6 +192,14 @@ def add_picture_fixture(self, request, add_paragraph_, run_, picture_): run_.add_picture.return_value = picture_ return document, path, width, height, run_, picture_ + @pytest.fixture + def add_float_picture_fixture(self, add_paragraph_, run_, float_picture_): + document = Document(None, None) + path, width, height, pos_x, pos_y = "foobar.png", 100, 200, 100000, 200000 + add_paragraph_.return_value.add_run.return_value = run_ + run_.add_float_picture.return_value = float_picture_ + return document, path, width, height, pos_x, pos_y, run_, float_picture_ + @pytest.fixture( params=[ ("w:sectPr", WD_SECTION.EVEN_PAGE, "w:sectPr/w:type{w:val=evenPage}"), @@ -317,6 +337,10 @@ def paragraphs_(self, request): def picture_(self, request): return instance_mock(request, InlineShape) + @pytest.fixture + def float_picture_(self, request): + return instance_mock(request, CT_Anchor) + @pytest.fixture def run_(self, request): return instance_mock(request, Run) From b90e31ad1296f17010d24275a56193b460a82c11 Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 8 Aug 2022 11:29:54 +0800 Subject: [PATCH 050/115] 0.0.5 --- HISTORY.md | 6 ++++++ docx/__init__.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 6c5b1b79..88acb5e5 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,12 @@ Release History --------------- +**0.0.5 (2022-8-08)** + +- minor refactor custom-properties +- add add_float_picture in Document #21 + + **0.0.4 (2022-7-21)** - public python-docx-oss docs @ readthedocs. diff --git a/docx/__init__.py b/docx/__init__.py index 9be9de2f..70487392 100644 --- a/docx/__init__.py +++ b/docx/__init__.py @@ -1,6 +1,6 @@ from docx.api import Document # noqa -__version__ = "0.0.4" +__version__ = "0.0.5" # register custom Part classes with opc package reader From 31c75655e3af9b90fe321c789c30a67b6e540eda Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 8 Aug 2022 14:19:40 +0800 Subject: [PATCH 051/115] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 30ed1ef6..9f4eab97 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

-oss +oss

*As a Brazilian jiu-jitsu player, OSS means anything and everything. It’s a term used in BJJ that is a way of greeting and demonstrating respect to others.* From dea8690b7ff1ac1015c5c9d601bd7520f6da14d6 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 21 Oct 2022 11:33:03 +0800 Subject: [PATCH 052/115] change default custom xml file name to item1 (#23) * change xml name to item1 * 0.0.6rc2 --- HISTORY.md | 9 +++++++-- docx/__init__.py | 2 +- docx/parts/document.py | 2 +- docx/parts/story.py | 1 - 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 88acb5e5..5788341f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,10 +1,15 @@ Release History --------------- +**0.0.6 (2022-10-21)** + +- change default custom xml file name to item1. #23 + + **0.0.5 (2022-8-08)** -- minor refactor custom-properties -- add add_float_picture in Document #21 +- minor refactor custom-properties. +- add add_float_picture in Document. #21 **0.0.4 (2022-7-21)** diff --git a/docx/__init__.py b/docx/__init__.py index 70487392..cd71e7a2 100644 --- a/docx/__init__.py +++ b/docx/__init__.py @@ -1,6 +1,6 @@ from docx.api import Document # noqa -__version__ = "0.0.5" +__version__ = "0.0.6rc2" # register custom Part classes with opc package reader diff --git a/docx/parts/document.py b/docx/parts/document.py index f5a65428..cef39b95 100644 --- a/docx/parts/document.py +++ b/docx/parts/document.py @@ -63,7 +63,7 @@ def custom_xml_parts(self) -> list[CustomXmlPart]: return [] def add_custom_xml_part( - self, xml: str, file_name: str = "item", content_type: str = CT.XML + self, xml: str, file_name: str = "item1", content_type: str = CT.XML ) -> CustomXmlPart: """ Add a file in /customXml/*file_name*.xml with default content *xml* diff --git a/docx/parts/story.py b/docx/parts/story.py index 8d48ec70..b23d2d36 100644 --- a/docx/parts/story.py +++ b/docx/parts/story.py @@ -61,7 +61,6 @@ def new_pic_anchor(self, image_descriptor, width, height, pos_x, pos_y): """ rId, image = self.get_or_add_image(image_descriptor) cx, cy = image.scaled_dimensions(width, height) - print(width, height, cx, cy) shape_id, filename = self.next_id, image.filename return CT_Anchor.new_pic_anchor(shape_id, rId, filename, cx, cy, pos_x, pos_y) From 38391e1c781c4f615a67ec90eaba94041bb9bdcc Mon Sep 17 00:00:00 2001 From: Liu Liqiu Date: Mon, 24 Oct 2022 16:25:47 +0800 Subject: [PATCH 053/115] add emf image file support (#24) * add emf image file support --- docx/image/__init__.py | 2 ++ docx/image/constants.py | 1 + docx/image/emf.py | 46 +++++++++++++++++++++++++++++++++++++++++ tests/image/test_emf.py | 38 ++++++++++++++++++++++++++++++++++ 4 files changed, 87 insertions(+) create mode 100644 docx/image/emf.py create mode 100644 tests/image/test_emf.py diff --git a/docx/image/__init__.py b/docx/image/__init__.py index e8523454..43683946 100644 --- a/docx/image/__init__.py +++ b/docx/image/__init__.py @@ -12,6 +12,7 @@ from docx.image.jpeg import Exif, Jfif from docx.image.png import Png from docx.image.tiff import Tiff +from docx.image.emf import Emf SIGNATURES = ( @@ -24,4 +25,5 @@ (Tiff, 0, b"MM\x00*"), # big-endian (Motorola) TIFF (Tiff, 0, b"II*\x00"), # little-endian (Intel) TIFF (Bmp, 0, b"BM"), + (Emf, 0, b"\x01\x00\x00\x00"), ) diff --git a/docx/image/constants.py b/docx/image/constants.py index e4fa17fb..8c414354 100644 --- a/docx/image/constants.py +++ b/docx/image/constants.py @@ -113,6 +113,7 @@ class MIME_TYPE(object): JPEG = "image/jpeg" PNG = "image/png" TIFF = "image/tiff" + EMF = "image/emf" class PNG_CHUNK_TYPE(object): diff --git a/docx/image/emf.py b/docx/image/emf.py new file mode 100644 index 00000000..96806751 --- /dev/null +++ b/docx/image/emf.py @@ -0,0 +1,46 @@ +# encoding: utf-8 + +from .constants import MIME_TYPE +from .helpers import LITTLE_ENDIAN, StreamReader +from .image import BaseImageHeader + + +class Emf(BaseImageHeader): + """ + Image header parser for EMF images + """ + + @property + def content_type(self): + """ + MIME content type for this image, unconditionally `image/png` for + EMF images. + """ + return MIME_TYPE.EMF + + @property + def default_ext(self): + """ + Default filename extension, always 'emf' for EMF images. + """ + return "emf" + + @classmethod + def from_stream(cls, stream): + """ + Return a |Emf| instance having header properties parsed from image in + *stream*. + """ + stream_rdr = StreamReader(stream, LITTLE_ENDIAN) + x0 = stream_rdr.read_long(8) + y0 = stream_rdr.read_long(12) + x1 = stream_rdr.read_long(16) + y1 = stream_rdr.read_long(20) + + frame = tuple(map(stream_rdr.read_long, (24, 28, 32, 36))) + size = x1 - x0, y1 - y0 + + xdpi = 2540.0 * (x1 - x0) / (frame[2] - frame[0]) + ydpi = 2540.0 * (y1 - y0) / (frame[3] - frame[1]) + + return cls(x1 - x0, y1 - y0, xdpi, ydpi) diff --git a/tests/image/test_emf.py b/tests/image/test_emf.py new file mode 100644 index 00000000..3fb1453f --- /dev/null +++ b/tests/image/test_emf.py @@ -0,0 +1,38 @@ +# encoding: utf-8 + +"""Unit test suite for docx.image.emf module""" + +import pytest + +from docx.compat import BytesIO +from docx.image.constants import MIME_TYPE +from docx.image.emf import Emf + +from ..unitutil.mock import ANY, initializer_mock + + +class DescribeEmf(object): + def it_can_construct_from_a_emf_stream(self, Emf__init__): + cx, cy = 69, 69 + h_dpi, v_dpi = 2540.0, 2540.0 + bytes_ = b"\x01\x00\x00\x00l\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\x00\x00\x00E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\x00\x00\x00E\x00\x00\x00" + stream = BytesIO(bytes_) + + emf = Emf.from_stream(stream) + + Emf__init__.assert_called_once_with(ANY, cx, cy, h_dpi, v_dpi) + assert isinstance(emf, Emf) + + def it_knows_its_content_type(self): + emf = Emf(None, None, None, None) + assert emf.content_type == MIME_TYPE.EMF + + def it_knows_its_default_ext(self): + emf = Emf(None, None, None, None) + assert emf.default_ext == "emf" + + # fixture components --------------------------------------------- + + @pytest.fixture + def Emf__init__(self, request): + return initializer_mock(request, Emf) From 0247e20f262f8da58c611998c62287fa6c54bfd6 Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 24 Oct 2022 16:28:18 +0800 Subject: [PATCH 054/115] 0.0.7 --- HISTORY.md | 5 +++++ docx/__init__.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 5788341f..208dc571 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,11 @@ Release History --------------- +**0.0.7 (2022-10-29)** + +- add emf image file support. #24 + + **0.0.6 (2022-10-21)** - change default custom xml file name to item1. #23 diff --git a/docx/__init__.py b/docx/__init__.py index cd71e7a2..bdbabd04 100644 --- a/docx/__init__.py +++ b/docx/__init__.py @@ -1,6 +1,6 @@ from docx.api import Document # noqa -__version__ = "0.0.6rc2" +__version__ = "0.0.7" # register custom Part classes with opc package reader From 86bdddf27ca3d4493d40add358264780da2ff262 Mon Sep 17 00:00:00 2001 From: Ethan Date: Wed, 11 Jan 2023 16:59:00 +0800 Subject: [PATCH 055/115] add python3.11 and remove 3.8 3.9 --- setup.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 9e38746a..64ba61be 100644 --- a/setup.py +++ b/setup.py @@ -45,9 +45,8 @@ def text_of(relpath): "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Topic :: Office/Business :: Office Suites", "Topic :: Software Development :: Libraries", ] From d1dae187ce24108cdf87a385c72218f40b4ec74b Mon Sep 17 00:00:00 2001 From: Ethan Date: Wed, 11 Jan 2023 17:24:39 +0800 Subject: [PATCH 056/115] version 0.0.8 --- docx/__init__.py | 2 +- setup.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docx/__init__.py b/docx/__init__.py index bdbabd04..189315c4 100644 --- a/docx/__init__.py +++ b/docx/__init__.py @@ -1,6 +1,6 @@ from docx.api import Document # noqa -__version__ = "0.0.7" +__version__ = "0.0.8" # register custom Part classes with opc package reader diff --git a/setup.py b/setup.py index 64ba61be..e994881f 100644 --- a/setup.py +++ b/setup.py @@ -26,8 +26,8 @@ def text_of(relpath): NAME = "python-docx-oss" VERSION = version -DESCRIPTION = "Create and update Microsoft Word .docx files." -KEYWORDS = "docx office openxml word python-docx" +DESCRIPTION = "CRUD Microsoft Word .docx files." +KEYWORDS = "docx office openxml word python-docx-oss" AUTHOR = "Ethan St. Lee" AUTHOR_EMAIL = "ethan@ginolegaltech.cn" URL = "https://github.com/lsaint/python-docx-oss" @@ -40,7 +40,7 @@ def text_of(relpath): TESTS_REQUIRE = ["behave", "mock", "pyparsing", "pytest"] CLASSIFIERS = [ - "Development Status :: 3 - Alpha", + "Development Status :: 3 - Beta", "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", From 0bedff69047d966cd199d332a05919eb880e3fd0 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 12 Jan 2023 10:41:42 +0800 Subject: [PATCH 057/115] +WARNING for customXml --- docs/user/custom-xml.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/user/custom-xml.rst b/docs/user/custom-xml.rst index adac9ad9..72bd8b05 100644 --- a/docs/user/custom-xml.rst +++ b/docs/user/custom-xml.rst @@ -14,6 +14,11 @@ It can not be seen or modified in Word like :ref:`CustomProperties` in this circumstance. + eg:: from docx import Document From 62dcf492d74ea87f250b0e0cf3c164fab93c476b Mon Sep 17 00:00:00 2001 From: Ethan Date: Tue, 26 Sep 2023 10:14:52 +0800 Subject: [PATCH 058/115] typo --- docx/image/emf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docx/image/emf.py b/docx/image/emf.py index 96806751..771c549f 100644 --- a/docx/image/emf.py +++ b/docx/image/emf.py @@ -13,7 +13,7 @@ class Emf(BaseImageHeader): @property def content_type(self): """ - MIME content type for this image, unconditionally `image/png` for + MIME content type for this image, unconditionally `image/emf` for EMF images. """ return MIME_TYPE.EMF From 126b54a4b3b053edd1e250d2e734f1141896973d Mon Sep 17 00:00:00 2001 From: 08600rr <08600rr@users.noreply.github.com> Date: Thu, 21 Nov 2024 15:01:42 +0800 Subject: [PATCH 059/115] Update README.md (#26) Replace the character ' in "It's a term used in ..." --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9f4eab97..c90ec55a 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ oss

-*As a Brazilian jiu-jitsu player, OSS means anything and everything. It’s a term used in BJJ that is a way of greeting and demonstrating respect to others.* +*As a Brazilian jiu-jitsu player, OSS means anything and everything. It's a term used in BJJ that is a way of greeting and demonstrating respect to others.* **_python-docx-oss_** is a Python library for CRUD Microsoft Word (.docx) files. It fork from [python-docx](https://github.com/python-openxml/python-docx). From 05181c18eb395a718df0facc09127c2973ed609b Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 21 Nov 2024 15:41:17 +0800 Subject: [PATCH 060/115] py3.12 3.13 --- setup.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup.py b/setup.py index e994881f..6e6dccf4 100644 --- a/setup.py +++ b/setup.py @@ -47,6 +47,8 @@ def text_of(relpath): "Operating System :: OS Independent", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Topic :: Office/Business :: Office Suites", "Topic :: Software Development :: Libraries", ] From 4c37607ff6c8043f5d76b5cc80b2356ed891de69 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 21 Nov 2024 15:42:54 +0800 Subject: [PATCH 061/115] gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index a15d9208..f400bd3f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +local.txt .coverage /dist/ /docs/.build/ From 012a24578e8a8433cf0ffd63686e8b8006c919d5 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 21 Nov 2024 16:09:42 +0800 Subject: [PATCH 062/115] separate requirements --- requirements-dev.txt | 5 +++++ requirements.txt | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 requirements-dev.txt diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 00000000..8f8ccd2b --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,5 @@ +behave>=1.2.6 +flake8>=4.0.1 +mock>=4.0.3 +pytest>=6.2.5 +pytest-mock>=3.7.0 diff --git a/requirements.txt b/requirements.txt index e88bfbe5..9b000afc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,2 @@ -behave>=1.2.6 -flake8>=4.0.1 lxml>=4.6.5 -mock>=4.0.3 pyparsing>=2.4.7 -pytest>=6.2.5 -pytest-mock>=3.7.0 From 0d039560076669e34faf9e3b9035e1e8dbfedb40 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 22 Nov 2024 09:41:15 +0800 Subject: [PATCH 063/115] make build --- Makefile | 6 +++--- requirements-dev.txt | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 69b1eb2a..d1f057b3 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ PYTHON = python TWINE = twine SETUP = $(PYTHON) ./setup.py -.PHONY: accept clean coverage docs readme register sdist test upload +.PHONY: accept clean coverage docs readme register build test upload help: @echo "Please use \`make ' where is one or more of" @@ -15,7 +15,7 @@ help: @echo " docs generate documentation" @echo " opendocs open browser to local version of documentation" @echo " register update metadata (README.rst) on PyPI" - @echo " sdist generate a source distribution into dist/" + @echo " build generate a source distribution into dist/" @echo " upload upload distribution tarball to PyPI" accept: @@ -40,7 +40,7 @@ opendocs: register: $(SETUP) register -sdist: +build: $(SETUP) sdist upload: diff --git a/requirements-dev.txt b/requirements-dev.txt index 8f8ccd2b..da1066f0 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,3 +1,5 @@ +setuptools +twine behave>=1.2.6 flake8>=4.0.1 mock>=4.0.3 From 04d0581024a10e9edb54fee5f196f174d69acca5 Mon Sep 17 00:00:00 2001 From: shin1007 <51842098+shin1007@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:48:45 +0900 Subject: [PATCH 064/115] EastAsia font support fixes (#25) * Fix typo: "the the" #688 * eastAsia font support with test * fixed typo * fixed typo and added 2 tests * now font.name returns dictionary(ascii, hAnsi, eastAsia) * enabled eastAsia font * fixed typo * updated docstring accordingly --- docs/dev/analysis/features/text/font.rst | 14 +++++++----- docx/image/constants.py | 2 +- docx/image/exceptions.py | 2 +- docx/oxml/text/font.py | 22 +++++++++++++++++++ docx/text/font.py | 27 ++++++++++++++++++----- tests/text/test_font.py | 28 +++++++++++++++++------- 6 files changed, 73 insertions(+), 22 deletions(-) diff --git a/docs/dev/analysis/features/text/font.rst b/docs/dev/analysis/features/text/font.rst index 1682b5c7..0c48f439 100644 --- a/docs/dev/analysis/features/text/font.rst +++ b/docs/dev/analysis/features/text/font.rst @@ -40,19 +40,21 @@ be used. Protocol ~~~~~~~~ -Initially, only the base typeface name is supported by the API, using the -:attr:`~.Font.name` property. Its value is the that of the `w:rFonts/@w:ascii` -attribute or |None| if not present. Assignment to this property sets both the -`w:ascii` and the `w:hAnsi` attribute to the assigned string or removes them -both if |None| is assigned:: +Assignment to name property sets all of the +`w:ascii`, `w:hAnsi`, and the `w:eastAsia` attribute to the assigned string or removes them +all if |None| is assigned:: >>> font = document.styles['Normal'].font >>> font.name None >>> font.name = 'Arial' >>> font.name - 'Arial' + {'ascii':'Arial', 'hAnsi': 'Arial', 'eastAsia': 'Arial'} +You can set one or some of name attributes by using *dict* type:: + >>> font.name = {'ascii':'Arial', 'hAnsi': 'Arial', 'eastAsia': 'MS Gothic'} + >>> font.name + {'ascii':'Arial', 'hAnsi': 'Arial', 'eastAsia': 'MS Gothic'} Boolean run properties ---------------------- diff --git a/docx/image/constants.py b/docx/image/constants.py index 8c414354..a27e8521 100644 --- a/docx/image/constants.py +++ b/docx/image/constants.py @@ -1,7 +1,7 @@ # encoding: utf-8 """ -Constants specific the the image sub-package +Constants specific to the image sub-package """ diff --git a/docx/image/exceptions.py b/docx/image/exceptions.py index f233edc4..c45fc6d9 100644 --- a/docx/image/exceptions.py +++ b/docx/image/exceptions.py @@ -1,7 +1,7 @@ # encoding: utf-8 """ -Exceptions specific the the image sub-package +Exceptions specific to the image sub-package """ diff --git a/docx/oxml/text/font.py b/docx/oxml/text/font.py index 73913af9..068d7e1f 100644 --- a/docx/oxml/text/font.py +++ b/docx/oxml/text/font.py @@ -30,6 +30,7 @@ class CT_Fonts(BaseOxmlElement): ascii = OptionalAttribute("w:ascii", ST_String) hAnsi = OptionalAttribute("w:hAnsi", ST_String) + eastAsia = OptionalAttribute("w:eastAsia", ST_String) class CT_Highlight(BaseOxmlElement): @@ -188,6 +189,27 @@ def rFonts_hAnsi(self, value): rFonts = self.get_or_add_rFonts() rFonts.hAnsi = value + @property + def rFonts_eastAsia(self): + """ + The value of `w:rFonts/@w:eastAsia` or |None| if not present. Represents + the assigned typeface name. The rFonts element also specifies other + special-case typeface names; this method handles the case where just + the common name is required. + """ + rFonts = self.rFonts + if rFonts is None: + return None + return rFonts.eastAsia + + @rFonts_eastAsia.setter + def rFonts_eastAsia(self, value): + if value is None: + self._remove_rFonts() + return + rFonts = self.get_or_add_rFonts() + rFonts.eastAsia = value + @property def style(self): """ diff --git a/docx/text/font.py b/docx/text/font.py index 5a88e8af..f9ccbaf2 100644 --- a/docx/text/font.py +++ b/docx/text/font.py @@ -179,21 +179,36 @@ def math(self, value): @property def name(self): """ - Get or set the typeface name for this |Font| instance, causing the + Get or set the typeface names for this |Font| instance, causing the text it controls to appear in the named font, if a matching font is found. |None| indicates the typeface is inherited from the style - hierarchy. + hierarchy. `ascii`, `hAnsi`, and `eastAsia` can be set respectively + by specifying them in dictionary format """ rPr = self._element.rPr if rPr is None: - return None - return rPr.rFonts_ascii + return { + "ascii": None, + "hAnsi": None, + "eastAsia": None, + } + return { + "ascii": rPr.rFonts_ascii, + "hAnsi": rPr.rFonts_hAnsi, + "eastAsia": rPr.rFonts_eastAsia, + } @name.setter def name(self, value): rPr = self._element.get_or_add_rPr() - rPr.rFonts_ascii = value - rPr.rFonts_hAnsi = value + if isinstance(value, dict): + rPr.rFonts_ascii = value.get('ascii') + rPr.rFonts_hAnsi = value.get('hAnsi') + rPr.rFonts_eastAsia = value.get('eastAsia') + else: + rPr.rFonts_ascii = value + rPr.rFonts_hAnsi = value + rPr.rFonts_eastAsia = value @property def no_proof(self): diff --git a/tests/text/test_font.py b/tests/text/test_font.py index 5b4b15eb..46149bc0 100644 --- a/tests/text/test_font.py +++ b/tests/text/test_font.py @@ -228,10 +228,12 @@ def highlight_set_fixture(self, request): @pytest.fixture( params=[ - ("w:r", None), - ("w:r/w:rPr", None), - ("w:r/w:rPr/w:rFonts", None), - ("w:r/w:rPr/w:rFonts{w:ascii=Arial}", "Arial"), + ("w:r", {'ascii': None, 'hAnsi': None, 'eastAsia': None}), + ("w:r/w:rPr", {'ascii': None, 'hAnsi': None, 'eastAsia': None}), + ("w:r/w:rPr/w:rFonts", {'ascii': None, 'hAnsi': None, 'eastAsia': None}), + ("w:r/w:rPr/w:rFonts{w:ascii=Arial}", {'ascii': "Arial", 'hAnsi': None, 'eastAsia': None}), + ("w:r/w:rPr/w:rFonts{w:hAnsi=Arial}", {'ascii': None, 'hAnsi': "Arial", 'eastAsia': None}), + ("w:r/w:rPr/w:rFonts{w:eastAsia=Arial}", {'ascii': None, 'hAnsi': None, 'eastAsia': "Arial"}), ] ) def name_get_fixture(self, request): @@ -241,17 +243,27 @@ def name_get_fixture(self, request): @pytest.fixture( params=[ - ("w:r", "Foo", "w:r/w:rPr/w:rFonts{w:ascii=Foo,w:hAnsi=Foo}"), - ("w:r/w:rPr", "Foo", "w:r/w:rPr/w:rFonts{w:ascii=Foo,w:hAnsi=Foo}"), + ("w:r", "Foo", "w:r/w:rPr/w:rFonts{w:ascii=Foo,w:hAnsi=Foo,w:eastAsia=Foo}"), + ("w:r/w:rPr", "Foo", "w:r/w:rPr/w:rFonts{w:ascii=Foo,w:hAnsi=Foo,w:eastAsia=Foo}"), ( "w:r/w:rPr/w:rFonts{w:hAnsi=Foo}", "Bar", - "w:r/w:rPr/w:rFonts{w:ascii=Bar,w:hAnsi=Bar}", + "w:r/w:rPr/w:rFonts{w:ascii=Bar,w:hAnsi=Bar,w:eastAsia=Bar}", ), ( "w:r/w:rPr/w:rFonts{w:ascii=Foo,w:hAnsi=Foo}", "Bar", - "w:r/w:rPr/w:rFonts{w:ascii=Bar,w:hAnsi=Bar}", + "w:r/w:rPr/w:rFonts{w:ascii=Bar,w:hAnsi=Bar,w:eastAsia=Bar}", + ), + ( + "w:r/w:rPr/w:rFonts{w:ascii=Foo,w:eastAsia=Foo}", + "Bar", + "w:r/w:rPr/w:rFonts{w:ascii=Bar,w:hAnsi=Bar,w:eastAsia=Bar}", + ), + ( + "w:r/w:rPr/w:rFonts{w:hAnsi=Foo,w:eastAsia=Foo}", + "Bar", + "w:r/w:rPr/w:rFonts{w:ascii=Bar,w:hAnsi=Bar,w:eastAsia=Bar}", ), ] ) From 2e938b96c397f7d7df02d752b75e2f39cd16c7ca Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 22 Nov 2024 10:49:31 +0800 Subject: [PATCH 065/115] HISTORY.md --- HISTORY.md | 53 +++++++++++++++++++++++++---------------------------- LICENSE | 2 +- README.md | 5 +++-- setup.py | 9 ++++----- 4 files changed, 33 insertions(+), 36 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 208dc571..26c2ec04 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,49 +1,46 @@ -Release History ---------------- +## Release History -**0.0.7 (2022-10-29)** +**0.0.8 (2024-11-22)** + +- EastAsia font support fixes #25 -- add emf image file support. #24 +**0.0.7 (2022-10-29)** +- add emf image file support. #24 **0.0.6 (2022-10-21)** -- change default custom xml file name to item1. #23 - +- change default custom xml file name to item1. #23 **0.0.5 (2022-8-08)** -- minor refactor custom-properties. -- add add_float_picture in Document. #21 - +- minor refactor custom-properties. +- add add_float_picture in Document. #21 **0.0.4 (2022-7-21)** -- public python-docx-oss docs @ readthedocs. -- add delete_item in CustomXmlPart. #17 - +- public python-docx-oss docs @ readthedocs. +- add delete_item in CustomXmlPart. #17 **0.0.3 (2022-7-01)** -- Change method text to texts in CT_R. #14 -- Add external target_ref setter. #15 -- Blacken all Python files. - +- Change method text to texts in CT_R. #14 +- Add external target_ref setter. #15 +- Blacken all Python files. **0.0.2 (2022-06-24)** -- Add custom xml support. #10 -- Add Part __eq__. -- Add Part element setter. -- Add Relationships parts_with_reltype. - +- Add custom xml support. #10 +- Add Part **eq**. +- Add Part element setter. +- Add Relationships parts_with_reltype. **0.0.1 (2022-06-16)** -- Only support Python3.8, 3.9 and 3.10. -- Add custom properties support. #2 -- Add drop_rels in Package. #5 -- Add drop_rels in Part. #5 -- Add default NumberingPart. #4 -- Fix Python3.8+ __dict__ TypeError. #6 -- Add some typehint. +- Only support Python3.8, 3.9 and 3.10. +- Add custom properties support. #2 +- Add drop_rels in Package. #5 +- Add drop_rels in Part. #5 +- Add default NumberingPart. #4 +- Fix Python3.8+ **dict** TypeError. #6 +- Add some typehint. diff --git a/LICENSE b/LICENSE index 1d15a3f5..097ae181 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2013 Steve Canny, https://github.com/scanny Copyright (c) 2022 Ethan St. Lee, https://github.com/lsaint +Copyright (c) 2013 Steve Canny, https://github.com/scanny Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index c90ec55a..9c62fc76 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,10 @@ oss

-*As a Brazilian jiu-jitsu player, OSS means anything and everything. It's a term used in BJJ that is a way of greeting and demonstrating respect to others.* +_As a Brazilian jiu-jitsu player, OSS means anything and everything. It's a term used in BJJ that is a way of greeting and demonstrating respect to others._ **_python-docx-oss_** is a Python library for CRUD Microsoft Word (.docx) files. It fork from [python-docx](https://github.com/python-openxml/python-docx). -

PyPI @@ -25,3 +24,5 @@ --- More information is available in the [python-docx-oss documentation](https://python-docx-oss.readthedocs.io/en/latest/) + +This project is based on the original work by [Steve Canny](https://github.com/scanny) and has been modified by [Ethan St. Lee](https://github.com/lsaint). diff --git a/setup.py b/setup.py index 6e6dccf4..dac81a40 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,7 @@ #!/usr/bin/env python import os +import pathlib import re from setuptools import find_packages, setup @@ -13,15 +14,13 @@ def text_of(relpath): """ thisdir = os.path.dirname(__file__) file_path = os.path.join(thisdir, os.path.normpath(relpath)) - with open(file_path) as f: - text = f.read() - return text + return pathlib.Path(file_path).read_text() # Read the version from docx.__version__ without importing the package # (and thus attempting to import packages it depends on that may not be # installed yet) -version = re.search(r'__version__ = "([^"]+)"', text_of("docx/__init__.py")).group(1) +version = re.search(r'__version__ = "([^"]+)"', text_of("docx/__init__.py"))[1] NAME = "python-docx-oss" @@ -40,7 +39,7 @@ def text_of(relpath): TESTS_REQUIRE = ["behave", "mock", "pyparsing", "pytest"] CLASSIFIERS = [ - "Development Status :: 3 - Beta", + "Development Status :: 4 - Beta", "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", From 6bf94b8d7ce9b65769d71710e0ea6d17c94bcf33 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 22 Nov 2024 10:56:29 +0800 Subject: [PATCH 066/115] HISTORY.md --- HISTORY.md | 1 + tox.ini | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 26c2ec04..5280120f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,6 +3,7 @@ **0.0.8 (2024-11-22)** - EastAsia font support fixes #25 +- Update README.md #26 **0.0.7 (2022-10-29)** diff --git a/tox.ini b/tox.ini index 27f8e25b..f5afb0de 100644 --- a/tox.ini +++ b/tox.ini @@ -12,7 +12,7 @@ python_classes = Test Describe python_functions = it_ they_ and_it_ but_it_ test_ [tox] -envlist = py38, py39, py310 +envlist = py310, py311, py312, py313 [testenv] deps = From e6e1aa3543842583126928e7895c6ad0ea5f8da3 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 22 Nov 2024 11:51:58 +0800 Subject: [PATCH 067/115] docs Python >= 3.10 --- docs/user/install.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user/install.rst b/docs/user/install.rst index ea11dc81..248ced71 100644 --- a/docs/user/install.rst +++ b/docs/user/install.rst @@ -26,5 +26,5 @@ but if you use this last method you will need to install those yourself. Dependencies ------------ -* Python 3.8, 3.9 or 3.10 +* Python >= 3.10 * lxml >= 4.6.5 From c539969d7fc5c922f27a28ac8de641fe44f82717 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 22 Nov 2024 17:57:05 +0800 Subject: [PATCH 068/115] update readthedocs os & py --- .readthedocs.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index eb50d101..9eafe51e 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -1,9 +1,9 @@ version: 2 build: - os: "ubuntu-20.04" + os: "ubuntu-22.04" tools: - python: "3.10" + python: "3.12" python: install: From e2727e934e504b2cc1fb82ce6186a2b9d67c584e Mon Sep 17 00:00:00 2001 From: Ethan St Lee Date: Tue, 26 Nov 2024 10:18:50 +0800 Subject: [PATCH 069/115] Add basic support for adding SVG pictures to docx files (#27) * Add basic support for adding SVG pictures to docx files --- docx/image/__init__.py | 5 ++- docx/image/constants.py | 1 + docx/image/svg.py | 65 ++++++++++++++++++++++++++++ docx/oxml/__init__.py | 2 + docx/oxml/ns.py | 11 +++-- docx/oxml/shape.py | 58 +++++++++++++++++++------ tests/image/test_svg.py | 57 ++++++++++++++++++++++++ tests/test_files/snippets/inline.txt | 2 +- 8 files changed, 180 insertions(+), 21 deletions(-) create mode 100644 docx/image/svg.py create mode 100644 tests/image/test_svg.py diff --git a/docx/image/__init__.py b/docx/image/__init__.py index 43683946..3b0f0979 100644 --- a/docx/image/__init__.py +++ b/docx/image/__init__.py @@ -8,11 +8,12 @@ from __future__ import absolute_import, division, print_function, unicode_literals from docx.image.bmp import Bmp +from docx.image.emf import Emf from docx.image.gif import Gif from docx.image.jpeg import Exif, Jfif from docx.image.png import Png +from docx.image.svg import Svg from docx.image.tiff import Tiff -from docx.image.emf import Emf SIGNATURES = ( @@ -26,4 +27,6 @@ (Tiff, 0, b"II*\x00"), # little-endian (Intel) TIFF (Bmp, 0, b"BM"), (Emf, 0, b"\x01\x00\x00\x00"), + (Svg, 0, b" tuple[int, int]: + _, _, logical_width, logical_height = map(int, viewbox.split()) + + aspect_ratio = logical_width / logical_height + + if aspect_ratio >= 1: + final_width = base_px + final_height = base_px / aspect_ratio + else: + final_height = base_px + final_width = base_px * aspect_ratio + + return int(final_width), int(final_height) diff --git a/docx/oxml/__init__.py b/docx/oxml/__init__.py index 62043fa7..31de2185 100644 --- a/docx/oxml/__init__.py +++ b/docx/oxml/__init__.py @@ -133,6 +133,8 @@ def OxmlElement(nsptag_str, attrs=None, nsdecls=None): register_element_cls("a:blip", CT_Blip) register_element_cls("a:ext", CT_PositiveSize2D) +register_element_cls("a:extLst", CT_Transform2D) +register_element_cls("asvg:svgBlip", CT_Transform2D) register_element_cls("a:graphic", CT_GraphicalObject) register_element_cls("a:graphicData", CT_GraphicalObjectData) register_element_cls("a:off", CT_Point2D) diff --git a/docx/oxml/ns.py b/docx/oxml/ns.py index 77cc77ea..4436ccbd 100644 --- a/docx/oxml/ns.py +++ b/docx/oxml/ns.py @@ -1,5 +1,3 @@ -# encoding: utf-8 - """ Namespace-related objects. """ @@ -25,9 +23,10 @@ "wp": "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing", "xml": "http://www.w3.org/XML/1998/namespace", "xsi": "http://www.w3.org/2001/XMLSchema-instance", + "asvg": "http://schemas.microsoft.com/office/drawing/2016/SVG/main", } -pfxmap = dict((value, key) for key, value in nsmap.items()) +pfxmap = {value: key for key, value in nsmap.items()} class NamespacePrefixedTag(str): @@ -50,7 +49,7 @@ def clark_name(self): @classmethod def from_clark_name(cls, clark_name): nsuri, local_name = clark_name[1:].split("}") - nstag = "%s:%s" % (pfxmap[nsuri], local_name) + nstag = f"{pfxmap[nsuri]}:{local_name}" return cls(nstag) @property @@ -93,7 +92,7 @@ def nsdecls(*prefixes): Return a string containing a namespace declaration for each of the namespace prefix strings, e.g. 'p', 'ct', passed as *prefixes*. """ - return " ".join(['xmlns:%s="%s"' % (pfx, nsmap[pfx]) for pfx in prefixes]) + return " ".join([f'xmlns:{pfx}="{nsmap[pfx]}"' for pfx in prefixes]) def nspfxmap(*nspfxs): @@ -102,7 +101,7 @@ def nspfxmap(*nspfxs): *nspfxs*. Any number of namespace prefixes can be supplied, e.g. namespaces('a', 'r', 'p'). """ - return dict((pfx, nsmap[pfx]) for pfx in nspfxs) + return {pfx: nsmap[pfx] for pfx in nspfxs} def qn(tag): diff --git a/docx/oxml/shape.py b/docx/oxml/shape.py index b195210a..556ee782 100644 --- a/docx/oxml/shape.py +++ b/docx/oxml/shape.py @@ -1,6 +1,7 @@ """ Custom element classes for shape-related elements like ```` """ + from docx.oxml import parse_xml from docx.oxml.ns import nsdecls from docx.oxml.xmlchemy import BaseOxmlElement, OneAndOnlyOne @@ -31,6 +32,7 @@ class CT_Blip(BaseOxmlElement): embed = OptionalAttribute("r:embed", ST_RelationshipId) link = OptionalAttribute("r:link", ST_RelationshipId) + extLst = ZeroOrOne("a:extLst") class CT_BlipFillProperties(BaseOxmlElement): @@ -108,7 +110,7 @@ def _inline_xml(cls): " \n" ' \n' " \n" - "" % nsdecls("wp", "a", "pic", "r") + "" % nsdecls("wp", "a", "pic", "r", "asvg") ) @@ -145,14 +147,48 @@ def new(cls, pic_id, filename, rId, cx, cy): contents required to define a viable picture element, based on the values passed as parameters. """ - pic = parse_xml(cls._pic_xml()) + if filename.endswith(".svg"): + pic = parse_xml(cls._pic_xml_svg()) + pic.blipFill.blip.extLst.ext.svgBlip.embed = rId + else: + pic = parse_xml(cls._pic_xml()) + pic.blipFill.blip.embed = rId pic.nvPicPr.cNvPr.id = pic_id pic.nvPicPr.cNvPr.name = filename - pic.blipFill.blip.embed = rId pic.spPr.cx = cx pic.spPr.cy = cy return pic + @classmethod + def _pic_xml_svg(cls): + return ( + "\n" + " \n" + ' \n' + " \n" + " \n" + " \n" + " \n" + " \n" + ' \n' + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + ' \n' + ' \n' + " \n" + ' \n' + " \n" + "" % nsdecls("pic", "a", "r", "asvg") + ) + @classmethod def _pic_xml(cls): return ( @@ -174,7 +210,7 @@ def _pic_xml(cls): " \n" ' \n' " \n" - "" % nsdecls("pic", "a", "r") + "" % nsdecls("pic", "a", "r", "asvg") ) @@ -204,6 +240,7 @@ class CT_PositiveSize2D(BaseOxmlElement): cx = RequiredAttribute("cx", ST_PositiveCoordinate) cy = RequiredAttribute("cy", ST_PositiveCoordinate) + svgBlip = ZeroOrOne("asvg:svgBlip") class CT_PresetGeometry2D(BaseOxmlElement): @@ -260,9 +297,7 @@ def cy(self): Shape height as an instance of Emu, or None if not present. """ xfrm = self.xfrm - if xfrm is None: - return None - return xfrm.cy + return None if xfrm is None else xfrm.cy @cy.setter def cy(self, value): @@ -284,13 +319,12 @@ class CT_Transform2D(BaseOxmlElement): off = ZeroOrOne("a:off", successors=("a:ext",)) ext = ZeroOrOne("a:ext", successors=()) + embed = OptionalAttribute("r:embed", ST_RelationshipId) @property def cx(self): ext = self.ext - if ext is None: - return None - return ext.cx + return None if ext is None else ext.cx @cx.setter def cx(self, value): @@ -300,9 +334,7 @@ def cx(self, value): @property def cy(self): ext = self.ext - if ext is None: - return None - return ext.cy + return None if ext is None else ext.cy @cy.setter def cy(self, value): diff --git a/tests/image/test_svg.py b/tests/image/test_svg.py new file mode 100644 index 00000000..bc18b6e5 --- /dev/null +++ b/tests/image/test_svg.py @@ -0,0 +1,57 @@ +import io +from xml.etree.ElementTree import Element, tostring + +import pytest + +from docx.image.svg import BASE_PX, Svg + + +@pytest.fixture +def svg_with_dimensions(): + """Fixture for SVG stream with width and height.""" + root = Element("svg", width="200", height="100") + return io.BytesIO(tostring(root)) + + +@pytest.fixture +def svg_with_viewbox(): + """Fixture for SVG stream with viewBox but no width and height.""" + root = Element("svg", viewBox="0 0 400 200") + return io.BytesIO(tostring(root)) + + +@pytest.fixture( + params=[ + ("0 0 400 200", 72, 36, 72), # Landscape + ("0 0 200 400", 100, 200, 200), # Portrait + ("0 0 100 100", 50, 50, 50), # Square + ] +) +def viewbox_data(request): + """Fixture for different viewBox test cases as tuples.""" + return request.param + + +@pytest.fixture( + params=[ + (b'', 200, 100), + (b'', BASE_PX, BASE_PX // 2), + ] +) +def svg_stream_data(request): + return request.param + + +def test_dimensions_from_stream(svg_stream_data): + stream_data, expected_width, expected_height = svg_stream_data + stream = io.BytesIO(stream_data) + width, height = Svg._dimensions_from_stream(stream) + assert width == expected_width + assert height == expected_height + + +def test_calculate_scaled_dimensions(viewbox_data): + viewbox, expected_width, expected_height, base_px = viewbox_data + width, height = Svg._calculate_scaled_dimensions(viewbox, base_px) + assert width == expected_width + assert height == expected_height diff --git a/tests/test_files/snippets/inline.txt b/tests/test_files/snippets/inline.txt index 3b0d5814..baf0a7d0 100644 --- a/tests/test_files/snippets/inline.txt +++ b/tests/test_files/snippets/inline.txt @@ -1,4 +1,4 @@ - + From 06fe9f12b8aa8e6c0d336efb87be4834027afb3a Mon Sep 17 00:00:00 2001 From: Ethan Date: Tue, 26 Nov 2024 10:21:08 +0800 Subject: [PATCH 070/115] update docs --- HISTORY.md | 9 +++- docs/_static/img/example-docx-01.png | Bin 77526 -> 1247998 bytes docs/index.rst | 77 ++++++++++++++------------- docs/user/shapes.rst | 7 +-- docx/__init__.py | 15 +++--- 5 files changed, 57 insertions(+), 51 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 5280120f..9ba210c4 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,9 +1,14 @@ ## Release History +**0.0.9 (2024-11-26)** + +- svg file support in add_picture. #27 +- update docs. + **0.0.8 (2024-11-22)** -- EastAsia font support fixes #25 -- Update README.md #26 +- EastAsia font support fixes. #25 +- Update README.md. #26 **0.0.7 (2022-10-29)** diff --git a/docs/_static/img/example-docx-01.png b/docs/_static/img/example-docx-01.png index 6af10995b6b8d0beae4550e5b654b0ef7fd614bf..19b8be7188d99bcb15bb798dba67cce0f104baad 100644 GIT binary patch literal 1247998 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 z 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%0A@d4abS>jn|*r61r1y9%+ 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⩔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

A4B4XqW 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

  • Mg=MqEMe%q+*!K|#&Ks|MFwT+$U4 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�h@lbMT+T#+eaSte3DkElm=8W1<3q1NWZN;QpZ8 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�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

    KyrHpz`a@?@Q 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

    hA2LoEv4ca3)6PHFmmo-rzL!?0K~iT z7H{8k&Qnkm^F!Rl(()6pNFT7X0?F5=AwRG}FmVua5jY(n^_P)H@60%F@w#fa-IPXQ>P-Xh#F z!?Ii1O4@;fqlc3bI(r5w!c}~Ds)KkWRq{;ix~GpSV3bDfn8DHflO~1qZINRDLPrFY z!AA&X2m9MObW0PII3)sS6 z2X^}2Xhqom#V>vae45L5zw=7q^5vIaKvA(=-gxISg40v%g6}LZTzY}s>Ifm}n-gPW z>}GC5L4ye)>eGOEmDk^Sw|sE@7E0jN@`ca6NS&0Wx(EfCGdaw*}%3=$exa;2&0KEu*Q#lG9prwio$8(jeadOZO2lsfg z&C?ojirI0{a;ot#1fbw=8ICa|4L-5GyyObmL0tT^jT{?u3~_yXJog#q_^IhK&GYoo z&Yr%Q~R|m?RP3DSy zgw^t#^+`PKM<~qTJ1^_eh_F$I+|pEE0*-6)u&2uGmA02Q&rYiT1p7p zM`d{MIO$bnxSN`emr8P;^s~`KdHUFBtO zCX(!zjpfD9eZE}0@L1{Z>m`1xyoR0o4oqL&y!|nBYARDGF?u)=dSQAZ+D9Sg%F;|} zUAc*Apoa3&Py8GTtgUhfUkw92J?z-l#MpNDv-s9`zD4m{m@(=s7cM-`$xU zJ!KFDM-z7a7cphDKwG!8v~#j(iwy{iWo8!BRrbBs!*cf)&c6qGBqeQ$FE0Af%JMq! z7@wen0_~3Ou7E#}PZ<@qNp+Q(qvbFE@-Jf^sS5?jBnm%H8niE$-}!^z+lFn<5=P4JmA>t z$x=@WIRfjSWP`CnUL6?d4L=F{@X6%a$IHcO%rRj??wyaWmtNM6GJ79OkS+a4Ii``x zyW^yavmJ10?d~mu@Vn+8x1rAfhbXu1Tr1yQgQtT3JPF}kX}`;HTik@>yS(m|3Iy?H zTpt)M&p&axytCd|<~hMMx{J9j)&>m-!s!U5wQr<+0W)78q42rKc)Qo!R?eInE323W z8yy-7e++Nq+nP{(5G6UN31!hpc|v4uBWja-!_}O%FrOD-8Pt;SR*%WqY$C(V)G$w5hk*kKU(2~ zHP*E%zz$K8*wo;W=j zlRWc$2t#s70YzA-`0?dE1oAw_0)~Z(;ZDu2L5`LrzOWqe*RT+}_#scYVX;62R!rlr zS_pI@1-O6{iy6{~FhV%wtBQ~KTF{WVMCMrR1%7;(xhV9bDRAQ1OZfhYi{FVewaO6Sn^n=iE#UdAdZl-#F|emFVjX6 zk|jPBeBX>0Ba!ka(pR(wX5v)EAxv+^97^~R0M{%M-k_t4dfKi=n8DsV1#Es;QbaUe z@K2PU{AO@QdgINaYt zqB7FUdS$)yS$IMuErV=ZH;%VE8QTyTc6VZu20`r#CK-0|1){()lmdh)u;6nsKH_40 zK;Yu(ivxD#9UQt-`T&zB@;?_tU?`Vx`!Yk z#|e}QP}+KgK#DT=5Y}}d$fW?vr9Bx{eh+rJ)eMA3@O4 z{89*vYyQjeR-p-Pz@NBA<$zaTwxT8#th1(BZ0guiNCE|b;@{GV5M=uCGV}3eA`$Wo zPL#g!v*c?mb60*?Hs|j~I{7R5qZ1eat#b%jiKtCOSr7R(1bN43MEc-Q;(}MmAG}GR zJ0*kGAZL38pHf85RhB7#NjZc=?4EX4q`AdKp{nrQRj<%GOo@fyGKJrk8GS0i@M1yL zrNBbPQSdBb*2*96u`8UU#@U9#sLcaq-JmN%Nc*w4MH`S-T-=>*n;i?`6|f8Z=$3*6 zDIh-n+3%|~mKUdKz$9^#e=EcyP0rJS8}Gpf!h&|0Ecqdno`eSs$_PbUOrkkwh_gkv zv>cXS{E18D-}M`A7<>+YIJ#e#IQuei%RX=3{s1}}5T zkHM?tlh;C#Mqd5Vj82^{BkY2G|LxaFM<(zxZS*%_3VaVi@exgUm;S-C#z|xF*Lk(= zu6e70!CrP-BWUBF${2UvyP$I185m4^^!9P->n_?Qgrq7Y6m;8GJ}V4&?CE6(^cbfW z6p(u=WF4i%$WS{wzSrQnf}pOqJbrc(WkN@pKu|P+z*w^#d#oFl5zhX>Yj2e+AK#Yx z<(cO$VMYdlGGp7T-+i_G^p`(ZrY9K37+2nY|DCdhU~migUwY{aX`%-~Qy)9@hX)7B z-I>{-w>;*0bq7JzZN`B%@@^wg#ji5{G=|F`e((F`Coz@N-qT2E*uq=|w**G|GrSSdV>1|?p8_fH(`Bl51#wlgt2+xHyD$ia(gRX%t!P3Pk( zF%=@qOI{s}2ez5M9)gX4ArAUN@dO1$vim)E5=RDpXg7VqNRnF@rtCl!Hh z2>w7P(rJ#*F{_2XpzVI^t};zQ?G8KNsdPd<(i6zA^LX#gI*b^9(Rla|U8IIO37rIU>Y zOPo+xMUip&qj$>iKy!Ke$xG$jsQ_khwz_z z@h8fKQx|Z)3^2@Wt>f%_eqpVAeCK0Mop0c;;Q^;9;44fgt)nRN#L^)<^A~64$`H=H zhbKl#KR&cR`rsPE`wf(Og9xH~5u6|5dtX z`ElChL0QH$+ZJmI=TGU`J=7JaFIPE9_0(sc!4%isa_{dCN5+_F(-*#G2?!1H#4^L0#rWE_f0c#M) zN!K~G5?{XeS>AC>b3Bw+=1_D-I_L?@(kAvL%yGe|W0;9E?fBUz@c}Y|!s$-=;oI-U z>7$WOPL*N$h{~m4+wT|3IAEOEp-(oW;2OakmwpWtQp0d%Z2flm{_Iwn;WUQ*VF!M5 zY_`&U-p%m#w?1Ad9iRJ|^7k(Gm0jwl`KSAgZC~y|p?x1A`@vxN%&^a>@VhYD zS?D1Pr;xh;v|bFI6h{4)U1^K7gV7`&J$v)Qow&+Igdgw z;-#5Yam{0+#tB+rT5izP_9ri?h<2Xif7ChS!+AJijnx{WXK1uMwliDS`^HO4ADean z-hh9QbvrO8GGqh9AwJUl_%uFuMzSbzjba?DuKMH3+#zh^!K0R}esV!WnmR6K za9&~_=kA1GFQ#1h_|M%kE`-cux?I@#=EVZ2ipw`bNGv|4Rn{KME5a1!M?k2QgjeIFw%aBavbCx4NWSInk_pw08G?peui3EQvVzYkm5D$r=@m{9& z?~h_py$f6E5oxlXJXR2V3h;F$9|||_k6u|yT~@~Wadkv9f}-7mhNi3GC&p3p430Q5 z<~`C?c!H4s9=;NP`IPkJk!LK^zq);^ig2s(AuZ2YrQ>n}*9cFZInI}5nlkEOpRFlo zdas~Ur0|7UKR=Qe%q_%dd*~gtVBv3hjsx});YME}ap2j2@CB0?58N?@uquUvS(e4S z!(O3J6J`OT9@d$@)XK-0J7Xg~C5flP=Qs{dn&S&BY+x}nFaH9sy8MbSq;FlT_(h~cub?4^$ zx8@NRxw|)@@&TnlwS$i;1VlJCY-#RfNAx5Dz;Sj%e_Zb0`!GIqbp+boIgAixH0ajX zJ6LWlzl)>q-Lk>Qnjf6I2<;SPig!B#D{(#0mLHdb1WggCRIq|+iUZsc*eIY==%64% zVVCg=s5D8{jKIuY{?bcZ-C<6IGzyOl&#_(jx#QMmvHc7u6LhG@Hc#E)Oq@KiTOat+ zN};&0>ONrJ$doM=FcjEHEqN?2>ttKi7xi&0Ca)(;6j(GO7!w!U=D;%f_!X|XqCB1y zem0SA3)|hn$89~Od-8nQU!5tNvp1=Sdvy5+p6%G-R^g?oFCBCnCQZa6`ay+G&W%}) z?H~@))1*Et#4}IE<=knCx*sLaCEU!HX%#{!=xE|}kKyi;mv#!Fb7!-CDhmk(leDmW z=;FV+Oa<=>;De8$RS+big$o|QBWHy-astX_SPGhoyEK*$6sU@`T}`|cuzM-QNV+5s zMPT)lC5U}>NsypnzKgGyv=xqHK^PPdPI&R<7S&EEmpAl+k{K%LBvVl(q|DQWqyAG!-(4xs~s} z`(gP%|Ix3atQjo-{onr2LMia-Ex7(;nGW?tOC&id|<3&T127I4uU=DdWbOb4mQu<{rDy{XfO8>Isz%!gOA|g2QU6&iIH@7g`;y zcWDF1DorWb=7vAq-|P#rukGTv>G-P2H{TCYBGX%VNPe(S$VV!NV_XKVrxKzAk={%s zrT^vlARTO1m6x8#Q7CA8X|_lIGundJzsEXb{yt-TDAuT->v_jQc|%iF>nO}M( z>`zRU>+ih636tJ(~PGNN#rf* zo_#~bfMNMZuRw{hj534%%os)}Q}6+%>F{aM(~JY~1$N`JzJnvqJ^R`6EMv=i?|x8z z?Q6eZp1$;W>1n_R2=pJp_m1_k@iY&%zK#L`<A^3?E+=Oi z*i@nu_m08I^7)C*a{2CDnS=Hm4MKr{qU^A%oady?H&LSOVp3{yW45$tQi}RorZfqq zx8?c{&79NhL(;|mtP;Zw5t^7<$86O9yEah%;lKB#(nr}%oZNZ&%Dpn(epoJT-!50y zACzmH#sF}P3qvS>$Jo&F9w&dcIb9Xs=9Cj-h?S+b&L^Gpb;lpx%Jlef>E2x^@69ph zK~G^x6Z>wA7u;2<_-_6fpTRqo>Qy*pSOY4R^EGd=)-s3X5M7^k$u(iF7hHPCL-re) z{}jrgp>23&@&c!zSi1u9fIiJit2A>O<~}DOdf}nNEu7AytPoSNk}sTB9fLgCEG~O0 zHQIX1NC&4aFfq8rnA3nFd>NQ6 z>3I2#@;d%Vo`2$8>7g%alF!-y%U}AbM^0k=X-W*yJyB#xg_G-q0-t;eoG3Cr`E7K9 z;g2B&K7UDP-zi+O`Yt3~X!rr=vVd=x*iq(!!=sn+No4{q<6VlH(nYJ6iyfcLmmv|# z!pA#d!maXWNahLQzl)>D#E*+qZv+KQ^9X}`2!?nJL4Tyn#aS)}v!M7DmkKWd3Cj;Z z?|<~N4B?sH=lZH26J=`eYAOP)N8)DXSo6k$+y$tJOPhcKe!kU(@&wJShUIXN^337O zak``OtF)P(G-Qfr!p)z`A7N2W)b$ufz_e_yC@kL&$s^P)5HOE4$;&e8a~O&AB1UAic%cf^|Rak=2>OY%z9+pxk%xOc1UtjvXN>j!+inm2c4MiFL>;#6idAxLfR9T!;H zoxd5UTc}j+0VKvtO+)&iI+(Owh_TIQMMRB6N&Q3 z6@;Mdq^n@0a~lH9b_7xG0@ty#GEe!{iiFt~k>WW%$OY{SnS~bo$!qYv{fB(vc3w;1snogd5V073o~|~MyVDret}GcWUB{gez>Y~j7&_$ zgL;cP_}A@h-&PqbBU0e3;03x^hNoR>rHAQ{`T;N$(ze29@`u7P z6-o|+Dmip`Ea18yb>ei|I)q6l!rKwdYxYN>p!j(?&Z^kh$1aA-K5f4ThhPky2N8(;X0 zj8}ee`C9q4-~3wnTYv4Z;MlmYY*Fs_-g&P)_r&=!(cc%schOgw+Ji})Rcx9|OUxbBp55){)=BJ;XE>qfCXMEj2u)9XTzjkkt zad$rGHi7ft9(H-RqA*fGuf2Hf`)_ed%w64^oQAPax1n@hMG$TKsYKA8yjPxt%5}2s z5GR&tTbp0LuxV6&$jiYI!K(-a6}BNjjh(;5+qQNrxk~uaRjF?{k%v#5D^=)(fK%lK zyWt5&;nPg}r2@G_p)_Oan!;@IIw#tGUiKmT&JL$;Jjo$8jvp#Q#93S|)Un4?9E}J8 z7xCW|{WBt&SD;G>8^OhNxeg&0^%Z~N7;afnp7V&|)p%fEu;17ZozvVcoeFaJ69KU1 z{Nh9(rEafzYQ{d2sVa6ZY}d4?_Vp zJw46%h$$q@#eIC^I%T$?pcpHUJ$8=MjLj$#?i`I}wtEYI)^BERmV6J&vlmX64hDq> zY_QN&&Emow^EP80n+#eJsIMW|zJ}?erv25j4j+!6c?uI%XAs0UU|MaXba%5OA9G2~ zDBJc_F2Q5n&{doJ2h?YSzB@a!SYGB7(R=T`1uyBS96v8}i;U&8i*pq8^W>v`XjbvL z(NN(MV>Psv@%48lA9bLx+s1_04t_U0?I_>v)3?2B!dOd*zw0sY2!dNNGbNY?#|{)U z`-htEYQ(8D>k@>yI*iv(&ZTEAlyyw$tTQG~V>ao@C%#lZ_vueVXO)c52cf>$fMB$7 z2)kLsskn+$YxMgS%vP1Y zv2(Tj%0KBs1C(EZEpDM2{AFyuQE@SvX(A?x9 ze9KSSZ|o>9oS!ZoTTA85nYFS-+nnYU$r_8@fx(fo#QN#gk7vu7)w`v0ALS^gG3@5` zd{4LG;>SKgx%LgmZ*j2ys>D#4p-H9JZqJwY7rtEn?#2GHz|gaJ=T^DCvRz*4!OZ9^ zr!g9a%c>`LsmCFG>oJtg`s}!|f}ox<8M=WPhGK^E3C#-7V*G znIivUJwn}DIT6)?X;e*i$xkZV#WCoX)c`hiiHg-@ilq|Ce@}44S|nenCH)(kM?L8q z`n6zGC5GWoGvZ!(ILFJwYpe#>3hx0m5ZE4?t=$fD^s=3p`OC4Pi3+3c;U#L)bpnr%76UQpL`NSs(76!GLjA_ zzb6#Cf9+&10}I>Sym!uBAQ%+;qY}+L;+OA@CspkJKuF z5?|Fg;Q9kx7f>O1R>QPH zNsN5^6Rs*U)0w`y>P!~QWf_T4U{Jx$M1iM?NL#}pg8}9|x|t*|QV|tN>YzUnyE?y# zP3X@buT!)=F_Ajb)oBfR_%hNk7&-3VgiUzdy-CmG_~Z+dP;SK41tjc%7>^YkK;~7a z^Ub^p)*|&o?|x|54=j%h`0n^lr|tr+$~3ANbGBna~uS*LY2?dD1c~yNa%O_W$ zk@XZW+e}!-`+;)ApT-27V_2rF%gsFUt9209?6*hHByPj>(E%SG=@6B4lovvEzZ}RJ zJH!2uVLb9=mBNljob<(qiAAXmfG(lvP*BPkCH&0I(?j*lx`PM*jxO7*67U6#h^Xqr zjcCeM0Gs{KXv4&fPja3UmgO8lwVpvM+e+L-lMiczhkNY6+jr-0^?{^v<`6SdZS2(S z?nMBDsRVbH`k{ZQV?}&ibhQn!J%+r{kE8bA@IvGW~*mBqz-2p9&- z_~;n~nR{h$thZdf{t6#nm>%fDEXano;DHI|3W5}{DFAhMcLI4AI5tGqTv9P z9nHJotMEfow(tShi~w(!9oz1>@96K!`avTLnc7AMIeK zTzA^Fbaa*8k!b`x%g~wjK=^csV4%jY-q|dl2)S!$3{zLwdFR7fpBe7j-dMn~s|`;1 z%}TpTsFF?}AtAs|nq)pKNDunw;4xR#a$J<1#OZClYZuv zUg1QQvQs(8?r{VRG0!Q;7hitFMf98p1MvukPi0g?Dw-<9a_4oL^s@g(_Q)dth+93s zO0#zUzE-=nmSxhXt4eR>QbFOEYIW^N&{Q>eepPXD?NqF$TQ z5N9uiaE65-CjxWKlwMIbVS$rE6~;wzu-y`t&xmRi4!b3uOAyw@@xnH>iMBmCfnvcO z)Z*TW0>cv;Z3v*E9Qud!7Kcq7`Wn`OQbK}BI|bmL^3Z>VeM(2fZ3r)26CqjSon7(p zy8U@>eyt4jwh`Z4&QCv9))0`}Mhco{FkRP;Nu9UezgnKYa0aEtv*q{Sd?$oi11KY& zI(@o)`r_ju1d^r@Dvs(UxfBTop#j|G^MGwojUwgZJ|JCo80ER$$ zzrXz-{#DGdOqNv?40mQ1${;(f2iR4;i4tLq9pCHp)eQvH+T!n25rgn)8>K}9JJ`GS zbv!;B!cU#t_9N_7Iq>Z}>t$xW0TV$f(CkA2^o3_8@i%~p7EZveA%lGV87OiFFPCTsP?eJ(TZ{qHdz&#z!L#F#%8fK}hoG0dnvIg)Zsc)Zu}?^IxS(od z`$qC)D7Ru9U~I6j!8?xo3fydS#|p<3`9(h|mMvWA@4T44c~CykmO8@?Q#v%Ec|(y( zzCQd{h|{XR5#Y5>(u&s}uoPMivXRzs}u1MT$6SK3Enz__T(+F zkZ-B0)4Rgf9NVh78a!13gu;Syh3|Nh8yT{LD^!;+LeMEb&|AM3@@)scCsZ8UOZm}vU&$~87f z?1qxAms1}1QDD!*zx@LPm=VJa5InZ5$r#4(R_d&FLG*t_Lv@-R6 zIC>DAW0xNVh31vUQMmLlU$#;9`7%l)WlTz;p^WkH?Lg_-h-IY zR^k}SO6b`FPahzqcFb21N2Al0v=O{8GBsG%m+()6u-mqa%_OujQ)jH_DeE8!7L7aJ78z^*2#WaJqsqVrqP>OhMDW?ha11;5Ua8F!DhkZK_b)(~+zA z-I!|KEAQUH!S_Dn0(kAAe6Y_b=x&AgTmx9woHOVIT#mQ)6HOHDwD*=5FP<-`w8}?| zTV)6V{vnRm58wf2x#*7rID>y0Md-ErbLA$A?;&s-1h3WhfpV^|t^E46rP4QhyA19x zmnO}EQg)W-d~`ggS$fPf5HQDO6g{>XV}y!~Lrhuy_EKy4Z+`iUrAJvi?Q;uS;9RJ@ zuzR=MM8Wz&117nE>6p>m(_N-Icgtl=Bd$MyM=Y!Qv!0%ov#sLf4s(E}`9?9zH{QO_ z$r5}Zq4tRc(gcQaWwh7SS)N7F+`DwA{9q1cj-3^r)Y-aon)Pzo9H;vUmlYhB{3nFG zlFsIX{UVQZqRLAZ6|S}PQPDm;UY_k^e(U0dY|jAG6zes{<0X_3FeY%}Rm_OB1J*cC ztk`bOrwz;jjg-sEGI+sp-~o!I?vb(5j$eyq){4!Pr@|{b19-%U4f2{|6Gp5jNVA1s zrgg^uMox8gtMIiF?L8=^zy<$IciYFyMU-pkk4qzt!aeQuzx?4~Ro7Df>WjdGCV$$c z>9~J=`JjyVmh$(1_ThESpO)(+?t}s-6!?p#0OKp8=*e|LffEXR;1rp1002M$Nkl1DV%Vb#lOHUpG{Mh z7D$L|d?<aN8N~v^hbr6D)R`}wDlFRGcaHVO^D1I)T#1ruH*0;MvW=&QJ!h*Fw6DI zoOQV&D67IVCSLdnMCzAgJS%!0MZ`m~bTukDG_lQc z9)30?%gea>{rJtNY=h&lprwoTiV6V(u+dit4O#|T$s)5l0E)3f1E7eX~u#t^C_0outKwIgK>6)_2sz|@Ai-J?1_bIs%DRyx+sg-1yK^4oLfGLBbpK2cc!Et1RV7-E%bD+O7cvqpB3WI^3-ZG9*s}~`XYqG|u zOGCMS|9%-C9xXTS+$k4NPnW08oiE>b{f+X*5~rm`aRT`vzaruEfg+ z@{(=k-TdZN=r2z>?x_S<@E5!jebknhmvL54n|dmONt1OqYiH6s-h)jDy5$qch#eKM z@UoV=iX#-pw*RJ{seQV~I5I#6}B(#OZUG8Nxi& zsi{eLx3Mg93c>kD`aIwyqvpZ3Hde~jk8hM0pL?df^2#gaKE48;edZzx1x{GR$&p4* z2&|#hz$;TWg0?N*4eP5UmbZNgJ1BoU0RU|#CZ>}u)l9}mTzg8g-z zgl}#xmnWZkvMkKrD<8dgIcOF02lQ4U(TTD#PFFz92h7)gv)LB5b$;vc0wWqK-SXQg z`6~F1^s$+WOl_FkF>g;Vr+gUq);E%u7!IPnBg+rs?fxL{LxmeDhJ5yf% z&dcS@nWxJaKl3HhGgi@ORlNPd%P*Iu70hI@W|^J4foZ50%BPm7sdM? zCeYeAsnY@9I(~VwO=WbG0(TD7?Lu?sNR_2-3`#zxG7nw$we&^d+=CLk0pBX;FO_!w4DhchY3h*^Ewk=IiK0Sdn`p!XTxr8aI-@U(87H;1z=QdfZ zJy0o{YXOV3JinvDL~4bHeFo%W98%FBAI2Sl`;}XF%hFR{E`R5RiL%DJ@c!&vncvtg zFLmSC{r=_h+CIu(XlOk>sdQ?juN+{$?CK))1+HU~SB@$05J_D(dm2yEd74u?dup^i zSeq*!FVRQs>*B*@UxyXS1AJ9{<=im-h3=Ls_zG!elMW~b??hkbN#2V!9O*5q?(5E1 zaT&&+kR6LuSQ@3GJmyjR4&z7P$V7Q=pVM|@=TOS`m1RzeI6fXYp3u*h+1%7IFaj^K z-chkly``5G4L=iALry{bs1> z*v7H=8Vb?_;(HlW9$@md4by}@D7BXGn=`}4qp9(c(#7eVEykr@6#D<*4+gTXf6m_% zMaG|#U?<5>DDW3dffGf>UogQ>iaVjepM?U?J~kDL4;LCPPIJA}7)Sm6DDkK#%Rm+^ zENuAab1ler(c*%{4++CuWV*3B7iq_(yG9VO=~HRqqBs{lE|y#n)@2B%UTmqzsLKk0 z0CDvdizER@P%d74uAacR5+bm`iH|QcDhyTH#Z{qnbT_O9Z~73L7+76(T>b7MEN}w% zs9)eB?xx5xd=6L!MWVz{I-0^?KQsat5+|O-1fGHk06qlTnTOY-tE$gYgpf>~<@%8H z$TITnC~>6qCuvdtiq*qu{0Ja_&?Fa~iMeU=1IYAQGQ1Hr$^~$R$x%7^U`lJv6)=5B zSQQ~6JfaCmULc;dfni0H5L!k)QyyQEIn5o^Fuik`FH8OZ*?aRK&$6q&^H$})ZTY#+^;-Lym07uG!nfXqP(O&N(O<1_Fsl|G(kwkLqzuZmi5Hi7w~Ez@Rlg#hVWdxiNecxdd$SqGax`^W!`!Uv zS|27T`K{XF2ZA8X7b8y!;g5ovHH7x-*zj&s=&G=o1%lbc5p%v(VzhD8zv9D=IgWoz zg!d{yy1Q`h=prpjXHG4?Ag*BozMwficw1?8WLMR3nE~p1^u)1eQ zdwJp1EJ=2hd*1j6c6gV|RfHFsPZ%A>(e%I=3oe9$3O86tYunzF4_Bv7vIre7Jw7zma^6whjLAiF6 z#cLBvEX(pd4mvF^`8zH&LSx&bzZJx}>#rL@V4R4s%ao4RqPju_HV7o;R|-fv;NqWc zmNaVHmX}++P5j_B3&hog_je@W2baRp5O8s8ezEI0Ue))teegTNo1g7YGc=B0cfkY1{AvkI1OOz~WMmKHI!%-eF3|azl{qK%Q6N zBEBk?h*%YVeDgmpdBXhK=`Vd2Z3{uNLh10I!84-A&RxUVt{NeDGfxX=_P#S9|9d&1 zA#WHq%*8=#H$v+Lgki(%;z!nrAnQO&n5SaSI-p;sZ|+5~ql4W+oNkNRiBm6^2aX+& z-MpVZ@j^L^!{hK5s{7ii6nU~7%{oea9TZLWwU6?+ZTP{2I>?_Yc z^%Rbg$IFlW{qGCkHSV?#0X(&587MWo)|bjFIQZVlX|4{0q2magHSe=Djh};svt{z? zMPya@H2}{!1XQEF?d1%L8HJb6&30lw=ur9G6JIR%?QJW^IBD_93<606pp$beWfB3s zea&*5I#{JF2=HkO){*(E9B!lU8XrXwM3@;(EP?wf?`ySLU-m;{jLeMk2lm8u$9J>^ zcwPS(ak`mysxx-$-g>a^-8pak;Ax8N$u3JC3JTJ*Zv9h{5Ijp8<44f8%#L&U(D30e zgZeTp9)*b>O-z~hG81zDs7#|q8SEb&do7RVvQ!etA=VfN_U?r4m2v@R z$SQkv3_ie){T-Yrym;{5rx;W!E};O^bkPJS zJ1$}8*r7fy-@>WA8&H1Q0q^DK?p_pM zoXS~Qwx8kzAoDs;0m4q@&>aUU=UDmFr=O#L=_!xC?Jb;U+F71IaRTS+JIej{J;-US z|AZ2Q%@~{xtBZ?aiCY9&#(T^r?w*c=}u!yn#t61muRRyf5|;;UA3Xr*#|O zRDkKKO!bt34zN2gvG(gPEur-N9!@FHhai;yUH`Gc*%LJG^-?_ z)Mfn8o#pFLoP6r+6bfJzehU2q!#Zb)K8kxHMgJD5BQ`9Bx zM6+U>WMOi<;@;$&j@S156-LQm zi9jOo*N8wWGX5ID&a4uFuM~lYj~@!5oD&um8O#qE*z080#a1jWm~8Mm=0Vy6ZWe6j z;cq7cF7Vum>Sa(rVv^#*ndhzOzKL|4bcAq$gx&oSLIx)f=H)+zF86Pp>G(Um` z&2{1CyE-wgi909c0heW}-#&9fLAtGHrdgjwK+=@jU1KalMIf5o42HUbw(uQs=dq4)2ZS(*`?A8_%kV z9N#t}YCNXXt!MR3d=eyRmR9rhkKZ+)NS!!dQhw{bX~$!N*XOT(UtiapeBWHHcuiV2 zNo)e}UDJzlMg91SfaViPHIZsK^QBf>@tbFqfM6CU*n;m`{#IHw#dsMCiHKd})`a-& z>Q0D5Xi9c_m9)eL9XFP6FFvzPf-bA^4TGOvSQOrk$Nafi`zh)56Dh8A-qEudyG|TVq zy3XG9vSSdN#EWa}XjI6-f|cTH(!=alSs1t~2tg#PVFfC3t9GCH3R;4!zzo!g)7Fl; z3>F^>tUFnx+n*>nT3^T12f`@@v9{#~`$z>mD(&JTVnJk0pWn7u`w|~VeHw|Y`Q4=F zvsz}$T7}q=q8L$6_K@~vnlw?E7`wa>F0h;`8<;kr#L$O82{R-L`B&NHZU1G~Vd}vU zEPA)0$Qc~ijbMOXaqR9|Uc;#*j=TqYM_FVJlndw1#mS7_yZ5uuUMXkJKZlTIN4W!A z;S&od%Y`%UaCT8w7ojUUouu3fL(S~^oI+*FK)&LFbc6nslGta*Gicy(2&RllSlP7` zyWEz$?*24I{-{rdtqT9N}r?eYWpD>$%# zZ3tsKFh5}lmglA|sBBpJ*j=ZfOsBHOU&YaD4?DK|#`l-G%V!A2A|JupB5~H)jk$(N z8|k{qC-Sc4x)EksB-L@$G8@LQ%{U`%!XOR2ut?BY!}!>u#xr?~n<&4P6R7*XNsD@m zw0%|um^H3K(fZCY(6nkC)9_yYt-=X~r9i|p#?`=xAg#+drmxUDzQNtNP!w%17X8q4 z^W+9~Wu18u&$6h5@RUwdzIf+H5Ne5Pxtr&X|3)-#{}k%#17es{O;>Tat@$*|YINU= zrDgI`@ZfK8R={DsOS{kfHdLH0wN6^`=yD)V&5Z5KOlRa~g}>NXtTnoPPfIaiJy+=;Vm ze8`NA2j4368^GSYyJY)lH@ygec4LyK58>+)m}s`el6TOjU${Dnp8$5J(+}?B6vxQO zXq>*V4X@A;{>vvmQ$F~?5229lDQ|ttgXM{*PXymg;Zx%sk33Yq`(2MiBD?Y_hbJGR z&!#Q5BcQ^b9_e4ET`pH;${;)Sv7z6yg7eymQ!xfCaX*FfcO0Q6?w!GOwR~=Jy?o#- z=4w2x1rF^uX3G(L5`Fq4Cp%Eu9NsxpCJ;dB6#K#iPGD&RhEqV>*|vexa(CCu1GXhh zd!cwu0XSODoVx&jHGP!r zww}r`u6*0{BMPK_<~Zl&xAnPs1rH*4CY&^A7EFGMaglqm9KvkRBEoB1tvk)v`BSl> zQ+Ep${R0U`UrXB2PL0d>+JjJf8ikOig<@>wc`YaGPrLTCjIF8@esCAHC#6kO3TwZj zxi#oRNN)ce3hJhhp-qG`4`Hlxf=*18jqW`XJL@$Ywy``PLe0qwXBbnimwpr!3S1S! zt3(Z-3arz;9jteNpui||E00Pw^HXQUqrzbbG$=`-@-9BKL zXKu>);`z%Ie~ptqIMN17{i`Stzm6%YK2A4zihK!0gGwTm8TLun8E4-2`+pSvAoTIE zoujI|_u-F&!zt4G#~=Ji>1FJ-ZWk9Ym&DjK$hh>z2acB~Kl^92apw=UAM8Z|<@`u9 zQT8=c)A})?uG;&`qu=yM`P4^0LI2$-msUSJNkc%3$eQfp~?kvMGRz{kfjWxw+c_m+F^ zd7ymcBY#N#EA&B_VS2+`%e&wGPIwm{1T&ghu!`SdeSmvd)d z0jH(%=KJn1`*x0(Dg0}E-M#l=Vv3C%Gc%mN>L^2FyE#!djA${BeJ5^8+n ziKR}yBTY`%+&j!BhndN;IJO`E7^Qsh++2ASXYXU}o|a+!vaf}1H=8_vZnBJ^tQ+Q} zRX=U8LoFM0(OE_NT%ql38yqh~m}s3v2^JeUXbUROw?WSaeWNEZl&7X|RNqWIcXui6*FBOjkQT%NvA%lln#+@8vbsQLUz1a5x> zQju}{*I}06b%?-ShYv8Pa0su9awks==P{9S@)Hv;$7CKm`E#-5)T9v*FfU^v(@f6l zg3g6YOm3L4@QQc{G)=%s4igNMYbT5YzmuJiuJP3AmKiyzj7bjhLlEV>2NIhJr*t{d zivPrSu@uShQFmAnwneMCnsqaImF`$LQVu5|&E+$XnflDQF{vcttHY2KX-TE|dDR7` z<&JFP87Y7fM7P35`H%`4MI2gDiQ_V}me*$?XkwC9bBLq}OZg&VlqBwbV?03-iwF;4 z{)=?tX${|c8_(;Lnr`!X^H~eiNKag>iX=8cup{O{z&gl9JbM zKCu38&BNbD^&{%n`sCqe7MplUR!yt&kQ5rTW_&X|kBkp*M!xY{elsH%K!5&fsB6+U zgukQx7$YKCA70#;R?t;>$Y;R~A>i?KO)&(CEh>E$>3biqp^2SpJ-rAKSunWMH57Qf zvyX_K$+SIp1ctDj-wK4x%SE_?oJt2=6HUOKsH+Gs>JCvCc7y#LA&80a1Rvxyz}k&& zgv(F@p_+l6vIZ*cPyAuJ-wQ>dL z(mh?6(ZG=<%RKta@RZID)(&! z3+^U%r6mab*+1WahK&%^RdCiT>17^^~78d(>4aVxJ)INu%+axrT8p zr!;$2T;pdv3jr%_EreMS*D$r53N$5b|KY<3{i|;j-o$RqtL#v1aEx-1ew4vFa4zGw z*~CMC)Vh(5;0+&fd0+X0Z~GB0<4KBb!+DO14R^?g{}Iv+!8F+FoH@+q5YKW2uhB+r zUkaXA6tp8CHH`1A$3g6~ukw5e({189IM_>hR>Ndc4|(W^LZN&gg4r=l;Aj%6pWWMC z^kJUA?sOPn@)a#|tg zjdK4X%z$iPD~Az?|KDGD8PhNH83>|Pyj-4N$M*diyY*3=fV1P+Zgw(1dVB;s@pEA! zYigz{35NTrBi>)Qx?K9ePt#oT!y*FUu(?k^t1xbsycMv^Gd*D2?Q`l^oR)bmPsodv zf8kePwEab!=f?JBy~@S}4ZevT)!qch$S?J!0>OSAz!P6zAM#5GKY8DSGDCs1$_v{| z52spY*j%ur**~I3>y<~TPfY-df3yea>E`r~zE)P~lcgt2x{!bH79a9!C;XyPxth3Q zw>dOK6No^hPug)RkDNAC%JDJ;hx7|kK6X=^cF!=To9_QQTTQum;cU5f_IaF4;~N8d z#AyKKnslig=)ojWzrHju6Zq&m9s?XqRx-}0$e5mzB7%@J8&OPr*zEZ6X%p-&k7Hw+SY z1ZCN76m^R;Qw4VjW#8y%(6&Hddg|P%GKvs&7h}a7V~9QsbU?oyWz9I|iIzA~s(+O! zP6eJqkur(0;r!_raZ3Jjgd4%<$Kj)#RC@Ah>a>@!YPQxVSdZ;FP>x{2=`yC>x;t)^ zmtJ@|`hYHcSEztcLDGziy`0YUG+Fo@#3bjDyY`XK6;2aiO04rnnVy*DRLjn?@96Gw z;tS8zc=8p@@0b-Qk>KN@A^SfSU+^R8dy-ToQRT@E>Y|Rtp7^{@xSe|urca@8d;TedoL1TF#w2TfX?*Ma+R6FJJ%mzg6D)@I&DX)Q4tXwKR<<9Zp@+Vi9%H`AN%KrIFrE5c_ zU(G{4_VU|bO&j#F=}ALuilH97m!36v>EEBbQGV=u-&Gz&akPz7El<31uCy^uy>0ts znShs{-d;}(5sf+1QHT@X^ZVB6dpS~T3$GPwwy#^)d3E5yd^yw3lW-e(%*F~H>Y|zzQq_Q);x0V zRefvNA5`T%Rm2O-1CH-4cduS4Gt7C{M|Q{9^QqI5<^DU5mff60vM;eO?eJs_{fXuR z*&$V?&!0y5yo%opi08Sd?|SrGLHgUedrAlIW|_~asIU&gi8`QJ)|eAhzflJI6lN|c zIXH;~|Eva&(63`cu6zHTWk0^{JhkK{OkTlVJlam*F}U|o`9J?`ZBv=?ohUONJMQR~ zS0a!I+|CH3BI9yg6Dsz&p`(*M|eYA^nc` z1c?O^GZc4t#z_jNX{~uogy+NOhK~tdylkaG{77Gv&BuS{6B7tC_eJX>9hY=2r@aUk z>6xw*E7OUIBKL;!zd@VlKK1fGzFX;79`lW8@w-MfjPy4N`7@FU5-=S@C9KQqu~OUylzd;--c;jwIZ9lz%t?miF`yF#8E2X#l0yg+%PxO-o)Op zO?G@&UL=T@$~51ZcZBgn4mX_^67k+Ug80D|zi;`ru7h>tH^Sen0Ru(CX3R}1G16}o zX{`wHKHf?%f5CyK>p#Am#j^cGC%b!HcxhACuyNGBjh(3c>2$N&pswxRxQ6XQpwP)K zYn?+YP&69_-I{Q*{|F(eizWnNArMD6=VGykQwBN#G@V7_D%guOfv5)`4I7vrSY03v zi&zC9p>Uw2O<66I3Q6PKyjt}Y52B;D)roc;p}jkK74TY4Ph_Zw(LR2Z0U?q*PTNsfXew&&-a8S(oWedi zJ|D<`*%JadjvO6609UY64BNab>)82a$DyV+WVbbUoKZ9vt+7iNorm?K@WFoc`h5L1 zz37jKw81WDoz^OV3Z|kQ3b_^DZ$pp~&ndHMdWFJ(-|oT{UzITm;9NK>{LsOs{v|A% z{!i?S^~V8#v4Gu%KqiQU7j@`u{fe6>Ft%F`@~A>^@>E~~{yy{5#kYOj*q(#f55E@A zSJ*{rz1X+vWO0LCkLx($BsR}TmvTs(JL*PIVjRBr%_xT^!@l(bf+&SWmrhrK&@#L9 zRJ;r#G+V@`w|20tWBE}9T-V?zG$OcRvE0Y*PpY#_oH|Ka-Dz3*sP5)e{4E8HbqXO6 z;KgEJyeUug2bKxQT^w&-R)GT$Vlqg9r2+}+T7koLu;1)= zB1CP+F`g1d{-Ak9nCnVmh+{tfDGc(ed_vj9miur}Ph5H4GS#L*9NybJVtnJFavu9X z^Y`*phTYpbLXQX-Piy-AG#`U{qN37J<99;fK>zmg&f~r14g^ZS^W3#^=B(z|Du&Vl zQPHNwxt^*3d+4#n+PADW?W+Zt{A5@&bcZE5k!Mg5b>#0ucie%nQ9mjQlTiR7RKJQq zC_=&SD)mC>1%FxVMmMaq*ApJZg9dS|*i@Rl4%zwJqub1I9 zloRayb$9MOehx0P<@uF)?B}Bt9$_pvJ2g{oK;w}PcENLc;2P$5PR_0(Ox#zlAgJ!V zv4nDCt-OSfjKgDtbo*x}vV?YL4neL_F)=?tW9y$DdPZ-r|9o<}h>ha$t%$qL1JMb#*D zt4eG6R9qY17>yv%@k~XE{i*$;yr?qBw&pWwQ<+iu(mEzp_=8~7KME6YcBjAT$ouk- z?}ia1JAN*q(CP!HE131t#E^7^b8nUK{HYA^w1YesiUCdnIG#^q=0_SkP)^zB%VTW_ zJylkz%4D8rb?z;P);PscD zd7@lC`AqDDj`l*_!JWHc-8y#E6E?)bY|)$F^f3NkhS{Y*A7-3pF+H_obP)WP7%PV` z5p}-2_>$%qyF!6+_p!qWeW%JP%r}h;>eL%^PXlZMn8txK<<{Z$H5_-_ro_`Wq(g3s zj0vMo6c95A&3BZ8J26>Bx#y{;!{eOhBd!~@E^xxgxxpb%7|zZiTxASmd|0Q9!zf>{ z&cxLbCq3T#+wbL+1=tdP*Y4fa+X|*5G0z4)D=XW}k>kfWsqspg!cRvJCpt!UjNs7z zdO3IMQt3nKIL{bm{npJBo}QpS;jtd(R`O4n@Ff3r+WZQ0jtxwE>MLM)6!TRtyaIn< zGHYxIUSux9hLh`#pDKN2lY`zk!bTc-ljjlXaBD94R3y1IeO1S?3kw=^^Ia~2rUTs-@upB z9A(|j&iu<4&XlKSIi*5@Xo8h@X-5;I+`+U+z4#r*K9AUq9nzmS7)w<#IW2?R*);92Jcw!d2yU z9dqp0s{%d{2Y1r4uYmXLPeN%-9*m^r#dDm-IQZuBvu{6C7U_c*@qhFLeDJ3J)w2KE z%jFBJy*MN9B@MPkknYa05zK0FvSI=gX7H}hoVUhUOx@b90E_-i9&hL5H1i|I*h77* z<;6>L;TT*-AZV1;HY}fZcK4NoD96up>UW-#QYwO-ve-8{w~%fx%V2*H<6rAO#%&wD z7xlnLo&OQvvYL*Y2vS-^eCda4%cu7axX4y@>Zl`T`_4QM|^dnqh=8HmBMF#X!J}baJ z)qm^GWyy0p323IuzIPk#Pv`14?tZj9x~mHxI1p_|=hgbMWZQ|mWB{_ z`k(OTQ)w}bwAIVFRVdJUK=h`(HH@*OjbK4{O}^4AeNhmD zvJf_mm*Ktf*2!bVECSW{4IYN&pOei99GOK@Cc-1)R7fM9AGH+qwv`=0&7^dRoLtftM*W)#I+-*E}S-=2$lIF zXZ5%F)LLl5`MgQH346n_w}~P%iQblDwwm3q*4D9 zT}=HGGcGIL-+aqw!CHom`sYUtWiC8y{TV0X)wjXV-g|9E@kbLoe%6nMcESf=^0e}& zn6=V#VZr;T9mC0kAweKSWJ7I|P8C29mdD1`jF`RRvU9=0l}Qg5S?)= zXb1r~3)E^e8(x>+l_GIza$*&s#AaC#C~3-T8KqDNccp>9jSc9d-mHgkTr9spV3@#S zvDbm1LQGd%=2i5C(T;fsuNz8y2rIq%GcbM?)FHmX$)W-|(>9L1h?jZB$q_*yeb^xu zl`0TSD}=@@bp5vP9>%QJGCST@6fE$*7n4t#thnP1_f@BfL9)FMC!#EZ2XNkg9TQdy z2&q<8e1N^B2thXAAwWjBVgAvKN!M@Nk66_3#*oKqJh@T63I(2o`A+)zY1?V~?ArEd zi#(Gx#Up-@l76HVWZ71Tg^&S3Ds9ku5`XE5Z;7!VAp8(Y0tK-%v(yI*@y=0Hi95VKNqL>JR}(2N%xi5bG_N+uQC^UhLb6)_-dkd?ntv@<>k03omy%xz zW}M+6m1Cr*Fdj1(+b~x$IW-%!sZfi)mwatY=C2}0VN1nPrGPv}zX45N<`+U@`~B8^ z(9Ltp7y@GI=;-k~5nLkp17F+i)YWS^+r1KT{HS$OX^e-&m0rV(xAoN2o8MKT%6s#N zCTVXjUN=cVAYof^?T4EB(tMtRN&8pnjXsKBniGK9Ix>^X-Ui1mnjeWI3aKpKq z*7{Nat`JKu&{T=ViZ%hybR)F>_~)N2|Kk7pkDOv?EC2oXe|I^JFz9#w@WbWJZ@ja# z!z2I0cRwC>&bMR3eEZT&=~}^|FOH5E5LES`T$x5NtqH7+&Vh1y9W!^>g@5X$7cnE! zRd%72IoywVpv&hGAabIF?cme+&*)+Yx8}3t0`_C0i0F+pmM{y4D7O5`#Ckc1BjN4r z?Em=51@OYTEWU$g@E0QY%PZaRlx0#$b9i?*bl}$jrO??cDAMWMyXg0Zj=AM4>s*2M0DZH{{y7BGhIJ!BAJ0@4HT869`Z{#h6HN;0ty}vh$Eiry z@m4xXM`hX7t0>dSOTM;`Q0d`GjPQNKb5CPv^2iKqe+ITa#UHrIGsfG7P?`XI^XD_$ zFwfek-@&n+W%uqq<^0JP%jCr~Wo>bebnQFfFY*}Me@Mn7EocMh4)WiD!}*=~k2reA zoe{>(Ro598h6eiK`2~EZOomyhMdl6r_UuGC)j=7rBix*aHXR(JB%)uNUzkUEfFKF9DH+Ol4PFI@1N&)5*H*yO+M_K6N!#dy zP$r&VDDC*O=!(95l>P|QKnqhSU>K)y#C@I9LS67|2Q=)!f$|%V9V(x|G~Es8d~knX z+1tHRhTxg;H@>SJyzgz%_w>>qXa-O-W<&ISy_2WQ$1b60!c-?PMBiy!Sc8Yf!}ew0 zr3o?X$F>2K@D|U8_LMi>eYl)QnRN0RO3yV+mCY+GM{sX^>fAP0Pn>Nl3v1gki?+9n z^!Jpjm>fDf)LZ`j>FF{CACF_&sSPLQP5X&)-5N4Ou4oswW%9Lewm!Y=C+vfxZkeaN z@4|BV```AB<)LBbdGOs+FJEB(GgJOnFa6fU#q!zhJ0ned1y3Fv8>bJPxKz%vvB!0? zicR~UsyLwyTYgprpZVm+aSq;5?!W(@^1z*k%eKXda^foUc-t{orLy)*kZJ1Ch669& z%Hz%RN;~r$;}RhHCDMpK#Xvk0YridJ%wPEJxaGY?x6f#|bLj3b_v{=loz&y}&ZBgs zgJlTC+A}X-D!ay*kI|R+(6gV!RO-1?uatlDz7Lkg{ckJ3^h0ke``YN;>C@Xem8bG} zJ2b9<;XHnDJgwW!_|V6xF6V}pFUD)~jk#X*NzD16#SJl@yJ>^wHTpOXE~6ZoDKDIO zzI?pxNco4~_DC6IZnD;tmG`x*l!KruC%v4W+^Wp@?;dF@_wTFtMu7ZC1QLPU3V~E) z+*Z|<#Qse|;Lbw_qNuT;=T}TZ9Jsk$I5#`1TTfzg1Wqu#^;MI1{EBBW&EnQ2IiGyAqC%w$s@4R` z2!se4d1g3^VVKs>2yyF2Lxayuy@n(Ft(nB{2v9!=6sII0!jx<7zG~&&N~@uo+qfX5 zrpx!ud?T^IC^GjWfbcm#0j4R(%~a~I`gxP)SHCB+g|CS=LF=P zcQ?NX)6_H5-AK#$v9Oo6&G)S+ERdM7Q&$GMSxQOtuTj2L-c|_cQ!nX-$s5}1!)Pav;Ja3dTIDrJ(A5OyJ96IAt!4M07dC&!tw%A?FtU>RJrlp84Sqf}SyAy#z-*A8I*uRb)b_L`LQryMw zLZ^e>zzVx9s|z}J7HT(F=h7+$gr`}2)^wqXFbZzk@i5-8&7JuHKoque57<#54Q6%s z_f0HC$Fd1WgpYowC0JyE=}tv=q{c!ErHOE?vokM*lE@{Ou4@7UVU9u?(iq_QKRM#J z;dniV>^ppFjB94V(cE2vkfFOPVcmU-z6yC3J%F32c7@!WaMF?SRr zLAUfHs4xu|+<_4oYCk(ph45a5k9qqt*o?YTp`ZfA2c85|C>4Ar@sJRwOo#*-L93@V zB5i2zz!Z#&(eU}90EOQXo_8v&4Cm$h$Wz+njaZ=bf^@6!x3;ekwv&EG_W)R9?;K&I zxVZ?gWh5DdO#Q>`Oocd4sTi({MX5ZeeeLZCFBjOUDqrb)LlX=gENU07T`t?Zhgl$F zmW18ElpFyE1aeB?^2;Zp{F;#xXP6HDVJG(FW%5N}J3L+v-1{Jc(G_+If3ZwsYkd{} z0AejaS6-xy!C%VTXw#G}7VUr_40X3(t=qtldhq$peg#s*xdqy$AOS1`qv+r3dxH=( z;+lqGwMPw#rbxmFJc;LDb45OeFkdvFNu4k5U^yIXLV#bIHwg+=b>{mxf)PTi_|&X4=^{938q*`A)KpYG|M z?m>A$v%o=kMsZ#4jn?J4{%q137~f4Om1b#phApY$v$oPjzk%YfBnBt|;s~XM0l6!w z2E#Byqd$DAH$o{s>G*VWavUV#K}25l93fuiMszrpKXNH4UFop*9!I1^Cbs~rWEAIpBgk}EF09IFoM&zQW}nx1b0ku?aINVx9egu- zo3%^Hp$!o(!JU$~2e~RWE5t&DbOld(xpy;0x53Y6upwkSrnIsqpZuN=silOC}ceXH0{5)6!spX^`$CUz#s&`p5zB&!Asi#1_mQImP7`Q zqeD5uyt4Ui7lD7M@L06kkFf>SM(74)sPtG=rfZ|xvkflkQfleDqvhfm(+u0b0dqKn zJsLX#jEcp^+)+$)5NTo!hu%#Jm2wKT8h4g`nAdFrBqIWa=kQSiyh2*EEsuamdsQ#B z0a z5Lw0nLKfrbSlNhUMS+hxM`8|lccy?bxq2tA>x)@o$}u6LL&6cWSxbBapi94ssuj!i z*&j(z)q6L`ODgD&*rD(tiDjuo6;$|!-}g}w-2P$5H5l;W(@L@F9*6vBCtv0kx5!7I z6Pvcv8B))=@QFU{CRU}*BbmLU-eqN^_qHGD*DLZKC=54)CWV z2XM_Ny3LsMa*3>UzBo2RYD5DAI-M}j*C$2=cE4&Whr2h>dJi4`3t-70CqvStu1iAz)9}<=VYjIlzlk2A z&I<$fE_RUNkNkQ1B(1{V^sT}N-bh)!bUL*#E$L)Ep!q}8JA6BGJ$kO0t?x#;{0>#} zZ*faf405iD0t!z6QK@6~?H7!%d%WworRTin8yvGBB5y$vm zeiD5+Pe4&6Th^_5Z|{fYQW4D;0DkHC z^wYBg{eAfvxsnQD5{0Cw-G@?DgISGV3ZxVxM*Y6PH@qI)I|hGa;ng0GXmtB z8R?zl5DZLto@{3U-^?2csVPqwx8WLkKUHGv+*`}g(GTt~VmBeG+H>PC5RXNpauNcD zx8#i0v43$_UkhSEPi0a5J(WeMsrB=b7csC9@s6|B_`P_7gw7%S(3T?O$1QvoJtDts zOn!3qip1naS85un^~KRhCjzk72WUs}d+K}%V}KxQx91sEUh5N}Xt+2%ktmrED~_$? z7^2@FZk!hJ@mjq;s+>l9Z;7_qFGE^sJS#)4gxoN@$^sb_q`1{Ci|S8MHPwOfT~UH- zg!P95F2m7X8Ad0QrV^{Y(JdAh@AXx(js7n}s*kPdhExmk)uFn75KRh*LTsJe(|we@ zuQxr#^d*#hNgvc=GuCodiY-Z!2Bwin9~NrRVpDjDq_qop>z`j=oxT}Le$^~E*1hcE zl3y4Te9sYkU)eH*EEK){iige|ZKzp-q+f>BJ`&(4<{`whvA7`5`CD*zp{>eCcC&-m zRkhz6NYQll&VO9c^0I?h^hLiqOlupzL%n}-IwQxa(;<0gO<>2ez`&uUn!rUtZ(pt+ zjr=Dph7GcmUPzgmy{Y6UaSaYTK=Zy?IwqbcLhOvT1o%y$2y9Um3to5z2L;+BUJIEk z)*{k*g&;Bd>LT~8#v1NTt+9HZ;VY(JZO!MjoeMD!Vpd9|NGY@^7hhgmiIKxtQ7v^o z-aqE?;+ozx8E@H;YJENgnS%ZZsasi*M##YvFH?TmD$JgWa7Dk;aSw>pBIzel9r;HKquIe# zn!Qh)q+(knrcQWXRG$59PftYYOW;J%#Hj zU-Ex^NXX7rW0|jb>JucSO7$tdEO;A?|1~7CTIaI51nFQsN{tDOj2|S1&F-vDUikz+ zn>NHQ!ZzSw|14(k)=DP(m$ zaqx=49P>y!q+Q~_D&<&IxO<{Hs=eN4Gys5OJdN21te8f zVO-!U?tKv9u2DbEq^7dDP8c{*j@K{$S}JO{~9A&{Uj$yYwwMGjt!}dKfh@yAZ^vG5!c~&|Z>HMiho6!`+dKUhCQd2Y zb%n)NNWBYVMCiGPW7|~{7NEJ-x&Y3d%_|AObdC>f{>~H#k#;I2F_DuG2zA?6Lxq24 zso^u0F6Y^CN&;Avl#&prN({E=5rJQZgf#F`K#B9;0I>-ywmqy#^da+m;E$g_H3sSS zO=o4iwQ|=foTxE4#n{U?+XFn*tJ8^Sjpb*j(e~jFTHuf!(rVV!ppsseg3%7-jiYe#1bHKXq%*4{SXI)LqyoYq6P zebJ>_1cLN@Y%%WGC4)s(L6;Iz z5zlSMN5K)>v&wFGta08a%DKu-N+U(28tMASNh*0F*1)$`53&2;>)`uO)7%o~!gK?W)9a;QtZA?z9li2t`6SAGzb0%YE|-Pbv@TlqWQ{vq z4s)F2m2@)RoLRmTcDe9rSUN6Gy_ygBi7Yig$hah)COjN_c9rctP8fFLPbcB47}BwJg2nltK~d3aw^S6NKkigO4TNCK zp48exuAsuR!r=?%{{C~oT&Ox9f`1Tb2HjChL}*TTDt9jghIYN^TWISNOO|?1m0EQa zpA2w^Y8}jHcL3Y6V`YX<%W>0f=IhRxn>MumejV<0t7o9}sV;`SJy>1zk#|R99?6B& z$A1}n!o+Np{^E!XMQe49q10m53tsfTP*T)mwiTrjYi&c0l#~TjeLkav%l?u#c^c~P zaj_NWH5_blw;SOMH1J3cCw+XZv+|6`MxeXc9%L&oW<{A$m~6NmbDud7O1gsCeLmOI zN@6x2#c$#+1bHZIMNem0;zv@XdX zTC*V#FWOl!(b2s5?4o#NEK(zxX;j>q?X!~(3XFRp@Kekwv?T;|A(Ar0iN3@D*dmR1 zkp_g)8-&X22r|4Pjvw)lL6hYlzU?7?!20R0lzvLw>+{B;rRxymyM~V7f$X*N6WKs#_fUh2HrmWb_389wf@>A{ABg<7G1rk36Q4dg}~4#-(o^_raqH&L;= z-Qb`HNM_G)y6DWgD{jS5>~U7-*%FKDG`W~MlAL|d5>&lMyd0HiCRko(-SRj?DsJ_P zNMDd#I7mjKf^BApy$R(x?06q2Y0OCOc%KlgDDt7^0Y3`37&5SUQZRh{W3M_9pY|im zRK{Q`HZ?7~A8#TjVe7Oh`TSQ<c1=& z)ppsMF1FK%XEQX-MTK(%!=}C;MrB^@X}{UOW|-sgiP9r=Uby6)57Zy1&mUdFlK+xt zw8~q(h_>^LpXk$trd|8>IaVn84}&LmcXHFM78d8XT`n&|mJ5fNVTTjmpOJN%kHJ_J zo{Va61Ft1-lv*-Mc8aG$We1YgvMcr6tF=}qYqSwUMQEU5Vx+>1QU+x#_-cm7LI7k6 zPu*;71tR(^k%Rq{tw9FXonc#grs}$#J9c4>Btt53H0{UwJRN25aPXIT03!V$Y-sL* zm5)=j-l4~K6n$|l4?bK@i?K&(RIlC#&L5sbjdB_pr}rgq-US)_YOT2#q#C9;5WxAx zD5L(NEv!dejL(@3FXKk^0xStLV|?_s_O0l=wz0k8L1nzuHEi}-&uSPZc@^GN&hI1f z-n<$+0>o;yk0;~U6sFxF1(IKyzKy*V3#Y|dRYiC8FnJ6_n4$=>t5v1b^k5F=k4ocy z;&4SXz6im2-V&X`;A`vegD5(w()odvy=(v1E2Lm?i) z4kBdXoImVI%`Q{h;9-4s^iXBV>(k!Dr1833dEQC#P;o>ct3YzYz&^JB}r zT50BvApG~jWYtYgc=wEOj%R5;rssqYJq$-bsS92Vbk<0(3{6rI(AFOo5d2Um3LGfv zZsjnWF0=%GOHwhklwlV7{fdWh$-pljud=MG?1#2n zZDMVXR63Hj)9Z8zAEXEgKJv($e36q18$@~ubU$6MOG`<6Tm$`di5af%QS9O+^8BQe zwBU++BI`fVtarcrn_|gMXHB{xYs$ zNYKK5st~#F*(yyIt+qydWT}w#%VMjzF~aQzLzJGyvDoaqlyJrSVF9&mOQP%mLHq_= zhPXneq?K1*%>84!hm}Oy@#)u-?!HthZ?F4=Dvq#+Tz^O?BY@QJ*#N*SC@3%L+rvP6 z%w&ZhbYkcpS3MghOzv!v@I5!HhqZ@~w(?+{>h@}P-`4AulXiU1<6UaFqpCjc-Khm) zAHWN~(*GmAh(r!r{oqIjtKT6(yM^~p2?#T(>&ih~aD zX8*=1@JG#k+sO1SHfOY_1&|HaKO~d!@^ycm0owAX-jS-pp(OUjFDV;w>@fE`3;a#a zjOtORIQT#^?75T=kp+nDKhC{OPE~}ZdkKnfB@SPJ|b=p=LvG)36n)_ zc4kxiz{a^gF6!BjaAl>B$JYb4T1baNTdi$&!|nj&kB~-9Tt5-o^Afx8W4@C%Qjz)a z;F9ot6<&79S34uIzKr^xDxI#Y_98j9j%H$nr3Xa!s}Ctwnu~(c_f8q6=1ca<%{xo5 zwC7eTxy&x=+H!GCl3V3(R@m3vdEB?j_Kgfo3%3ymyWwdGy^ZkFC(2PrO#HgUEqwS2CXarUYxiP~%x$o1}sO@405cPxx6uoHc$a-gR*^hCKOr zLmzr0pnBkVc;O3S_g~bW%Jzb>cu`I7h&KD0)cW}LBgvX(Ri5mz^-?MN3)dxtJErwl zgxqP(l)~D^01RtC2N>4m8G*UogX7MH!WsdvM}+1;c%5zcr+unNMtV(wlvYa1w114} zDZz0r1zXvd4z0}nAb11(GINs&`z&yAl=;@pjQ?&3aU8=Jaz7_hol;*P1s>!35V@j> zQ%9JzA<*J}E8jXozd(*daTjqX#jp)fTa%sV9WMpd+V#~AT^Yk6oJfFmJe_JQvxcq4 zy3keyXl>tMUW=QK=*X`f=S{BgxUGw{c>5C!+paCd?l>=58$C>FTgtyas9Oy0CeIBD z5ug;bLa@vb2_82lY);nK`Dx{&v|hJ8ak$ujbvpXhb<{w5LER#LSzQq?!6N6!<1QAw z4I7=FO&tLo_ZkF0Kr7SMAFpGH>26rQFei>T+N~a(igB;X$&j?>>=5za)*Gq71G_v>0kCKO94>sz`1o zUNLxkNIO>jvYDF{Cjyb@_n9UfJDT+#$H4f)((UZr*l~E(oP-5-CNbjezIspx#N`TU zZi1?Y$EUm99O%Lhh*62*Mn(70lVrXNyVXZiIHYvdRC)w>b=#p#!r$7b-`wvD9f8v8 z0jo2cAU8-@#B>?nrh%rKa;MiLs<~`+lFS9bT*dHjKZrI7GF*b{c7{pVP7+Md{scHh zdAbNno+vdBD^0QQ*`EA1P87RAV+cA=mhX3|%CJH%>yt`ENnaD}BtKwBpKf(5!p;1P5-fLT=4mk-% zvRXZS6N9Wj;E-?j89|ch2PPkzOZF-OWX=QCzMYY7_`eZ{uuZhhN$_{jo3;heNkNfYrhU)c^ zXf3}~-k3CL@$27`a(ztqMgTBzt~J*mS>;=T=`VTe<9CDeV5JU(nM%71B+9~W{TAshFJ#kqrx`F<_h6RnRFfaT^?-k z#ZFix!e8W6I)a_6CGY`BMYzVZc;i&nhdFEICl9KqiVWSGd6^*h?q(O!0oZ0@>cAcD z^M)biYh}D>xBM_Nn9L=@9F)8mbh4YYee-~z=+iVWohz;&V^toHhSlzfD8NO*lP}T_ zyk%U0$n=1PrY;WdnEAn4IHWVY@f#|^ZXMgGTEPa~_mP20pAqEGqAe0CFUJ#wvym(m z+ifL01M;>uR(r9{yFa#!CR;~YhYNS|^-8i8Q%H29)naOXe(Q^p(NREBP_?aegeDa& zUV{`DA6S`;5_Frsa||saMy*!}RChC19x}%BBh332+;%pwSUdK1GQrxggqSwg%zN2j z99>XJZo_FS(`n{AwQb6DjbnE2g|BA(GD6eNjhn*?v^pYjHrQm-bn7CU{8!75H$zgj zX>>jUS1Y3Q?HEKX!DmT=5KukfWF>J%#{-*}mSwR_VU6fVXh0!|{5&GGQ?rDk5H;|U zC!{uekrm8TkfjDQgOoW)|2ZC!z8i~CD;Y?{dRqOF<1xs1P8)SSlMjd8Q%B?~U5q!G zNUYp$`0luU74NC(d?XhXDM%=|gMm(uja>tbP?-{_^J4#4qUW$bNw^h`%)pVL^*}zxR5=hK zKoxB=C$daP}E_KHOVJMsV41)RFzEDN)ZF#@9dxDiVce;c* zF8b%PzCHnmCnM|M3SWFn0><0i4?RUuP{)hje36nivzN$kp8g7hlcy!+MaQ*`*ll(w z@<1o~t{eF#84l@1#DDhzB>I|ppAx>@`kWYND*fA~;_1xax8P}na(KMCYv+w+z_PE3 z=sI@?X&{iJB>p=)9Ebj*z}qqSQd&zJkBr<|qA`Z{T$LO_0}*ehy0a6Vn0aDQADQne z-NC+PP5qWTT;>tDZzk){cp|EayZt+{3x*FOPHvSQZooH!Dfr{pOFUyHwzauZflp7= z6YHu%nYBJtZ~ZO?aAq?v_`~{aBe2O?lNCbHsGHA&AJ>~v508-67JqPZcdCAW5LQ`E zFOy^Yb$6wtJg91nro33pzl>b`;yqu+O*|@zZg0uyuoj;t%qq zC7cxHxbs(254IrF&}0DxLrK}QWz3hXZO%12I$nT2s5z%k2GKWEp6IxKB3}{a2Ue1o z%XP{U@dWfpU$=6mDqq#7C80vJKEVwnP(k(f!+SGH#J*3yy34eXj>In4bmD`@>7QFe z7(~ol;Fzrt(BY_RShny3$KJ4Fbawf2Y4=V`1qd?|UG$PBi-lEEK#(ug=?(dvo3*3% zLu_rWDqq|?N*&2rN3?4V72#)Bf_@m+toN{`+@2;$weAs4jsDg@CSfI#5PVul&xWh< zLJdtiy2JSE;OL~QOqA`>^Gkfk-6m#6mhMS~gP@UforyD2aRiOeqfM~(p-}7aD8X1m zuV=+;9$IMepM^JO`%Jf#(x8w?>9q%Z_Qt!l*N1y2$1RMbQ$S|dDP+9a_u33#=6`3N zeoVv=*KsT6dA6;$(v?4ffS5r3n!;7JL(gOc_;@#sFQ7U$^93J%BztHCer}QPQkgq%NTV8QqQjZs( z30%?C90M^Zf)TG;f4fz$52haY7yKqGkTHUzU zVpj6hHI%iR;~kr7F_9`9W%G+&QQnQ^>*udny}~{!UzYr9)q=d%Bd^JxEH_#min8>9 z%rYLaNurrw7+7<=bYdqA=?n(6k1@?Kj|J=gh)~NSZ`PpO5pv|3Roac$uJKTJSDICw zVN^FIzuo~m+J&Oas&FS@MLh04dpVg_`3&bw&AIG^f(VjWP;GVU!ka4u)tb;YdPeW5 zlf^0<5rK+=2PzXWwxxIc4EU)qp02hH(QcbPYR`)4QbsOt#W7=N=T9p+2XY?44-R}W zr7_m-lj;QQ;ndjzIX@a3m2xiY%dyz+bD{ZV>Vw)hz~=KYuX11GJ<7twItj~_FbYWi zRaadgux_x|2`9hP;*DPmNo*%O^^evn{xKmw@83*aHxbY*pS0riIg`WMnm)}3ZHed&h20laZQHKfcMJ?%sK&5WOl!(`aa9HhrPNjaVFTSjmSDX}o zoFVgkVibw_%fng2i`hiq;!qFx^L0b$jDq#wZa9B5fsaW@^&c4@NR z$)+7-od=(-7ygV}=5&RZPD+WeUzK!9rt4ivyjdMvzQ=W-kjxR&5esskk2=i6G43$6}wZSDvfEAy?$Dn|in}VtW&R-lf%)M-ArD@Zpr8 zenvzsb8~k+@&B|F7_nycHV#XRi7U7WA?|!l<8hf5mHoL;+!pVd;r-&`FFBAUGoeqR zu9uR1V`nS7U`;H5S!R%n^yE=VB*r^%Ys z*YV8Q2e?w7X#l(i?2cMFF1A&#-}dN_9lqT3BcUCPXWxr{9vWIHj*<(X_TBAI`~{jkF*kbMuxW$CeO-{sKqJ$PFLPB z8@w(55jRUuH{cI#{YX<>E~(la-rnOB}f4GBNE2)IF9xN}jLLVKd5CGV6&=BoqG zXNgnE8v+h~_XMbYRSjNh__qIRSoPCoAKz*$x`}JZeLC4}N>6!f(P)>9t%hY29kO2% z>A;*-Y&r@AhsZW|curwcEce~|z#Vxg2`Oom=PKXU8`^zzi@Q~>Zsz7B$pkn!CoaZK z$p^|>Por_upPWY$YsCe+IAcVp`~{M<`0;5i zsngB5?dIgnmgv21Jdj?jtk+7XRFc_!$cY5&jMyj)d=WkO((+X0EJCl!dlc2xQM`YX zts4}FHE!bkXlq{=*L}ajYTJyx=~aM&@vKXyx)hxZ(5&4pL$hB_P$V>K?ksiRd_ATe z?|x?W*XX*v$Oa5=y60u-LYoqSW?7SfzS~H&T+(9#@`wD&@-Y`819Ds^o)N^?NDX*v zZ^zT2Su#5JJ1hPOZnmaO5qC7e&=)Uv(~>jb!Mz(J$t!nas;a8-`{*wFpYv`@>oL=Y z7yRxs-k|*+N0o;@_!m^n$KRfQekfuLz{(O`^8*E>yfbxXQK`s>s=avhG3b$D)BD>g z(3wjq7P=rFc}QW!ZUdZ2w@@XAiR-(1*PDdvvnC@kYoo~;9h*kKNrfy8w#BZVHpzE# z@fHx=E*s@PXv{vz>yyjG4_zUhCP{1n|osicrJ<#59ea~ZSL;@ z5{U%%eil3ShAcbz~#_%ZK+gZ%Zxl##rE!=K0{4?j?~pcOqCA_PZn?rb~AM zD2+Bg9P5Gfzo>CQIX|wADI;P+VC(5L0i%- z9A5*>a-Zfo>h5J*Av+EXd)eOrWRXd)2ZE%muj9ixtfY^;-D;MGJ6z=F>Jzw^_ce?@ zc*PRY5e?eD>NC6;(W46}At*BZ#Lwmj~`sHzLxuplFd4TC6I}W+rs}uLu@58}cDWG#wZq=i?65f+D zP?2z(SD9~@@+Rm@9YKFIQwoa#3hG^m`Z=t?Sw24LmY|oU*KY){+UlEPx!{B6(Y)L` zs?5AOEq||HMT)d_mY%gteX`9pkw zI&6UtwJPq!^si6A4(>6NkEFgkrYrq41Zcg5wmWK$~9) zpn>$e@yOop)tBHKwmKegp&athUAt1bJRV`3C2q^Tc$Fb(+mO9N4#74{I}WFYFE@XT z&PA;$_aI}0-t5%lYYSB`&TuY;zak`hpVu{s2B8-m_-v2jD*$ik6-TpKN*6s+UXMv% z$fjRgp48Uh0EFEyvwWIYt`HqBaF5Ok=Y#wM!2fv-FwuoLuHrM^4=_|=RTCMPYnoB? zDn>2P(t!&ZRXoCVNY0E^h}ywMD<}gR9xOpquP~uY&aJD$T3z?V4h$Pn+T-4$kCG3| z_)|a8`6?AtIY}Qd@I2{8J&Y?KcT#~ zwl=^2i%)uXb_}rOi_xQ>scFH)B`%m-XEQn3bkx#>Qk@v?8OVD4F70BbCAx0=&(OG{z&R<6X zxo6hrmeZlQ%=kOnw=gD3Dp(_uKx|s&0p(Lf63^{%#3{`G@J-EV(9yPdG?PPU{<^En z49t<2XYStQKURYF?D%J_E_tY+uMC0X z*8h^*>95?oxJmoeu+=b7=IVG`!(mNvnM`r{t^4lV&KZRCDcJuqS$fp*-&%wD`|EF$ zlc@fsHBGX=GlkKUmis%?ZJvKb&-?jvKysT=5(*q6a#aE*EKg=6KGlom+P&%lnW4wW z@BA(Yis_k|jF5XEYhhtwb!fx8%zs4k>$MpJp}h(A*x}1q)SrNNd3(;;g$WM+Pe)6 z;Q25-JUng&#T_@}GNLH7o;Io*90lkneQ`vp%m|T@mL9`+y~Ie(1xMu4g=3J~lQ@(C z0gazu0J#;(w}jO+<#yimq9AMU;|tH*>yCed2IF#y%f_QE{~dh4{HOKl=k;91f&--2 z6=>UD|BHuI5kB8X*M|k8=LL|;>#-;^AtB+__pe`n^O1BcGC~fQB6Y%4pqg7^gf)tK zdA9PuvlT?L>Z6n->U>73g>0 zKHeLQ7&R8N^}Mkab0{Gp0q_NS8$EN1mMNMW4OP{mBhP@6XRIetEAMfmulZ zS@xO*Ot9V!Fy|Mf*yynsbS?UNojC{@&3zi>vtSnz>UcOCfA%~S+|m`ftBsSYsn$wJ zc)m`R;NPN!+UXV!e3#ZUg!L7~>cCLm?676%_cZL^0rq_W0YEqND#N*H?(Xg>_Z^4A zfKva*QUxQUtyA;^A|pc&%?t#2czb>LF1%-moj#aK=x?wZ9~r%*8*1s)^cI#@ISa{Z z3q$C#$0#E&_pvNDGVue=4V>sD9H80nw0W$_ju+u|)0?7yJll{ZK9*Pz@4ngZX(aAR zHjU(=m-ML@R4Dpb*xdE_?ZMZ{eNU5?w+ zCdYF(!t?vh(Jc7fCT3|Zd2jrmOlU;Uc|_0BZ~ty#gUWc_q!@^4-qy9p@!<$cDc?B8Fdg@&|}#^6`8xnnY0w;onftqq*-qO zpwUFix6=9y4Tl}?2l3$Ydjy2unY&CEx1o*63(N7di-{@!92s|ylkBY+EBCvJPToCs z4v~j_?BliO>SOt@QOr&8yjwo%t4(&B81u6-q|8tv<+2j>0XwD(c{y`NK)V-aa%B5G z9xIy`t;n-Xc-Gpd`-rkqQ6e@ZG)Y}~c+S=}VJk>v+cq%GyX`sqdfzH7+CI`VFhqWU(CNPME%4|I zLAJb2c~3BKXs)S?0Rtbz5FZ03VNJ*%dVKb+pXA|WzP=G)vs>jlUaHOof?K=5RbzB) zuz}c)oLz|MaoEy5X0TKoLR#cFrEKuOfB&9{F#kECQ)eFGrFRcKNQ>Fo`fxQ&I{9Yz zD&+g^iA7uN9N@7(MWn1e(cQ>-I}mZKFizyF$myH?46<6<^Vr`8?d~85uzRh3;#($< z-Tn{CST^8oSuOM}QPWnxW#9XaVue%|OFyuZVlGSNeodgAB;s`}Z^FnA+I}B+%*(m} z!mACDZgXsc@l@8-IFUzLLoWdCyl)=*N#*D_VoJGT={b5eieRv9)OF+=Sfl~`5osTl zq>-7Q)(T&}JK7~HIq;bEsN#e`KdirMYk z@}+*aF{@b!j$@!gd zQkMI5mpEN1Y|Pb-kt}|fi9~~#m>4Hs1DoPx^O1P+zr-U`Q4a;#IH5y_$-y&dob@2= z@U*(yeNoqCk{hsMmCFr@Yl%4iO3mIRn>8?#9Y5ko=N0@0R^+`SW!GA1rXqy|BJH0G z87}nGhRyG%>7=yF}B6;w*9Au5k==8k3yC%TL;5KSJw{5iyD;0KmXs#xOtjI0@(OuHs5C0nYDs?IyT*}z`6xs>-AX)~qGC5q{$ z_TtKXJMi_24xVR=9|a_^S=!I)qR!fZU7%&NxO6x7H9KCYTeh0;hLCnf%=RKRuKixn zHZr&w=I-o`=!)Q9{~9s-xK%rHKAGA1bHrM@?;R9kf&V~k5^6M$@aJ0kb{1{9bNh87 zG39GVJ+)TZZYj}(yi=Q+6L?Vlg@^MZkp+B;f?fFmWTxh55G)IXL(HhN;jPK_fANy! zx0=pj*0*mhZbc{ZSa-4{idn4G&kRpJ173gczS<7P5LkmE-eay(pBFh)-1!pPQYa^t zM&L&9sm7#V5w-hBQW`9wkRi0hV&_Ks{WU-Lwyl0z1j5JM(b~ng-XZn|h7_rVV9VFB z4F@YQ2#+j5ZDwJ76rf-{S0qTe&e|9v?`Hvim%_cYst`ibT3Xc$5DGn#q}6% z7OJPyifU$ho^?lwYyQm-1f)Kffwo-_2bRQk$e@$*YJs&i2cA`H%6YEmNXDvomnnW) ziirHvv!!M_6OYe#emA!X1mouEw*gCO8*8$qcXH+;eY^+4ut;R_v@pE8?FKiJ5$~R1 zS}gsLTcZ-JW`3BaZ| z(Ct0J7b9B&L#$6dtba|nJBt$_nWu^%YmW1E(%H}pcV-b~bxy23MBYOHYN>!R#%iw2 za8Vds2meQ^MKMHTbG*}@z}4nT;m|FrK?U=pwv3S(LXytFInv<<%?M$oToHpuXf#PI z=+31ylQpmWR`FblD$>}rN`S_LAi29(Trr+ro>SZU>0~IumR;O z=Q%mr^!q!}oyywVz!E3}uQCZh&Y*{A%By*RZp6QK(u&ISi#znx9k!>CeJKI?eJUj%J%Wcrrr7>GtV* zns$A`u6cuInAE>RS0*!{`?3#p>T#5Y!@lj9=8#4%(`a==?Kt-4zb;2z3H-JuPa)(s}dw+OR!&!5h(gj^)=44E;F;&!Q`I zgEvYZPGpK_!x*DhC_Sh*IkETnJ~a#hsveWS>Iqj#EFi~3f_YC6_{&n6V+od5`dfQ!(P2a*233=B14IC^gmmXE7_ke>=HHjAcT^i8ZiGz4tkn-3FvxHd)IhMg)f z;T}KYtVW zH*-iNqTM|Qp-)s+Ql5>Hz)6UH`$^%mj^a%W(In-oYo}~DJodO_HycW0=Q;Bd$Qjbq zHo%?T&;Z{`50BOiPt-R@+>YH+r=VOzbzc6L4ytn~0petIP%8-fJfCHyjL?v~T2exD zI7F2l{B75C!)?ipXW?b;yyS3dqK5YoC-r5ycwT|ElWGSp25Pqr{s!k(yqiUG@02W$ zTvseo(@T!-0_v~)6!$D?a%irxKIP58um1ox$rVUSdp4^$5R=h8p=;)0+J^R{2La z=)UCuhML$zB@yQiXVW5o!?%LP`)Uy1BAnR0Mq2?4ohms7DwO#o{!SGm8&67%EdFoM zqI;g@+JxZhgG~HOB{yZ#e6Gu}(IQNF6($PV9b9sOEqv$5DR`g3jHi`XWKRZqvgSfnABY9c(;Y4 z);=24TWp*C4PW0=$(vjIA3XLaDhpVjrd#FMY=*zqALe+EL1AKH`IlP7cU@XO0=_1}o2B!>GH+;<;;R^XhH2YeFwi}ME|jM$hruoP4rV8%~m zsIcGjnOIn+tfSvCFD9yp(D#R9@KXO-{J?2B5udDW*s2@BJ?gX*il6ZyaFn|lAEI)7 zFqycZr9U~b`u(&rdtVkTumkLej4cd|+;91_{tZ9>hABJc+};jb6MtSwe$K8nC1`3l zNMBouLl+rEwx<$YMfE)!e7j^+tXZyAXS>32{Z)Mfy66SIIj4WR{r$awo%d%_2bzc> z3-*$DOghFQuh7u&^XJd+Yn8!>P))u4M^n(g;Xi=TV9)>gHuVe&4Cu|-)oDTNevotL zv)W;49EOf$*J{H~#V8bCRR*8AZ$I4Ao%@h!`RZ>)K2@V-yj!X&I+LsBgu1V!P*nVk zMdH;liPB3*3=G`ckp`RjiKk2dhO7+N*;B2Xfm>?5kZI_8a{ndBrKuPY873dhH#RmJ zcuYs#o{zr-&E0@WSB8~@v8r2Lz7kr-9Iv{*fUpXfX39GVRQPb{hVEO6KJSNosVF=t zre;ysqnX|cv&KJ2y1|~AE4R0|`OtW>e1&JRXLpMIc6pJHfc(^k-CG;kD3ui>G=)W> z1qBM{H!xc$Ex23UB~3Q-LlKQohK*sX^|MCN75%_JUP{s~V)WwD(J^$vk#(7~vp?7i)BQPvblMl*!)U?w z>rQ`7z^c>J&D_vs{x#V-l&Pt3OX zo;5f3`H)Ww+E9lV4D~(|TByD8$&MJhm3&!t1zV235qLYCut=VA(B;1wym)+1#>l>t?Z>^Xuu<-7s^mz-NkVnzA zr^gcxh6EaOa`-)Y)?=IwbFLT%qnY2Gt(a2t?L$G8s>HkThpGN`wzR5(konr_Y`NBS z<8nFbAC7@#+?Mvq74`2Tu>C*Oy=7RIYqvJ4fD;6jR0JfX5fK3eLApai=~n3m2|-#! zBt$}xEr=$?Cf`*m|hQC!zz>e`Ksye9T)olL&~TCMSD-^0DvW5Z^1mP0uL zn*O*Q?wa`Q(V7DoUj!3cr+czuXN;X9RMkQu@X~SmZYR~{-VHGq>r&Njwpm2-&{r5$ z*Kis?xHx&>9X~4~>5$P5o7Qk2aa(a_D&BO{~i3wpb)-LWsG5+FjhpjLPAg z{8}GMH{naFceUwybTZ~+#i*+njem)~NO#YhdtuJET*Am71vB8Cga>}zmt8vi&2J)l zaAhsa7!(A*Sc7Gc?H|ah=cv125O!{0WE&i)$;@obPXoHXH@HyT2LAI)2tstrA9Y{R zf6bJ!Uf@zMQ-18b?U&O=5D_xkeORfbkjfdD&+q=Ju;!hL{9PG6(^pS?u<^Nv8fL3L zGf`G(FOg+N_WsD1&lArf1{)l0S=g;c*tGTqo7(MeHv5iG;;`#?bJ+Z%-qSHSJGo zVr{BeFtN`B6+X&$;iJhcs%fw4Hh5lq&n8JIZbrVzEIppFSNCDO!0$k_9iu;J$^UNk z{)To(BR>UMC7(HgaUA;5b%Vc_s&f zGp|If3aXKPLm5rN`r>2$L2kXr>e!{d8^W1l(~~Z-vgSYVctn@KzcCnlC3)@Gz!RPF z=-Kb3`K)zau~Z9>WU)_tOaEBrv@qM~(SH)%RS&%_>mF9`DtREcEC-|JVRg@iiQirq z!3gp02a@ALCjswKwz{o0f}^6U8l7j%8k&6b5RlEU=)j59=47Y@`lY(9AYCeGMmXhSheIh?RtJkSj01o(x4@gwTU=% z&AXi>7+Ga#vqOK+;}VSI&ovDb)~7*BI_CD7A8~HQT$4dSOhpAh(^Q4S%pES~#Hx+i zZaIfz%PMbveDP}nD|4AoX+Gqlm>~e0c@vS^Z}RYZkRye0F=P%9Iu$_ZAlC3Ywlahn zAxwx4?qwWk$*b`SVSPBX#Q({@@AJ90Sy|V0@&u#cWa6*&*5hne3hOGiAyoyfP z4gZ#^eF_c@!PVnGT|Zum>tZv7(BOn_Wt>hG*6i$T>brL`jg5`JRI!2sj~4O-eD9o6 zKLgrR$B+Lk$G+rEi;kZr0Zo<3@d#a7h@pwdTpmw-@MTLHQ@eKU+PGm*(C5hUd1PH} zU}7p&sbBsDeYchK+FFdH-vu}TtAat;ZBxx%i5!cQkR~+LpK6enKuUP`uBD~rOKARv z#Z?M;LipngSVEy5awD{Hwa(F06VOQj{|j=7rHz3{s{&;qS-K4y7vs3(8E(OBMBKqxKD%!z=`a9V<3k06AvAMPgSg! zF8$1@A%dpia)!RUs~eG=hn`5wdTk|;5VN9JRT0yGMMv?s`D^zIE2~@utsHVou-wq{s5;)(fT7Ts!4BwD$$SQ{+Jb3V%$QC2fJ09L%NFA2 zi<8Qvq^wML`t<3b&`>IBZ8Sj%aMoOl%$d(aS3*LMtq9Nwa-#+0XN9*~b}L=Qx&s(c zC?^>OO?%$Q@rLj;0Gq+YY3oH_M{|Vb2K#hVUiG#TYMud_m(|G(Ld{D;^Re$!l5h%` z;X;(4RTHLh^nU;TQa+)7(6@y?3^a3jFmp|XV*T(Y?=_f)nZewn&1(cR_sYUA?_x*{ zoR)7D8Wi5CV14?tb#K0V`&QcAT@9@j!LlDbPrWYAf@WR?o_`mRD~M(uAD$PQ^}jCIP%uQ%9%yJQ+(_E+6`mBYdgX;@K}W4KuKRy6g>D(RP?arl^--LX5@* z_G^Q7E+d8v-oLEEjFkonP5&6RY<;y)0~9Km!ZkU#dwGN z=e*w;dbxhI>G|QDY$E;x?K(`@b$>ZqqCq)pK&O5*CY$1aLw3AU=^QC3 zm!u@8MkaEFwxr=puNza|qMqYI&q+RLoJA84`+rC(LgF@|sR;BOPx!JV4dw9#pWM_` z@y4d6uKqZyqb<*W2^u&3s&pAOE(VQ1^|A~`jjOZQi6J*LHN6`Y6q%%fI=OWVI+>6Ax&#eA3$68hM9eHcUidwFW*Gh5G$nd86u5E9@t(~e9p)r>flq{J zD1o#x%wCMGdU1%jb33~8e*DOh9e6a3d zDo29Z2%oVgkv9JPd4HzkwV#ZsDUY(}-iqIhb>lGeqtf7a93Uj&k}k<6u8dn)>8hr4 z4LH~xUGh8hd`4Z<23QO+ZORyCFMc+)j!=omul*l3-qTz4n@m+gEBpRSif*2`t($d( zbdr6q#1P1v4$I}HWk)hNh!M^x9~KryG&4|`A#1NAw@t&Vpto zI_NZksb*4kb}PS`u9{lUuf|Mom`9pX3Rpy&_W_TO&LS8><)8PB(BksIJ{?gxdqU#B zH2>|}vyDY#UnxhK%me{40hID-dfwAkS2R&9c(*?Z3ziP2n#&cAcX<;IXXIengN zVCo?lu{(45L`O?11WS7GmPythx{?Y9OHnoG=!koQ6R>|<@gZA(_Ie zsu5)K<*=XnzDN}g>ZaSw) z>jf4zwg_&k0s2DuHCeJ|it+TmA~ZD6H;g+SamLms3h--T*Rim(w@rWCdEFVvUd0T0 zqGF&%Sbsrqcym|Vv0K&Xqt|hS&Ps1C4#jW3t1#2L#CedFmS^cQt|pNs5lr@7a-jHm zTpJTi4b3!$_18_)Isi=?0F7b+q9@A|$X!mO#+TEo_dTj0x|smz2Y`%i@wJ%Tp8>40 zhfs#|G2WFB%7@=MCb@Hs72^3+5t$Y(=w60^X-?Rq)-HdT;vUtcXp4UrSOcLs(~6;6A|GN+e#eMul55t<4S;`Bz(DV&kVc{GO>T* z<`dMbBo!6)@VC5ItTpD$Djt6H3uGhFx(>77WH!FrE3Ot~FCZCo;|eBdsFoH=2d7cj>U)5oiEATX4ZhXliu)6Zp< zmBU{~L>Q@9TRCMb_L=kCDQknp>+c@{2 z(AHf>>N(t_H2P?R0b->tdzo|Y@^n8T$TcBgp_^!)EGTx-;1@i4|OA>8YLPtnJ4)Adj6V`wE1q|OE zu&Xx=PZ&wo%!W1=2IU+b3wav>-(-SAYb&~%RWu+w?6GSVUeInWr&YL9d?J1W)9t4} zQ_Mn6+3Y3Wxy*dpjkGaa1dgUCrdz?#9@Jm-tKV7~n*hp?XKvbx@ab161{l`kg}>@FH?*nnq{y-O?h|h!z5Q zhL7d2H)}Drwd}dl1Yz>9hj|ZWid_A93#2O_k7BtGSlrUoxN9)Er)=MV+fP zKeGq6)6CNHTk#v;yLNWDF4RlZR_hM|3y=8~D^+cEPOcO>_?hd0SyxoX1o#asSH3ZVS&y{Yw^Q z@f_9xQMZ=sz1Iw8%zo0lbuL;s>M-n<@Hy3iZo|5)CWhDk&Gcx=0EXLKRx!8CE0~(0 z{=JD;`sel)sZ%?jYy(gzQMVe%V^{fGzf$iDvnoJ3F@7EgLNo|>BA;tudcTBl=kIXI zWzdjYz@H_fs8W){Y@&?aXqP z?nb|I#bVn0#LoMnorqVjVk2EP_Tc2S2l<*XMJ;S+X&0Zfny~}!wlBXqgOOp)V|2hG z$ML>r4Q`Jg9(#pSZ4lX5vtF6QyHgi#C<$(jVwwzdwei#0RIW$rxUYA==`OAmF3;_b zq|eAMdoQCU{-UM$U}vrgs4asq#trTb)?PgA#{m7*ze01PZ!`toE&&T%7@aF1M=2(Ty(c)68Xl8H?%riv(oOVwy;}DzkM>A{2V4%L&@6TA zxDXz&24Bi&mGP}QY*$-&0-fm2+u-_&zUlT6Oifh=a!LNa7I zFkj?~TZ-h2OG`AA>@i2GN)EpLU(kccqy5Cg|TRwN+aI!^gta`M9uUZ4Xx9{MEZ& zt6#znl1MUMI4(?zm0#+R@f_s?dC!8_S2uZXuyYKI)Lg(`9z$K?I}_@3_tL4(A*@{ko-wf#?*8y&GuC)V6 zZN0u;N~@M+gYB8rlO(#viaP9;C&AID89{fJTOxKH42_V8Z0{^h$cf{X-tF0G1#KEU zZp8)4mV3n_?4Df6qaqIOx0HrsuAS!w z4eElg%V4`E>_3`Gdlj>oxR#&&dJOEc(EeI@Ca_uxuM`KmGo7|m!>fAz;s=Utmgvdm ztqL6ziaNVwh{>no?1L-oE6g`lADxElTx+^gVymF(O8E^LVoFT$x(=K~xQ*Gi!Qn{* zGoLbMKV7p?%cli!ib-Bxo}+wMddkc5U^{&e z_D%}V)t%SfFuUeEIo<9vK+p?rr=p9|xOX7t=i)oLi7{%?*5o1`p-FZ`WE&I;;!Y)?Em*q(~jL|hM9HLY7|6+ZQ$ zbb0J)>KAm6baz+RX1dZm4-Y0^M^2;!UdbbkR%dHMvW?+6<)(qNs#~c;+Ge6UOq5J? zJ0fgD#Z(4Bf^hlx%stX!S3#1a3R+N%EJoPBzJP-z50P-YdE9D?zt@J;Fi1HfI5_8t zZ-9Rg=V98bV=s>&@woK76dS6If-s`Nhl*^`_o$ChYjhm*&WG_~M&`clUOAWFr{U&~%&2(NEnD6OKuV@L*flqL=MZt~YeG7U7Ql|S)iefW&~ ztAQyIx%@3A`%Iwe(B+;vPukI?=eoe4$iMO=n$l+PHL$Ra0MfGo(Ij{*t-%i%@>a{P zJG5gU#3U7v+)B;5<`9G*Z`_t(RThJ*U)91rSP!T>S!jLxgbw@X2vALxs$wCvic2^jKoZ;)|++i^BtrtXhJGv=Ox&~CaobM?w zJk=k?c&-Q^kt@P{82tfD@8~%azee; zfomAQxC9m>j)Sqlf`u}5FabJbsxH63vz|}No5R=R8|;#-?CxIaFw^<9qPK@K=Gy_% z&iW|4(s|%N<5UFfDkr2L%=G7{YqIzHpAum1#S?22f)gy|ty8nfpFrg&Nuz|~NY$Y@ z%WSN*ldSt4(z`EPCR6wO&8v%$obJO53inmp@g&-rE??_6megPf0d2+ly*K$m@}|)1 z3+{IakbqZzlECpI?YM&NNX~5;)%8`SM)o%K9eKm)Nge$Zf^ER1tIh!xXu;oO9q$mb z1P)1gw4W1M;r3)~>^2Zs1=BAqHb@fcowp}mNoezlEBgF(nut;eeE6QLS=9>@8+%A> z=`eqaQssL>0l&6YVZ?US3-PB^QFFe!6h}*hq%YgdJawRgJCAV@$pmyiJ`&|N9I7`g z7y)%Jv*CIoMP7`V-(+(%vAsSx&3q{j--56s860KSNj^UNnLH)a&x3NJ1_|01V#;k@ zzOQQl)&O&+0S+M59FAJ`3}b@Dt>Q5JTs6B%Hmw3?Ljfa;p5lbs)0(=c`I^>RfK{HK zZ<>`8xUX4(ua-F7%H4x+wW4Ohoj51QMPv*JgW?J3rrMppnmep4gvy`DGd}wl_TXC( z&gnSy8@1+XY!dc-{E-ZBL6l=Ay&8# zT-|YU&?b|EGj5_MiekfZ$`N^wO^`b^-Hh~B5=VL~AoZZtQf8()Si#5>sS~Oim?)TP zkA3k(yYm*w5s5UA{uo^eq(%nJAHn4rGAYJyKdRF)RQ>R3wJ(*bx$bQ`~pQ@x4cRX z=l)$LdaXk9vw5|jY$NB^MXB97_qEuriwf;6`{Y}K955L`lbb915a&BY_ST@4_sgftuFO8wfk?Z(XyilurEuw`+YQ@)EU;460#`V~**{X^w0~ z5!h;fe3aMYz^1CD6|<3T(i}zD!IORFOi3M;YgCo(i1XNKuJ(~%6HP{-U``nd$}IUA zU`8Ey`Usv5BZf^rDAjqqJd4S40(Jul<&$<<(Y`=KNHe&)QfbkfjcCJwb+OR=TO)gL zWZxXFg8$KUYWz{(JwKU5LHAoc%1afi!P8El0ZcJ4s)=#fJ2kWc!6Ru#_fyk{OdAEA zvaJ42x_#vjZMxk3o%FvxK@d_I3b71UJP&vE#nOiOXQohuJ=vCMGig!LI|I_y2v8m# z2|0D;W-0_Wzbh9E3N2)Bzypb7_=;2dt_y_^c4pG&v`so!xHG9|n@t3=sk+Ps?qzcz ze?bQvmir7@E$&Z(bCY||qbq@}2lIBy6bL_WuY=1fU2HwnJoQdFJ;tI1*jZyi3m1n` zn}q?{B{3@3c@ExDFU++c()l`VKVB*;{HUriUB-v_R{~BJT$#ymW$L0U^AO|4Vdj6Z z@2u>^&f)6e#uW)0 z%i%{93pj0t`F9Pz_d=K;+sZeWY20*u<(_~ptMZ#$96nXExI1HE8@_^0^BPFW5@Ti1 zcAm#NF3#;&!$w_6j#{rTVQ*pyYaY0<1k0spVyUlmihDCc9@S4gO$ex7r;PMwSx2ET zmdoGVWo;i>Ty7~jm0@Iw&AnnwztM2yi?Rbm;ciDV{XO9E>pPGO(*>dcex)lPS% zmPWEXDuZBW;+wMK^Mn=?G+-Nq3sjsADW&Yij&s+i`=X@wq=D{R9W&{`J0AivTaZozN z%Uj@BTn;SB{NaDfiXnYuGt2JRExCXM0oRzGhju&%Cf~EmI zr7*UGmkeryLIDEpi(3FE$q-OaUOxLX=nf_+60RC^y*CGJ`?wnHGwVuTEny^Uz+6>T zQNbDy;+01)IS((q`;E&4FzHXk^$*>Iemo&=rWw6-2pDB-F56>uytpIMx(eP_zH3rL zMTnCP(>~fGV3Hv5n{6uRlaxFc*p&U-8~~Hcbn>e?f|lE`evyqNf=GiG1vP-lT{j1< z%S%vZHztYrxV@1^!i3{XC&#&}TorwYE{@uOe|?ZGB)fFmTPB=QMn=Z}<*Qe&1y4xu zjs{N&{1czKB^sTxK8^m0dqWsQUISxnJ(woC5IFDxE(?Xdw392xkG}5c?e=x^n_S~L z01LtpSnxz6SeP86u(0rr#XBGst`!**!xS7lo&%&pr54vq)Ji>YMhVf>+6Z#jLxgdm zF*7Mp5kM*o1+fvB-Ud=ZAtoj!H8V5wtE1*oOCN;*TR;4Emf?uyLhNYD*D^E#o(S-N z$0{2jEC+sv7SVlP3^SZ>-@ZwUiD4QTrrxVNLf~HkhpLxN*$93RPAc%3iip#JZm|Qy zP^okCpr$^f-G`SPW-i;K&p*xW1Nqj-7M!OT(R&;l z0X-2Cd~XsobBJ@KXI0YHwkV6d#KtD?MBIaz6UbEo8V@@{oDgQ)`x>m3SyJwiNC{Zh za{NpFw6r0qux}7+2u>iVP@3=A|2X-<%ASDU~0s(Lg zNj_;%qF(t!ub9qCa1ct1!nq}q&U`HV9wVGdF%lANA(`WrqjC>|8wi#^z!$$nh;<+@ zHL412s9QXJfD{GMK%{Z48d#wBX24O%={W_WZ%0Ih#R750hWob)MeF7L6X;9& z@FmY~(lm5lfVZz=V*UCEt!FhlFYno91BGefVSfjWr@}FR(~Lm)DB9y&qC-M6DgmvN zTKIAvwGNBT#bbz%UOyVP zi_&Uv;E$xs$1o0vfV0i0VrIkeM?_rbJu(b4T*%vy`As&Ym0}-JZUoCIF!Oo-j8zPfbqt=HMi{lnaOm!Ez!z?dd4# zkG7p547q_h_Y4}95RB?@Hi(FhKoJ(6pKOvY#M^7*Q(s>nGqBQR^S<)PEMQeI0^_Ik zT!{*`2sW|&X7Kz8^xhbFuf=sy7XoR0cz(yp(qCA|8-^~&D4vOKr>#4%8=K5ux8u}+goZHOHyX!~QAt(R=&#-Ew{Pn$r7S_ujW{`I zFa5pGXGBG3!!+u?Hk3j$pAO?lcz*`h2Lw;_oSZ)m46yG1Q6Jr3y$Uifg5@meV6m#y zCp7RUu;ZWbUq*DK8xr7Hb>Ftdih)S;D36Sj^dIrjYJ4u5Tp)kJEC?u{C4rPv0$Ww+ z?3+VJ9yg8>?qRO(t=LS&Awj7 z5eLx!+2|-H#v;zG1b)rgxw*8wyv}&aJkq1VE26>QK23u32ewE~!^d(HO&&kk%}w#^ zN;p_LAX)o?OLtR*=1$W4_l?c4j5D8^P!E@&ht<6_6Uc1bhvQ;U{(C*jVMI&UrMC&U z)V;)OtIt)4eY_5LdXYu1!lg@>bOxDj{`Q`#fo?u@6h4WzyCw7^KeGTLYgHfn z<+0<%Fmojg4ITtI#7EpQ82KmB%jkSDW5G;c{6;&4mf#wY*gQN(6QYCz8$k4}MC){pF{a7ZIaKwS#l-1x4yhse)e!V&y!kLG=Er5MA>%Q!_s`H@Abuus2&b4N%FHoSiT7TMzbs z4kwFYcZJdQJQzATI94};e|T6EfM0|ElL@pHi33E})Z9jQF-H=&4(d0hs)T;+bM&lx zFTHT{JTDEAb`bLTb?f(QDX3=_bOtM~34*oY((I^p{~thYlU< z$r#@}aT$oJlc+-1GnM{P^r1~W-}{z!@-2rkZUY6>#|kTh_`tOy|O z(Z?@v?)i0iNm{BgR8>`tuPy}y;2tJmF&y1hreL#djuJ$LlW3s16StqoVZr0=;BE~E zJt0GfQ~aq-M(|@-O<{Ia72@-GGQDhu-%b%o92AlF1qV+Ew%@*z+)E@&lZIoEP)4Rr z1Gfdj6PDz+vwHZ_aDUNK+n+T01DLlt(Y)fG_!u>!n5uFRr$DbV;;|(U` zlDty2bw7U#i3%VDzBc(@=wR#hcgWvNQH*j2NOUsBAgAx0G7~SVHUVJDOGLCKP_D$x zY!KcIT=AZhJ4Ip)DQf8mr~!23o#_QdBR=?HG4XN%mID7d;pA@SDIYIS^xp>puCl?x z_rOjwXYPz!^3(oDW=ZxUG#3;YO`m=7!ueSDbIk$i&x5d?p|C2uAW3F?Fa1@Gj%V|t zRjTrCWFl5@DF@IW$GkDl+Ok&F{p?8p`q!!RG;)!9l&`LfbO7IGoH1-yNBIEog21BT z_IIwEi=0rNpet+)5Z;%ywUS((%cGxu0p>0TUdguQVff6(h6fSS8yw*r%PA1Ux*zOq zKLDu#aLhVC<9?Ev#Qmt~<-t35IRtP<1%&WUQUh{{ay(Y6LJofLDM=SLl+r*L0vJv8 z31$HdUpmlp+Rlb?t%M*!s5}ofT*PLtWIgM(?)jc=-WZVRo{Y7*Vl~KZL%Y&0hTo7P z5jY-a-x|uAT|zrCw!bCCoFY*xpTidMRZZ?R5gChe-f@Tog%P+GXa=cPc__0sh>R=l zE94mM)Z`Quwa-Ab8v*(0!~K%s7ZK{W2dsqgFl0J20qpo8UuVRy%)O?S$Zd2d?3kYf z+{wHs|Et#C{k+-A&##l^Zpz{7<4WJIJzUi32OY~eWJ-mL0xrp7Px9mmIKjXa3EVJ`W5E~(pXEo(qhu99(to6M3tSzs zi2(a_&5uF8YhY<2C{CoQ+?GW;)B$22Ui+MB^y_NNec{j?N;ynuEpbZL>=kBjr3l)Sy6J0rvGJSkUbk=4%WzSIbNjh9z zawhfJcjXJqigPoc9Zr>IGEOEfWGlyU<_#VFux>*E@ZbW`hPh2^0JI|#2Q;AE>x`@-ty>9*Gj`y4i|J#bo*$#K1$MIpN>+E5011 zf+jLbhygAHT*K{_IK%7{4)eGRTC&(Pt+i`_G&REO+4-DDA?K48@^WqRzle|MT(B;z zF&%o}Z{A}3A0HSTHzXRHQ_cYngxJb=1t2seJTrpKj|YhG8%qnXkK!~6m$zpyn zhM!SR7F4d_G?=K|`Wcuvmt7vy(-+g%?t09syBIjIC~>K>LCU`?x^Qgjxv#5|T{8`t zb`%SzO^oX^uZ*K4xz%v@Ks~3NCrJ6z|7l=h@-baTw7Ygg@#>;Rb)z(D2 zNrKB89XLgAY#bKuzkkd8U~O?Z7LV01f2M@1V>A6to&DC38~i47VCVjSoV> zD>cO#v?8e{T-AVCIPCW!9pQ|SuIJhgXhd6Dq_#vLw|GeTRb!pdlem8EY-(QSqwabDMo!oiJQgMaRDC)$L0$ZG|IA&ecZ~O~-94**Th)3uepn!6c#DGL1<6B{S!s{rDu-#Qpl4-1zGrP8Uutcf+1(F(VB?+btOr@%5e|37?9qa?BTo9%36@Y zpMpvqakO3EVKh)=Wyy8l{1!&W@v!+8a#cq$qH7;oZGQj>X)N_~R9d7I0B|~S5NPSS zK*Dh||2~IIIMw0)lBc}T1P}awP1y!^yiIXySGpr4zH7MNzLWC~&OQUn9h5jijcZ6g z@Dv54Of8fIf>rYFx1CL{-r))nCrsj9PiV_5~<$tJ=&D>ZnMEg!cXEHKF*BiaoX;+Lr<4X#`6(>94(SX92W$K>6-;Y|x)t1*Abx76Qrq(AZ_t zhh)Wc}T9M?nlGOhf_`xQ8MdjJEU@^AAUB-EP&y5>B{7Jg!L z<%iEBi#Z&5dQ-e$Bvt;4!t$=xq8X`ghjQ6q|1OkW3P!$&b@>8!N8~7<8Rr-T1cmB$ zdZlM>kf35W|HGJe?|$?CRS;d2%qKefcP#+zF7TV^{HQ%j`iEF^D#F%ivO9Rlq|RIl z6V#nHZp?ag4|sKg%ifkXo3@{(IXFSvO;*+ClG6aS?snzC%%1|T%E5LCNZlJv>n$KN zF#>fgM~+0abKr^m)fa#Kh}{pCxn-U3nz5vkk<@RbADYT*pp0y4O;evN1bok*tp$7gn#* z+2iF&ZyKasxMO9X%}e|zwkvyZtJ0-|I=?`sRM7o8FeooKEJh6f-(>^{q%}djM5XJs ze9*S8;l8uxulLnWaJ89h0wjFb6<5rg0;WBB*0I^jPt+BUcnn%nM_b!0h0F!AePV?G zT^H`aY_|MDytmVzs=hqWE}bMtYFR_b<0Pi68BCCTPR_tL+yQ~#RFJ13yWCn#tJ6~T zVbynV^--`BUV<}n2o*LM5E&UAF@5n;Hs)_X?Y|#iJCmW~2b%@ln&)Pyum!%u(5qp~ z3r>CaSeAMked{00Rnw9iq*~Vfg@RKyaHNViEvo-ca$j9R!c?Rz)f=yvy+HvIW>R@I z(-Z@^;95D|UuUtcNii)vMK!xp{DYTSz|-AKTPm#*4_t=QF?*;2oPLpIbOBWTi@c&s z&J(%<7A1OX4+!D<+ftMa#EiFW>*sqeKna?+C>UV8H&nJhqCdK>TKDytwRbv2dVc({ zx@qqdn4w^^AL&Cn{o#z7*ZMo(tFm_d%7!%MjTGY?9qgFUt3cZE(?ffk?JT!RurOFb zfb&7M&EG^h>CGESa&mGV3OeKla)P&vDtyVW{?ce^$afK(Kg!*N=&pFowIqX)8i{T| z3VSUdOrByXvbcps?b(tb*3Dj)AFCRH(i0QUd4`{9B%nBX3<;){Xi!MAy*d?GWC$cU z>xBr=R1Ui2WMu+%$O?j(Ow&7>>BO62zM93?Vpy+p4(>|+mkh6{aMZd&P5Tww9#?oo)^6J6i!P4P4 zh))8eaxklBy)qkab-3ruaYtJxHrr`p13t1G3!(Bpl&=X5yi&%Trrf)OX0wiC4c`p8RaT*E(aQp0KRqf1jU~jJ0$SC6=yLk-5 zx^DAWh#gAz^J2%UAQ&NqnjC*^d4LgUE^&q=?n1M($!xr9Lh_I1k_y?Y_wqO>c^{;H zhb)A!MJK1PrcHtR9@}4o=8|;{%Q97-|&)yNaND zH+D#xa#|RWk&y6RYV#$Au0!Pt;AjtWPAnmOMU-e+)C~;J+yqdeJor~;w#b|^=50+V zT@8Frb6;g!1=YEI$MN#6p(}3HzXhPGAMsWym8^K#u^s@4OV|7J0z1L)+9ys{K|#Vv zc426A|CRL`_1&skC>jiK+WeNTNDT<)bC+`ioMPoT-#EA>Ur@0@8H{j;;y{;U#t5rE z!3f{iyPFz!2EzqrHe~ zsnZ#)X^b7L2qz>F(V9+g+(yicH_#>6@5^{KA(0})i}dF%vhxsFhK+da%B$%*s`7&3 zHBG*Os1eM8iAO(R&zr{!99v`-RA*`UNga6OsY*Z51g1 z0Fz>t+>xQq-j((;_ywV0TDk7u0Yr+IIzZ9`4-|05wcu!Ff92Jq!TQ6}VB8*zqlbBu z0n{*cU{VLPu+kWM&zDxG+FqT&J68|-WEN0$E0oE?Ei{Aq;VA!^_;^n3!^Gv=x3Ksb zV1p@li`>JN_$P5(l$W6u%oap+FlDPpasU#@;i|kk7m<%3_Ge3br)iXKfai>xeubA9 z|D*~4BiU)vhR$#AFyo>f{21`s6XH%Ni_KXHkl#NDfbGUBGUw%hDK7!=cGUA&oQDVk^xn>n8&-f~ z9OV+$)-TKYDxE=HW&q|wE@U1FPL`vf8wO`Z?a)%Zf^J_C$)mvHhb+o3DEl8*5r%x3 zg(dXYuV0^U^0q?Y0?P_*e2i#&2ThAWH}J|H@$&xbW70U_C?99sQK-lJL(Sh|C-LJ% z>x)xD51EfA!-mj5s8Hr(rYQ3foe~BeVUTw6@xlh?!8wVDS@g%rKb#Hj()bNJWK})_ zE`Cg1Fdec%Pp}EQu}{xVjQ{InJzF&6*|NMB+5e&Cos&74k*yy^B%j1BCzPx1jM8Y6 z8eOa!${4#u(lk*CS1bpTfX+>fUoVPIWq_b^iXwK2V zs{(jM{`D~_;+7w0swrF=L4f%i9D2@Qy2KZ#;Za*KLyOr=u87>Kpap(MR{r-==)zKz zC(NJrc7qV3K3%ZxipD>D4erJTw5Y-~&tTLvJ$zG;XeR=he%MfIObQxCNIg=jlD>zA zQO*f#&Tr#n928X1gMp0zr0+n`l-o2?A*_WRp!P~7yq8Gh036HKVik+4IOH-xKcS`s zo)#*T2=$U^L92JdJt6J_%o)KoASjRs7=Xnjc-#kyelfvWl83WYKtAP$rwQlnV(*oy zNS=R^g@+qIdZYIKSB?KmhLO}39*$<}F>nm{NTv$?Ac1};na8YxGBOElp^w^FoXx-L zWc~-VhS~tdJ{l9LbhVr{-}_E1*}$P zN1g#%IVgy-S@Fx>7XAI_^9NVpE}0s?a24l>Sor|NN&rpVl_^yD01HYFP({6;6bCDH z7asOfy^#*=kT)QM8XXA0i_5SwX*|WZag7@4qYXhKzo`*yoyJJB-|xc zQ_qp8>R+FSC<9W*J281zgzz6SmN~uI1wHMJHdaauuMBJ~$c7g1ifCnljgGjTqk?|_ zO4u~Fuz)fwX=!Pt0#~JugctSi;faijd6Xkw9}9omtX)9mEdG4%9f$Te3lBD400NC5 zl{GW-^8ZcKe^c)dnp%%!5}9xi^A(zpBcoUW8+7$^s|f5p??0c{N5kQWyKSFDbMhY+ zmQy;trS$0f1$hqp)}=`-nC>Jr-D>>lfKWgkq~9N7(!){-N3^_~R6rijg&=Xs#b#cV z{TqS@JLJksUI52vLR{hR#TH(4bNuspDY|JXOoEB7{&S=;oF?Ot)J3Te8vC5B-wIU+ z9s^sBZ#`r``LBu)JrropJAJjS`R%ihFxw6{r)hQm@oCOk3XRzM-^af>}h^0 zY&wruQ;?Gz0`~$%91Mdq*{(xP>`xCe=Gfe}c1I8Ke`2nL&SCaSRZ&lq(pOQh?1wDX zeWy0DSPu7rEK^Zl2@22JKZskr5HR)h)|#$L&FLUlP|P-w9j+D`B8@Kj=Ki=P`yfXPC2N z81G=uD0ke4)Y1PzLgTCrJZABnU+1<8+=bsF&jVp3D1aGoq@EyvQZrO?zAo@8uR~ah zgB-C|FkA%BpsvXa1R(soag_fZOdI-RB_IX0{ohN3V1Y>BMJ$h@&Ic8uF;PK?gR^hn zzvuLEf$~LLoAk`Quz|dUxnS*%^w_XnK{CMp%zT_4odRRnS;q9u!XJxa3%O}Kl6-Ia zeJh*;7vKTgZEj?Xpniz!tg$8XKK}b!8aar&FmF-1qK`^i{-*F3=T?)Jk7g|t+K|Q< zL_VW0TxaYrW5)SW+tTpbRP02^mIU3TP%o9yX67H+#x+(W9SA7*Ac@&{WZ>6psN$!| zd*`F=48z4xoLc(nC2TlpV5ssbG6;#>kx39 zRpA8{r{T`p%r6i{HjIAqd5s_4X_C#(VwVfmubhPem;eyAy2)iK-sI;y5A|MWYsDDL zVMG=}j!vXiQGabh3*28MAG|#D%OTDk2iAhyg!j>!DH)Ho&hbP$4+Xa2%{JZM1I~=< zw(%)T-b)ytkZ!2?(Nt#s<^No-nq+ihiHs;2&R#54$Z4i4f94imjCiZ(&Im=uvU^Z} z<#PvfMY$KY#E_kL3{570eF^h`L36rpSo(a20+_^u>nE!qMyA22Dl5}Mh{*t-Vmg3K zO`x#8h+J}1L<+Fl9B!94bED#xbNpK4Djj6etG&ay6?0vRBRs zRo*A#GQNSwC1W_P;IT(X(m^}+rZ=+jen#3~{-^w+P(5rfI#48gK=Fclh`G%@z7HTi zjo39N?ir6RWWOmq#NrutejVq~DbxBMsv}meLBXyyv%B#Hz7o|Q`*9N+6!MS11D^Ka z(+SdNMOY^j1^<(izLi-pZ2xycz9O0cE0!#_2~?xnW$ZbRVOC+!gH~xFo8lp-6y5F6 zdRq-=AGpy`{f922w+Wa1gXUFTGM5s4B8B23MojV^o|^~k=U-(^klE3O?1rO^;};4) zB;>e5{|iw}?9k-;_iqP$e(r)CtUeU@Lv3s+z<4g@@7lKss9$R>zP1<|U*8AZnmnnB z)u7}C=3AaR_{oC&{wbg&uau1}%ao@L09qxky)`3vhIgER4AKQniNw=Y$}f-a5M>|b zU}qo=0O%0joPA1enzDr|^w#D=*oi8lO3=QJKE*}AZ0Wtc1^3HpnZm@bNki{g%kiND zcgEHHyTD+FAV*o{s|K|xH*>_hTaYVOQYAjOiZHiJfDrYno#T@XRX{ZY2L~UqZdrk?$lkFZ2e|OBJ9-`)BrF?qvmGU;Zj0q-?%941Dl)0WJ~=Sxd`!|kC`RAvgU@RJdd01{P6U@QzTft`8#UOiiI0208Zt`D-Sq>)bpSvQ$vw=`a4G!@F_LQ#!w{u_6T3se-{ zO@(vv;c7Lmz{*lCX0o!|p3iS<1mM|XR^rfj?S@vXb9iuc+E9i&WRw|avI&^%=Qz&Q zQ%G6e2GV}&*-*t=r`)8V>fwgN)m?x)bE4N#(N(CbtQ)rwmSte#b8WcfcKV}{eMlmV z;_J?>aX7`{PC#FF-O^#DARDIEag`^{Gts;nH1{{E@l(U=rE4$atkB0VCC1d-&h5H7 z=%S7J;PTxQ2ES|8?mQ;Xt7;C{g7Ist+eNN9UYT({Y8Lfz|}2z3`i z)?fSd7e}kz=S-tlXCo;;T zL%Lh^Yn-5P%{^xRD|1zALeG~Fk(TeSg)iW{R>o;N`tjL*-{8y~)F?fl8^12*UQaH@ za^Jo3sm2iDQwY9jC$$^ALb{2r8ZzLB_TcXlHaU!dV8>%RJ<%he&$Emgj&oH=#5In( z4@BpaPjmOt819?SUs#2dAqOXSVD9}gsaxqHH5;C{!-iOB&Oe=*o7l{IgW_;ivTY7> zg-$v`qE$b4S=KtHTfHofxFxsU&zg{k61yIC^s^y13>h5bTsG{os54uNP;FIvy$w$H z!m?LEeGeI_Gsjix$%Thmd?KFNRuMbQ_i?NN`uFvFWp}5LA%jb^liK62QGTyD_A1xC zp5)^fb}f;Y>CC+cjbw6!npOj^$Ci^C?brS*5qwVEvOk_{JDM|eimLre?%zfwP%pCD zoy!;3!dA;U6JK~{c5F<%e(&z#s4M(9h2Laryu}8G z>&CniB)v7~LIPFU|7q{b_ zW}9|p8%y?O6lRj7ZESpFZ=+`JU^X>sApF!>d*gT*Roo^Ky{R#7%`V0Wz< zK~55W;QfZZ1Z;$X4J&A>05Ki!a0kpkTynRwmJ4zdK5jL0IqDfh*!z6IFvIL%kA~}OgPmz@q_tLD-?del3n$$d6Aucm26%lZq z{?We6lopjXgeo+&PFN?L!!w_Z(?NbnGpORXmixPyNz^XPSrkQ(gws`;j}jE1Ac-LN z2y1>SpM6Hnus9(Vp4*X!KFgySD?<=tHx>{9d6lJQS4@}gqTuR%nHzKD${Vi4tKBzB zA0&Pf#lP+pZMN(0Vq7K9SfG1*y_Zfzg=jlEo$Mz%xL8~c@)-dQjh{G_5vij6^Y`L~ z4meTIFni7P7|1=krC#Xj(y4z`gk5nH~C{-Bpz)#|A4~N30bZ zM9@zc>Vd+!q`Ahy(?pl(;2C>B-Lf!QDJ->JxOU=%gpFP8k(ZF-;^O?d%7zaipz?Ma zq$2p%Bc&1wcvsE75j*1(Ltdg(n4?p8#@H@ke@Z{nXik92~)do^VVnY z=eG(=V@GrUpdPoKzt{b4N;Bhie4-}OVLC+BJ6tW}rJ9T7z#yna6LpPr$iA^Tv8-lh5X5d5dc?Zp~F$D88bB?F=@V#3Xq zDjC}>O#<(rd>k7{(aOX-)WY0VUX~{@%;84^??QZSkROy3>hB9&ByF42U|ksP(S0Ss zjTxQ}xbKlcT&+Fn2Ck`;joqh&<~^b`e}@$pg08tyuuM*H)HLmN3q*LIJrvZacb>CK zQCo?#G|GB2yKeEM@1*5(ajtb7N@CsqE3?i+Zyr8AMR-Ec^>5P0PQ3S%yQSH)a6TrT zpn=M)dZBcSG*qZ=FUD>$R>6mZWoqc%LCCq8M@gVn^KciZw8(bRxjkO8jWG?<8ulP_gpU*cDC=Ea z%*3F%AMV+u7gvzyX0IA8kKP+s%2TJgF}T%fBQr**{`i5tNva4s`@AN8p>*N{O-SU0 zlH#*${D9q!)n;*!EKiz`9?)&G>xjJj%C|*0lY>zX(O>Q=G}le;{`jPB0>wRlJe&TS z#$CYOTwbW)&XG2As}~#RA50;PV?f+a5TVtApOSxWaG9M5*MgQI1cP3aV*-pa(fW%ZAy_ z!FSX`uNBLOHMT?J4mnZAs|pw;Nytjt+p-$we3}I&YD%hQ=JHr1zV?CR;uY?qr}LR3 zgH;ou3k`kEl0En#X^L{7jKc`)gQ`))@)w-1;oQx!IT(%|m~}4nuc0+N{0upo)`MEXFscIxYf|tgC|2DsNhOF4sl18dTRqCHRRi)Wav@OuXUWm94VuF z!{%6lezL@*G@Cnau-%jJ9rhQ@NcK=j`Nk@p)!JbmHP)0)*C=kDN0ghbCrZiKJyO5~ z_XSszdgMK5U*B(=3VG5FLIt(VI}&cGlw%{KC@rnCi{f8!f40DsGy;fDfw)B z4((&rIq^)htkq(Q<*I^>pvDz4CaI_uh&RcxwVV_N)ytC|{qn-iSM0}1Bcm6ctb%3i zz0#x2hMCsu?+*a+>0d^Ce<)V;rO7;s?U zI#ec@Ye-rXwz;CRn?99Cu7+KKM;LzW?(Y`2r>2JnjQh$R(d+^~LndttDU7-a1Mirv zr%z#8=t)89=*^^wNlnyZ*X*UHY;(`L$;Y_1(7a9>!r^Uy;ET)RI7-iJH0MjvQVR<|BOLX$_fF&1MVQvp+xnQfvFH$6-tI0VHMN5S7fq-iQIX$j`1p3oD3>w0wWj0Ht6G)MZLKY z-!r0Fb?3HP2k!Lk$4@0sM~&~(+)sy-W=Lzsn%mU0?N-S^uA~Q)t-^HpF&J!?0OJ^2#-1@1HW&J7;rjjZn-s1r3svuuM%= zo<%BzT7?=&F6t8lMaiwMiL^p$klZ^cWeI-n^JpwS+YCXNy`-vtYLQb{?e2gCk`OAo z6F(K;5qMu$%`h{2x$$gOhN9Bo7JC)sY#Mq<7bFK|PNg8*u?U>yYHbg}DcdgaB4QRb zZgokQxbQIL1(Pgck6woX7L3XB^J4~W=xQMu$gYgAgXJL)x`L0<>SX_TS|Fn8k*|ft z!^w-49Fcv`y=Gt;N3EEyAJ@mLopEJ8mCDR2TaHlK?OK0f6DqIrK}CJ(g~ZW-yW}wc z;>ynkLpc!;8H2&2f)v zbVddguulRWSdWeA2?~ki9dg&iEsRd7$S=LR8dzU{uJLL%6G8ZJ->F$k1p(zADIi}< ztaM>zZ5ve;5Tq)WOHmL)BCz|zKuP6hY=<04r|W$zkk)8hnc}wi-2RFU6qT~FgU-=C zj;u?^;>~&}7KPZw?jViYfn%v!lO#1T%3EQZv$Ur2v$*=(c2JnpJ+i#;A6?qZEPprF z;OzKVPxi&~rl3Xq6HS0F*ro$oarL`idc~`$c?4e1W{uYOL{A@dUcZ!$*Y|-XU_eN~ zPszHR=oepaPL75lD(Yl^Z#i#fEXB1;3ZAmcd`o~gQgbRFyuJeP#w?Jm6-?^snhHX( z4$q~g*O>ohXK1r;z4r44^7x|{y%G8YoeMoc{9T>rVUQ~%B*XFz>hf0?TR7#iTV}*H zGy;x&qucf=#ByN3ZTT{HkU7U?Eqr#JjsUn6>o;}B;1;w``48>%gxduSoXxX97 zpevJg$yS(p)jmFoEP}h7HszGveuch14 zo3W{+=WEHv?9!lU>H#Bp&dk*;BTZB$2XEF_oH?qm0AgIjv&tAGqd04i)_7ZRyq@Tl z+RSS@Y$38vqq8Cqskd_u*`UnrP89r@Da9eWmoxSI(E0 zB_%Vu3MSs9y-h;ZD z`s7|8KRx&qv5$V;|8<{RRb(RAeVL`a&;L3@ z;=(=wL6)lGvwkClldET}h?a-19$_|bT;G?zYG=##4z_J=6=<&BKk6g`B#HaDAYyk5 zh|8eek||oF3(OUrGj>vRQRb+4+D#l&Ve2zym?%t?Dr`6tn=no}lsqM;dkx`@Fa66S zpHAYveLVWnn$^heIuqXn?4#fQwnFVZ2#?Yf(VV<i;xU`3p9Q-DMWwfqOO5&LLX}cv^cKpimik3RtzTkSw7Frz>5fyf~ z8`9d|xsmSnVvgQ};+$vBj?rilJqSr!!lK!>^!Of^2)AXqo<~PV>e6J<@g2ZGdO2q2 z5Z>@M|4>?%QQJ1d@zJ`SP1jyMdiTeY%=xNzaV{24B#zWXX}C&ov4hi<5>=scHaJ(` zSzz4a7U=T^D#q?89Ez|B~3vNvz#*kuAfbxJ_CBPiHUBv5zw7`|69Jtcb5 zvy1q-eGaDld}c+M)gG4-)&;4iTP0y#=&_gptCRAzpO(H98a40wz4qm`i!XpmO|gmO z?s^u-!9V%iN=jh+=~;3Lz$?)Qt;v<2T%d=Jl6pPWTUF_*_?AY8`=$LO5(xWV~&byDfuY;%Yp(H6<%EFZh z-DM!`+yc+3?lzQ2$nX8bZ=o!_+5b2i8ws#a2QwTe_+ z)x9eVZo_KH;Mi-sG>yjA9$OxoK$at_U8q}m9uHS!lELJRilX33FMYPi{}q361B~^s z)btVt#il0csC7NLS!oo9+ODuS^8(BsBp!uLE|u9R}3A;Q-vlCj=y z;=&F}w|=h$<;vT3%x{9>qSV`h??2wX;XNKa+}>2P+`O#rdjp>#Iu_K1h7@Iu9Y-&{ zo84V}VR5!$R!5NYi4`18M?6+isc7N#F}3`YtUAKWA&& zq-iY%|EPnmuag~x21Rr|s7ZI)yMeWP$nM2;@vbg6&g@~D8YW&%-XmTu@Hy#ukI23& zmX8h#=@4DEy@=D{UL8G9VpR4j&e-2parVAu^yhmu>3i0raGSK+b}0p(kwlM=`qwNO zT!^cjyodAkt4PZ^c)G5L4e9L=kNr?IZnRL}lTijm;-K&484t~&pv}laJ7F`#vHd(H zG>TE|HvENSD+-*aWJ>4G+$l}~5CT(yT~raVY`gcUjtSP2ccw9|@@u~M2C4Vu%EO`lsuKV!}e`hs;4m#`2Jj$Q(2KX+Nzd&}iL0M!3+)CM?$UKGml6Sr`3eSw^hQLX5D!JADMMZFrUK zMRGyCF_VgpyN}kqPgON{TbAcm4a?GS9!CC-9IP}N`_RMz33R6>2Rr1(9_;XK5S8gV zUdXO@sXF<3Z?bCPs=Xa+A4rpID)ek1io0&dD0-SY7r#^!+xMLJG9I;u)0uE<9H9N= zegO(gR?;>LoWQHKlM75k!{vFAjZc$#0rK$iWs#c z6D>flK?TwKNQ*BM(tdYcCQF60%|=z5H94|&LfNj1Zzb^v;!+U;O}o;koHqjIhwZh?)7 zmE_qNYhu~*B+V8kd71&F#vOkEIlKWFhvC-(U)Hc2&a)=E5tUnbBe4di<<@ znf#|9Vs+hxTj-!7Y7j%G!^g*ITogHTarz1PmwcAZk+gF`u^x2RY@tpE+1JWX%SaK?|*hJz^8n3KhJN=%l`U(7i{9EI!1%69%5OHE=521W`1O zY2~byCM{rpbL2_M9YXVnD4rEXVx+}rHuUxcyf&DxNXfsGTUA9d%bbm z-2r__?scgEMcaBVM&|F%M(26#XGf_fT;yURy8RoF8%lTVsc`l+ijN8hB}D3hK^tp1 zj@8Xb@wsVU@P}*w{DnTrCx?dKR1TF*$n?MuN|_MgpH=N>+fFV4MNMMN<*GkTq5E4e zz^xPBR^P84?+ef$DCHtkXpI5b1qs06F^Uw)wOB~MPOR=-I zP!|}YMcesEF3`RR&~C3UU@2EPca=x-)$IMJn#@EV6Q+`Jm~M`)3K|L25h0qM z;O1=gj18#P-{f4e)36`xG7jivZU^+f2QrZ^Ztu}P)kdB_;eCt-?;f5GtJN4;h%?u} zgLs|b`Yzw^28+JeU?e|=?o~}fCeezWD8Rd!9iKu*SK#i9;a zw=7uqpN_iSDq!7bgn+j$FdMQaR%Cl12o_H#hc|gj+1H&7k6&mPqSe-S2Q=`kHDYvb zA0+!gE7NdoRgzft0ifE!4=;&0#I6yL|1*3*$|b#&x?~B+v|4gk3nnxoG_b3992%5EJD|!CrpUdN}JTOA9Iv@d@=Gd>#G)&l93z!^y*+6Bq3*u80+=d({K$~NUpw0?d!q<^aIdB0&C}15uo} z`Hf)nj{=;89&8fxvZDG=S*)_o)2+y!WX+7WS*!}l{ciqEV0vh4XO6r2D{&0}_lB4A5;ajWF-B3!lx2fL+3BHt}`|1-o<_nisJG zeq8p;-W-Xw&Y-er7Vf)83ZFUBO{-)CkT&8(Ab7u6OV8h|>@OTYO z1WGLcibYCzUm8%0?DbX&$>>qb`XtuM?F%bu1U1;**R?9D2s{)8f>R$N*O-GTB6u{U z`!5Cpq~8M#LKD^1-1)k?|rv>0niO1bMYW4vu0jYlG z?xr9ncB#%T-~K!9Y!ZpI220${qn1-gL*v0Nn*p=nf59w(6oTK!=xM8j)kN~p`ISHc zI#a-+<$axiv+#|YTSLHFKc6ktt1uqANC)|V!yr~IuJ&m!Z$CC*Kgit#B{0n;0CD^m z5c%x+-^iXI!URej``I8CNd>MrO1%bze})!X78p?|D%8+Wfx|r&waakOsNZM_Ddv_M z1sYeqTJYo=#yQO`EySV}n7n_i7_^HZ|MGCu_Gdt%Wjg|mS6$91+^7q#_O{hAJ8h6} zhJog@yx2IxC>x#%3~$sx;$m}0=ja{mn%d?m@}Xqg9{iyuG`c5+%Po;rNL0YtutZrs zb>ble=6lvfnoWz*5^x>w(o%}&MR~uor&tv5Kxr1FY)A4013#e752*il2h^Jn z$EKi`Da0sm7tMX#b8ZElV$X-{4doqj+~>_ViHTs>$FmwNLDyb!lv# zV6xg+Nuz5YNC|#erQuj@E*PeZ5IVE_A0xfMNM*IUX*(zw*`P05>m;x*Z+J~4sKonm ztYTpdeD;@flnchZ zHMyd|@$~9{%qk>@q3bCgNdY?of4A@u*oXU9{m{4ABJanoLjrjJBK3rW%AiHtIK#cc9zT!$L{N8z)q^lvz9kRJg$$}+-DnpKON>vzP`{rGtkgJzhdu|% zq(eIa`W)fIWtISaWs#@X|1cN8ODkO#)Q~VhV)w+O%bD9H%RQ|Cwm}Kd4^WFX1~)x; zUU~Y&F#z|?Q)-wCfE!BK@BagidEX@WG1rMbG&fE?Y6E?|y&`6dCz(v;)mMB!^2q%d z%5K}t19xu#O1L5ET1yo#_be%vcijIYSP`+{CY*1Ku>nYHkMz5(9KUK(T0+W=SAO&T z0%LcslEXZzRF};-0V;hS&osDX0k|%VSF%5X1!Y&1-Jk|)0wU)1?)X}$g}OUFyN=la z3Qm4l;E5gY;fFK4Uq8GD;NH93H`O3CDNQZ9`cHlWq$k5Cy&q14PkMaP1N`*AN$UMT zzu$`jB~YLy(!T#^De`s5S1Bz1s{!uY6`x7Rf=6?{e(}?fuUf(Mr~m)9phTdBl*B}T zl6T*P)i*8my>R_OGF}IzghJ%4-@f?i$5*ZS53TxjLA%7oyb_J|w|_tB_j7y|rTo8mrqBy@c9-Y3m||E+wMf>V9cy#>J#U#L|9c zhcY2z+DPQ+FMS0?LDPfAR=@Hj-kTdgV=i8{{D*b=f9+=e#=mna{(S_o{1gA`$^C>M zKB<4_1OD6j{D1H`fxD`7#flY$7G@?V{{HrVGQY1b27$;O@cQ-3}Jq_2BLr2=4CgaM0lH?s|f|Tj$<>@7=Cj-BtbZ zzIN?ZW9>ahtyS}5j5#8e6{V2i@!`LG`GO=PEw1|I3k2}Xm#^%wU;nMR22Uyed*HcB zXuGO8n7aavoz1?8{B$reBbBi;wlGsQGydu6G-@XB1%k;#MqEVQW9=*(#s_opVYt-Z zVRiFvOGY|CS(LPCCIL`X$x*EL1xrNTHX;fd^B0pW8tN~6z7TZMAEZCNk`+C6`vOls zr>K8e(ktD49&BEQKW3dxY_va4wfA^WrSpSmr*C1Qz6QS88Py?>qQa`<{d?2+_BHTF z-q;UP)G{_ySf~obe}Es!fj>x<&Hi6VAU)*&1NmRJ{0HQJ+43I{QYFNMq@)2S!hV)I zW>VAfA_!tD)GOu_@Au)KNkO!)qj+jqX4@C{p*w1BW`q> zfg_EseT%cVA6m*d^*<;R2eo9t%T^xJ;{dx(WTvY-vgf=PfY{LnMDzB;bKGAw>iF}= zNTtm#?(MvpXQ3hsr#xXKv{Uw#)r+03A8+p-ukY?=Mx}96-^cZ%nhK?m4H*NAzjM-7dwRb)oF;IAi3CxD-j165Awown=(4sg%spFMu zoN0HPU$hXmCyDdqK->hunnxDUBKM-k{c4J`+vu_wM)NgIR<{1&WC3Z}J>Teu%5TgF z^a@sI%Ag|8{P?P!qS+DRdb~^~9*3>3DC~VC$y?KeXFYc-i*_)o{td1ByqnmAAa87e zKwF_*j2=sF04lzKkFL)JHYy)c0uK?JKy-wakLvhs6a(jhX2_Sr!6Yda@!?50&h!~1 z*Q!6I=HW5z>tJouBkY2pTpX=h$bs-1#_+Q4>W7@R@z-5X;(lec!0R^y!!T9Lq7WBs zm3FH^lL?c$dRQ_wX=2pc``ntRYu6I(%aRwE^rx)o#S z8(lJ4SPy5rj3OspHwLRQtp(G^Q{_3{Gq(OAo73EtqA`8TR4xQ7TmLWF>{RtSsAcNv zt@K-2UBza7Fjt<`0;G$oeTy=Nr~^|~1BJ3#-k3nTTz?%zejuv?!S*{P6X2?frpv>0 zG~9-}@DsYgcoH zc?M<7a3E#aHmWIQTpZvIeR~<}d+QVb8pZ+Zpo~fL`KQRl8g?;wPqLV*l$g)y zLi?s#mI3BF9?!m)L;MAip4;&P8@=*pTZ6)3Xm~s|iGVXNXX`gefM9&M6x8G2*%qx* zb0)T%3*+W?E$r{BYF7KAdwkuj6~R#cKXAWiYTEH7snR;#dYP?7Pj+6IVK~oC`E-4s zjbV^d^eeY9ZOtsF6aMVH)Yhe&EG&w!MO!`z-4)aeThw9(-wZZqq7Zf}lfLQGkXdh* z9Hz|*X2J-z+;E8v))!hl(&Px|8id02T#Yg;uGJXqdp$-(`~9uj%f#u?@2t#7MJDF% zaFEOW6Jyi!meKYo9~X-Ltr{r369M+VlZ(LSc0{u;qI~aUh{e1ehOZn{WwqdZYqNEW z0;L)Ajwyx@(!?BNz2C9l#8|zLO@=dJmv_CFDiCarXtW{lYE9Q{dO@V-$>^9BsmJhq z&(x{~?J`1g<`Xp;MnA#5>;3YdYHxSCzeyNi2Pth;)wAIaxezY3Sq-=duHFA#P^a^{ zqf6#|xS?NDB>Ns7poon0%UXky@Oe6A>)aHMHt1!09NBRw zanP{p!+zZi0p2wTx)CD{$V$k}RNm=I?e?6}H4m20nqxTGHF3z1&v+eODg5hi44mEq zM36L&yw-|IFlwV%rfL=BUaa>frXMtQtw;lDMWhGCAHvQ-K!A4VOSTYe4S#C&hliO- z4jzPc;9iKj=v#-=Yo95&=gHiCy99uu)qS_N3KaTqS{`(U3sl7v`^7WtjH}}GZvC>B z`!N0bbM0?PMA)!Ju^|8?9J_Ucjgk%=;D1T&4rv@-<{RgJYi>t0|-RqwAs2r1OqW0zv#Gzq4PF_I42~j3HUq6@$+cjy+b1hA7R!XS( zOSxUQ+fX?dXVqg(z21~A(9U*{{QeGmvb(=kP~THsaj>^YE}CDLgz3{@WbnJW@xAyF z%VwmT=l$M6F_}~rj>+vd!T}o}Ew8q^hR==f-n>4UEp^)al;C*p@muS4cj>}Z#z=A0 z07>gvgKn&*Znc{gF$TTZnHKZb_fm0q!qpaMI}eYUyPQ5ZgVX)}?Rt%3(J(Ab&Ga+G z@LeG?2x9o4U5~YkD+HHUJyi-^WOXI-14D80&hABGfDn;h=(w4Oib`?c*cI&&-d}Jr zHiThVJ^u#2C#t_TR@_>P$F<(LqKgS09TkC8_;ARJN5_sh~Z_SNieEx7y131s(-TKyW zV}$k#cPt9Y%XoocpC85xwvl9yC0jV1!+UpW!Wq!F^ik(1m#f(bX>jp0pnu*v-fFI` zot~Dbk#pI_=_j8{n@^Q>|57|ImukE1bC5BqC|o@T+1RXerpb>pTR$JP4AUHUXCj|m znOduNweOiAZ{F#?8$NDiFJZbi7KpmxQ*J?z`9UMmR38}?Pty}`480u&S|0!|cMi;aSiGONDi0&-omV^F;TWkcB~T7}P(h2vt&PMA zdcItz&rH=pa3S4ZZ-3Wsmknykq?fuaUT5nCgRuVm5aYimS}RZ^!EE+pIUi@lxrNiJ zEqB?%MJ+bbLAAV64Hdmp!qYjec?S--i?N)Hw|47#lOwpz#%J@|xia_~CjLAF={+z>I6WuynBC?gPbnu_y!%@`b1yk*e~!Y$+2SpD`grGh_jN$o;gczi zgJUG8$W0m3f++(Yzx5aUTRc3*t1$fJLmGDC5!0imKcPrI2_n*)t|O-tn>7eS*5v>i zbq#zO7+b07>d9rFK`K^O)l|#szCJhyg&rDqdK~CO&|$Ntc`R*|W1LV*TEL=Xo4M95eu{6@9U=e_p>Cpcjf^X)L1X<Ety!*WqtBt69j*R0jl`9NTK+?UgReOaGi80JZR-%A@H0`k3a-(+Kaed-obX}E z_m$D3_?9RVEve|T3{5RJ{>YXC9@Ao6MJjk+n$R_ z&ZMyl66+e!&&8#)G?|8+&R6iuslAl7j0=0tO3mhhie5s@6VRg?)(JmURJQ#Dr}VaZ zFQuA;*F3HXqxWbhIrM4AbLHC;)ga#}YCOSHT@?DnZ7FPJ&pTW>?)Zb{V-tyEF#F%a zG((!6?E9V^H+|!zeNs#8b5v7yLo6fwcIpw-gqu8a^3y-HOifQxR{}Cvl$0@+el?$( zq~q=@S3izZbO`)x82AO&eJxYj!O_q}pi>s{MNQ48 zcImTsj>$1!k~KCs8AUwRGNM$KY>zhT5d{{`?{9r5)6DVxjy52_&waVYQ_5J8nC2VW z*AtvQGtP8tYioiJ_DseKQYEr4{dH0F>tbHRAsmsm1>P)Ha+ddek%-bbX8DMcr|jm1 z8akfM$P6sRv7jjl#SFy9d+qAJkgqf{RAOjbCi~V%@g6M(rn@$=e{Nu-g6MD0j?7Ri z7wy>)P!dp8FHQj5$EimI0b2oZOfyQ1e)2zw4~`138V3=LE$k%WuPH;tjTF+c`jta= z-I(_LOJ3dzj{rLqS5r+$!?5Gt#D8TYqh(j($vMCRH8qp&a!&3@B0DC8!Y{XBHa(H6 zuggz6JgR!8$|JC2Q`jl##ENJT;URuJ&7>O7s0Ema&1rUvoY+vaLULTXS!&01Y$4*- z45QvIFRvzNe(_L)9!mh-acS|kK6woST5)FIJg8($qFJ^0d{Wo`-86r5jUi2dnuc;L z1{CaAv;93Y-p-qWQiksarYTqBA7^1iMB%fz(7dT-{N5R?)1RMR%#u#P1IVsVwG@+H z8r(1qtW-?ZGsssF&=2MWDDy^@3;P>kf6lFErY~cKJfBsJm1cAqIGQL%S(|@{rZ-1hp+#uBPozoK-xuG{(9E^zxyw|kRE z9KWU^G5F*|xeepg0LhexEZyG5Uoyd`n$Y}&uDMQyQZ3i5^BgY`g&t5i+*a6dNa|@J zJiBp_XtOZT{v5t_t!e%T346w z8_7R$MMXFee8g{B%{ZU+9Gqe*LwP4Yrn%NQC*bZ^eW%kJ1X}MRm>p~n2`9XFHTZ*% zlF-XxTlr?XgE90kwIlu8V8Y2w;5>H+?!WF+-2d@A64m8IS%6-A<#4X$M@xMPX`4fo zLVt?H(E40xghxIMA%*5#Ucr6o+lk>!t8R9`%k}hEq6DJc7g%EJpC63ce3nV|)^Wky z8=}dv5k|m#zFh@GS*&HgiW6y`e5UDCi=r22WJ0<;Q-XC$qJNMpM0%( z5a??`Mw^R3`0td&J2#kGVITYB#pv~T@JJC3@KdwRlJm#3c)^&BRjPC4C4WlA`@<&5ynSYIqCYjWGzT)$A}L3daXWZA zhoSxxGW8(aaK@NZTUOTQBX?h-bcuhWrNEnk{S!CcLApqH$Ou@JdKqZbVK@#0dyiSYnb&-Lr# zX}krOD?2KydW#d| zdw$wQr}L<9&pmB^(MGgFXa3|oTN~PZZ$ob_>muy4A3Z3=#zXfU@B3+*iCjPVmV_9t zLw~!S+4^Q(zZ(ci7#4*A6K}`sI(p-}#VrZ_h%`u*^{juB?1d9lpE=p$FQjTh3y#)` zIG<}*S2H-}8MAHp5ZV51Pw~PnQq?5RB)ie}Tv-h!nKS3&W;dNbddIm%a+DVK_QdPH zsKgsYAB{W*4FLou8>_Akt&$2mtG>UxW5uJ96P8wUwZ~sdxs-Hn&^>iGQk|p%PP&BM zG~>b5aK#C_NUiJ;xr*?^9#9+F`8H)At$#Y9%KD zKsp)e>242y7|9z9+zPt|Ud;IFT@9~4`(LXIi%@Y177h`MuTPjd}y znXS>PB@~^|)9*I&DSlhvW_U2LIs7CeW9-QmRQ>?n8oUPjcARx}(rlI`IBxqrY^Lu| zW(-3OLv`FByJ(uLNV+?%CC4y$mdNCKG~+H}#+_Kmo3ZGJC?hgZk0fSoWM$qnL-6#p zVD&p8j>JxAEEkKFYLyC;5IjUk5ayqIF{L|Xz3o1zLelKVgu9anW=QYQUgl{hNDs_o zmIM7S-;WE|p@o#s(J+QJFg5(!PpL&^>EYqIwx=LU>k(ml#A&BbzLIxv+LT!i>?DZA z8H_xin>6b(jdgoH4<)N7?T0S^<{fPt?T4hF7h3!Er+gJAC9L7QSR)}s)2&MUnogW4 zZi?|`ja8RnfM=Ys4&tHhM6frgo9D$P)AwT!gBpq%l-+o3zNA>5HlUnQVvCIJO4PrD zX7APfH)p_6R6$#m_BH|TdyWY-u5uwvZjVv6zM!Z(phIPBWMHE{csMR7L)&h5&*&mY?t5p_G+*u9 zmD!g_E~8zr8eyXrAxNJr<+>Clo6q;HN?tqwqK>9b zzvnswcLxn3=1y@^=f^qmFc@(usBmt0Tdd0M>11jlLN{RSG1z^I@{-*;b(?9P|N>(5*pEfKusg|k>-JuuFQCM#- zt8KrYrOLHSrmK7W9Isi+pIy8LS6tw&07n^aSy+pPLg*6#@#G_eSL7!!|Qn^Z+^Toj3*ay~Xq$z@fS zanea%4g0MMgp1w`{7t%t_C8g8Xc-Q-Ab$7M&(l%W);VV>0vDN?38-y% zu%fbS)g`PFr%#R`_9gLLQvvAc0E``329l|4ZX^Ex?E(Dn*!}vXPp0d1H@?hQTb#hiN_4Vy zi4WQ8H+&oF6@I|AQ7~Jo{tokq=={-+|)48aAs%toR06jX)>LEx%^O&iQ^{WSVHh(vzUBp+Ew6PM*W72;Skg9+`}acS7%W2p|Gnv4i3*=@ z!!%E*e=nPu{q7hlmunC-1cODJ{(h4TP)B}hwD1fA;?A;vv5kOz3%uz-y1?6m>(G%EDmD}wEV5UVY`I-7 z-1zKCW%P5JTR+vDnB)6g;d)%e0c7327D5k77pfD_(UPe$yQ;4{A^5%BKnhQi+{LVp z)$)!k7kK#wc)O}SKBd%TuX{gr$bI-oME0!A3>f+?0X^$o-1fqVN`-QSl)bhUUs@G< zvOxN)rhknL?pHNHO6{RQ57U#K4pZ^(2r=b~W*%$KCa+777R>9#Ybv$!c6fP}6LJRK zex*Ycvf_CWsY6^c{-n^t^F=lFhH${b{@rvHZ-XYs|0IJdaas(f3i{4 zfdL?mi(&{grFe`G33?>t(TSFM>E@}IQ!|RY+fuMmGN}B^Ym!t#em~r0;f0(#(`D9H zT=Mf%NjP_kN%fh-%X1EjBy@&1tJw8Dqgl&&%uNKXkG?ZZ?co#~Xar`KXr9|O4L2uV z^Lq38c*46S7r-=I)dGGz$#wLhFIC*GsQ8+}cDd{y-D*{MArTam3p83!Tg6|+Imi>K z16@2)uoI%z5;KMUpMBfqR>ptReEWOxdhE2+XWFJ6l=)!4;(R6QG>wMgHTZ4$ykcbh z$!_zgl5;384H*M~PYbryYqg_ezujZw`v_Ip@;SOO05_R%wK-)5oeoFKvXFd}YC9Q> zPFc_v$R$~?y;^wj#TnyA%I3&ZkTwWZSGcH1K5dYdzu1lSEslYhMIsRzk?>i5dWx0; zel+pJNuVisRKoRt^R%IawOG5oy`d-{%vuBPF<_8)sqeHQz_i-(y9>6g2c*<2IcV8B z*=!u$%k;}Jo$1}}2j-O!QOo02b*h8kT3_=xI^x%Q-4V!z9{wMIrqu)3M}*0ZZZb{^0`3Yt^VV# zT5dD~WG?15AISDzaXA243`X2u?^dCvANba!6`auNkm{p%1e?iWDjMPa&eEW@3262j zJV%%M{q(_%C}YW^nSPQ*qIu4-g7rT1DAI?-*W|esb{?u74Q=R;gN@DK1gz@f@g1CN z=Ec^D#wI(&w!WHS{b1rTVUndAdAQ^ilhpX={2Q*CP$BlI0&gMq-Ko9uTte$s&&Ap~uyh%p8!vfUV!iJ6aux%6^FVUDG(|-~&c~`PXax z!pBwHU#WQqHEYVCRU2+kSUcKZGuWwj$FBR_KmVZ>E?y}-Ehbl%c^C*&(ud0ZQ)mWi z**Q|s?`}Pqs6dT1=`Ab2>|)RE{S{}L>Lj3)=@RA^3mHftkGCTL%e(fu$c0QS3YPGJ4%#9-~m7T`%W*G)~QT zM!?(pddqJEN+oiR5`|?gg6pj!tdup6`UpV7?NxgsyED3bSj5YvZmlx(-!H8K?s}Ft zvkp?HcQ4CZS^Ve4e!YjDcB4)?rVmWH$naXj$m3=C)b9>(R zjdL3Pxh;wuW4t{?KkfNqp|qrOCfVU|Dx^=h=<}>n^D8x(;!sqL%UpNPus9#Qn|V9; z1hb`Pq_%6H&lqQ{XO9lpa@Z!$aE=dGuU`)ta&2(P9^)0{8NNuF=d9tEODO9v33RK0 zexNwE4`shRL^*8p^%6}K?sv;oFkEd+BXs$885&+a4>LbtFa-DTCvMj5jxrqa4@zTW zVa#*Q4O$(=##yKb7)UKmrI<$03mBirSDJ?8XiVyN#$ze&36WsKBKz2ET3tzvHV>@) zAVpd^oAys*cf+Nljrq($phBv3KFCzz%l>f7CwPV5Y*6oy@{9kSHrETVeUk%yO7@N;&5;K-_{*& zHU;yP>X~zr2t=t(kFm%z4dFV zy|7QktQC3l>M)4w#!B#Pk|f1vryRAX$%u1v$2qI(C_0j;FKxxACCP%}sC$OEiOqPW zEmEz-=T=SiIz5|FU?T%Dy<_iHB9;S+c$J}1vn@Y46&OnQ3;NaJrpj)$h-}Asn{W&w zcbl)PIiVH26ItuWa|;cXa4E+vz%o-g@fJV4s?=J)ect52XDQt&{w@=mXZ6xJE%Yi! z?_%>9zFWU3=egx)7M%)}-gLAl7OswT|0`@Lo({u4a)0t-78c#L{Ew5CS-|;BGVi!h zmVcKdkJo1fH!9_eZgQRPO=hcs#7PlbzJr2QPX*--#AOxCx?{5>I z22ZmmM4$)NVLCK|{&NlPHOSUz^<<-FYm7P=3QJ(I5;969G?SOUhz0;g?Ys#*{ti26b` zul2Qz+CxqWD8b=*f>y0HPP~PeWnvNqzrhN9o%7dEYWI0uQV2DBR*lk3L`tBLV9M&kRjJgSwZ)&#QuFbraLy#sYtpK4GWO3N(#~<@Er!wAw>OXJ~+r8Df zEf~&s2zP>bDbVt1vwX0`6F*nF) z|0?|Ba;Z%vz(g4#cISa^Q{RSl*IC}lUC7i;pO?k71=>ZOy(Wh`tmP&m#!Pm6>_;a4v03l>*jY;`!K&rc!q?67A)kcop843IVlv`cgUr`JJ3G>=?&$!wMCbDdF%4t z`f@QfzA#R7XCq_d!o?9oz3zAX_8K`bY+a#QlTek6WvzX0MZyn~;*cu2>Xn*oy1a@J zCG&{|x?gv$1JO-O8MKli$;rw5-jTdbWV~z*pdQV#g~R>Kw2`S@MgDQ#rgKa8XMS%B zIFYLBF)Ic%lG$pe&h~@`6u48uqnNN7fQ)2;7l*1b_rr&Cn{>C!g^j3)*XQ+Ry#E=- z4+cX$n`9X{{z+jSwo_px$5g{-Mmo3Nf1_?Ws^RX0s93+8oGy#u`x1HLARil;iohy~ zofuf-GN@xl5w|skz&TOZ`+IIF_jC5Q-xI2kOlZO{_4v57-!JRnm58*%L@#2pI@Tu| zs@OTeRI&|Be8Y!q?W&UKMtAD|oQ1&B3-+n)?}Jq2`0W;sdD!3Gn3Vv|Zo|FEcBNCR z$_n*m;sfLYWs&q%ruw%-1j2;E-VY1)x67P(H`bSysV^^AMjKm#*-ESTPN1g{s?&HE zs6I4Y~gqo#HPy8o<`4 z=j#))VU5tA9Vn$e;HA55d|=>7l_9zkqfR50`OXUMqts7wkJ1ZRv23g%*o*Hol^WaT z5PsX!_#abem*JYL%agx~I2JdF;sh|pe_&cGX0 zLU3oL2~>5@W>x>5d{{KBh?(?Pw~uhKEV#suhS_f=gT|tlQPKs*YdC4}%1X+%Cqgr^ z=a;S&L)>*7Atu?`>K0bGxMYNKdc8~8&f3a2H6Jmc#U;syO_#fcKkdvHfO|jNTkOc? z=t0=<8`}8AZCLCL*#)`pA{Kme|%FyjuNme`5-#J%{~rOWZGntiluc|>SyFE7QeUXq+Otdck0IoEd%D8o9Vfd-on+7 z&bIEgMyGQ9*(}DIj@76Yy*}riN;)gS)7zNV6sfPz&x@n5VaeD_KbNu-GZNH;2cV9V zr|2-nSkOn#Lrr`9+K>O@@VoomOiggbx>0{a;|F7*$(Yd6J8xknM2I_OB}HVd?|eEX zlnK$mxEfSz@(T|m)ZnCN0c$uI7`Z`wEoL4HLka1Imzj5yC~`vC>~*FQNXC@pDh84W zG%TdnK$x8qEID9Kp}WD#%Tkk8GyT9Ax)I5K9X`+K0p9$+Zj0XAZ6JG(Po*3V z5Ks}!U_SNHA^O|V@exIh1_?vos>$A-(y^*&$NtuVC-ahif|4?h0v7<5+3W2QWlgvp ziX7Yv_|hju+PA%9T7N|sW+D)m2=7?n`2aFJOsI~((Brk6qeW$?vwVMF3Te4m?_Rv2 z+t<`*>wZ|0j7_c>5#7L%ew}VIW?x zk{4QuIEa5QxuIDy1@8YLYts#$Y1y00pjOD>bRgcRE_I1UPzI+51_lCS=Okyd96j7R zG#usctkG3qTHSFZE9>jj)3C-EdgEpyez6F80+;$uhU&zhC@J>ESz|FRwkui!^5vwn zG!OUo_FU^LEqXw-h6^P%1m{Q{XxjL7oqPmNy7(+&c{k2L-Ub_RJ74<>@UJx|RkGYk ze0in&OR<_(6|sYFCkMZ0kCNLiN;vz$Rv>)Gcg|`*I3)#p?1H$vC3K)I=p*hoF4Kl@ z!4|#BSD+u$&5efoQR=HCN2Jx30KIyqP9nmaY9i)hy3}NIbaG7fvCH)zqB5D!`<5z= z{Wx3`p5{+SYD<=*y^|mn4Q@ljHe8kPd)te%wy`@R2_`$e0nX-w7Rp#}6& zBG3afH>g^7j(Z2cARi2y%?AUX{Z!utLFPW3R z%f3iBQ?QSKgKP*+o#RbqSE}V2tAjWU8GrL9em`3{P7hRzROdZ{#Jr5~G{k!U_S>55 zHjd!MlMi8CZT)3!r^nIXI%Or9pFQ%B8cx1AJUkVT1JEShtJLx+ErzdtFq5~QG|K@e zuPxa+CKd54Jvr=OSN5Jfb0^a`rjg|H*2;=iH`zi@igE--XGxY<>!)AzHaX zvi!KMeK!Jogcn=ta5o0*bqDF#Okf(izMU$Eb{c%2X(+`^gk>*sC`0ObA@wcTfO| zJ^ekbX$7a|{6Aj`7?CE5-7Ql`UhD}s@GT=9Hg40Kk*8Ex3u$nFedr}RYY*|$^$3Ab=>vN#|{1j&UfC~LfBPiV}YSN99HYs zd(l-NnbF|nD$$RobGPfwJV2@D_@cJl^F5Bc?1S~p_im^kRj)jf2=K+Q0XZr8Z zmcF&u7*Y=o6wA_RRz|A!)xRV*U(t9DlS91&Crd7$m2qDUsZ|McJK2tXus}l^lOb}av?|*WqiDc zdyWweuIi*oO?Wq!mWxmZMeB0h$nZLi_E;e*$*yxD2ztL{MJwSR_pVck)8q=3-om51 z91Yol{+d1B$R5k^KUieEsr#G^$|csdX;h|2c0?7wS@E4&IkQmr$c^x&)iu za>MI%!;`AU4HlD-?5Mtg5D1YWnHt1%n{LPsM+Oo1Xn5hBwS%UfeeKox%ZW~)>+hl6Frocm`z zu{{y#)$&hepx%8X`zW`I4Ir!0c58(xC{r`R%S-=>=q{v#)a`S!7Z9Y@RBVx5?u+22^) zKkyAEjxb6Uj|>#+8xPJHBm2FYrFKUG1P03y#pRuxoPuFc!h9kA1-Tju`&go}8G~|I z|M|t<{}oaD&lKDLwX^+y8+`k3U;XdFxBp`h?Z3t8{xgX7OhfAD-@0hc$i!5$u35QQ zQ&Uqn{?F;2zcY&?5hnHuUv0GL{|Ne*meVm)#_R&c?(>{6|MTmUG{VeQLF>rj`=8Yr z0v3&Hw#W}8AW|tc$>2ee&sZ(jmGf_fu}67mqB%|6boG*n*QYX34tMT0761`1G^Fee8VE`# zijN0Sg?W07{F{>hcVwkXxqb&VRSQXxxmgW+ds^FsH>%+;PKn7r=6id$S*rXNThYE0 z$x3$e8570DlJcRemc$}|#XxGvMVYJPLyB+;o1)1|Jz5?eMSqlajjO7fZ~c{e8o9hZ z+w+SuxYNs}h#fh3-R_w!rZ;Ou7T2C{C4mT90&|1=JWx-1q*c)On9+IYA|IjjxBSY4 z;bQ~N-^>VIA(_7<%M3O}{LHnc3@9{`9A^FcZ@LzZ7;k?&q@uSOU{8PJaEyhCg~21U zvlHa6HC#wbrXN&mGv^zZwApzG9^iy&uoI|JmBnR^6e6@!vE4gfyX7WqHXkquPP5Yo zW6$MW^I6XPvXC`XwlGhVQmGON!*#L`{^TU&Z`N20rQ$>;UIv}K2_zv6$4uHXF;#ME z6Ou5?>MGTw zPdckxURYCBty&&CfsQn_sfa-inX$s6WNJ!o(7u6Zh~<(jQGtGHll}bLpsq7}QOJF! znoSa^u3Hr^VE%}=9{2Olq#Q+}iNXGiUa|hP$KR13IlRg3{3meNg5jdhJ@Zq+R-U)B z3gIqQqWE}JPUIzazn2ZI!A!$Cl~(IV6g`B~tih%8|G{v}J=sO}5(?^D>j4KI}wcVGol_V5ben(7SqII-GnPZvA9%Lsd=Vs%K(jswkc>LxcxV7;YwRv>>LaUkujV{ zZzc#^q#pGdww#icgXyz7R!i2!=Un?o+2wdxO-TbhDV6l}&wi%xGgvO8=kc03Q{{EX z0(XoQ26$0yI)s?R7)l2tS1B4cj}G!<>R;UD&_yt(fP3V1gYFKpzj?&oLs3>Gzu(b$p^uw?3ea4|KE z!j3!G;d_i2y8fK)jDakbJu7ubuA`w0ywH#t&)#0hgbPfx9Zumx_B&67>+ZgF$L0#f z?PY%|N}QR^@ud^5Y%w23PvI7q=Y>A6_0#dlF4VE1tazx)bPQssZLd02%e{&+VwV18OQbf zWjqvF91I5S6z1n!e?RQKe$>il9-HXWG`b*t-Ip?b+h?D4W@T$2f`6+Zk|8DC*A5FW zLG(1&2-`VJ?%Svzph?>a||;;Ce%2qHv5D=U4S2 zT{{x73*__E{vD~8Yc`j1*JKpQBOH$AsTecjTvy5Y;eBs)3?_fHSw4EMnj7pfyN((L zv*Fg*fm6N28HRswde3?r}unjav^u1-iJ#4)%=`-aQ5sR?-*v>2iuY5u`{`t>Y2d8qr)#@Oe?d;Yo&9HgWER`@$qGv z%{^lfbx6C}b#?0;XDqNs3BeOjm28l9m$px-5Bd^nesgqZtOz}3-`}5fRDF(blj7-x z=a(t!Wf^MqzeI2SL*e7{DW$$jdp1TSxtIX)v*nmceNu9AXn44AnGohAERqOwZiiP6 zT23}v5P5?;ftf^vB4a04&IGh*dPbrJJ##a^c5G>bn+x-R?tY&3%ugwW#TNyt&iPYv znF(WXxl}vx^YgQahzMKyS)~0B^*VJ~a$TY*QN1vM%5KCfBWVjtF&;=N^!}{*o;n{$ zjD+5P*3~rocRs{RR7>EDQC0#Eed4I^=77Z`)j5w^%-BJ;7YES>8RhBRGu68NqDFYN zoOE8q^OT8ceg>*aWPDHvQqP#{l%Ks_)FAoV# zajHKk!UXo|_c8H5cGbT=)r!+=CF)}ZgTY!h0;cyS#uJzuQ{38CUw56yZR}{NhZmWV zj!~;bZW2#%RvckVlA;Eo9EMlkBXRWpO&S|^x9tC9qNd7q?HGciWaM2w%j4wpoF<;s zr%Kaj1Ok^gN8g++9!LQGEJ`Oh9JhyYLSw`3p|VWB_p-7rTo7WqyT}I>sXEhhlw=M? zGxUy@>dVKIO%L1K4>4g8RK5!di94217KziD^MqFy%tc9Ogu@-v*tiYGk~2vD57yo> zI+LK$8cim)Z6_1kwr%r?Z9TEgiIa&j!Nlgowr$(EIq!GZJ!gIEyZ6`apS`N9tGicK z*WR`Fu2b&)n_QeJ4Rvg6bo$CVW8!twU%N@8&Z#PpCfqcj@|d@RMJ&EKZP5Ob!Jz$1 zHVE=ACY)0Y7oBMYbgijr%x)Ux2IAA`y1xu@HcJkcYCK?_7o@xp&22D!o22Q@=c>~Z zzz?^Pp+cWS-Z&8xa)t|T=U6QKl#D8?|1^-m(s-46?qqsk#2#H~6m`K?-8pQ})Y74@ z&Wk!%^r)!bT>KS_gbp!p(Gr7{2%GdSPA-KX>()>4ZbxO6t&}_W``I5Xa;hszB4y;N zG*%YvQ;j`E$j`fDQKA#Hdf}>|u;5bYGl36|kIeRyQqHYqnFMu@t>0=xC-gKlS=#)G zBT-USL0euu&#!4^Oh1k#yS$=JZTGVu;17!ZD%5y&@Jr^d``H^<0t!`tOM-gSaFOoj z)8st7jnx*f03AjN_p)@8Cpbb0vs1tvyiM-qKtmvtPd8LRt+>q>6crYG%w1jI4Sysn z`*Y4d#bUj>b}y+68mV_7-hsKclXGIa`7i8LajH1m&67tj0dd%lwpdlxyGp4g63Rd4 z;(zQ_>u$>~i83gX%x<)xD0(7);loY%p5ZXisN?GB;+F*R28&4bhGks1mTd|>E|oi8=nlo} zt@mm**R)UB94<$E~rjwo62&H%V95RY|my|z-3{H znyr_CtIQZ?QY1KLLJ0#A3_Yj~C$uu9RxxczOUZ)Q7%WfEUNNKj*|>Z@tw-`D^FIX5 z(o<&C6&Hz#oMR9lg{+a++d*M zN?>6tt?5&=%Av2-xW_TcLR(JNP*tcWteFlmm!|m+538T%rGNgk#>d~etRQEex2V&= zJrB`3uSi9M)>SueQmR@NFLsASN38r)u^1IaacO2a^5Sv*)2IQDbg5E2Quq|eOi+{B)`~Yl@iN56rlcjn4ND*Dbt@F8VZ;`!I ztLzgUp8$^(BQ*-`Yq7Yn6Hk3?%=GoI^ksjhzl>f9MEAORyYrwOe=3b$Ovzbm5MdWeaq}N1?)HDQEZB3 z3Vg?d3>q~MKKbW8^{y)XV}LZ!oNP+a<74l5#Et#!oYfVb&Xp~e6N)cAfxC`OU@{OQ{V#h9VP6HpWLx_w&WuUowL zk2lG7KEl6aTi)ID`1n_SynA>N0^fn4TYI7Z=irwA4Zr>eul{!`%KylE`QL(6{x|&k zA1U^Ku=XeY`_-q0@y$g=HZC4X9}O=a_TgzEil_}pislNfja56?4p+$Di$owx>W|NS z3h;_?Ah-?tR|7?7)M4Z0X-2Pow@XpyV#A#l;!epG-qnLc3aO3y!eXJg4lur}u6s!? z_Xvr6=~CKVO;_5GfHavnmq%b(@dp$PxP;sniGVR~j!a0j_yw;-$cY&K5Hq}P^O$kz z3#8;`OKvj-^P9B-z5iEP!x~NI&J}`6T=ALg_66c=Ac<}L3}U8VEh@fEz4H4Wtu%L! zc6NRw{Mc8kd*G<*xZh9-<?Vk)Hnn-@xf+a3I@xa3KugypWz zv70ptJ~{I7*!Ke8fu^Q%gBqzldIincur{z_U7}E#L`O81xpba#sWSXA3VNOtkYs-$ z^;7-WY~ckXnp2-(o|8wYSD(x0O-qLzA|zClEE5vm{>=UPdBO#!F+^>iTq`G8TiN8` z9gI)n5hkfnYVqNH10Xwr9$x@mp5T6lkGV&&W0%$``Iiw(O9@?AN;zG@*r_+_?MGX7 z(v|{dY8H0VKq^Z|SYJ3FmVpn=nOP*5@k&dG1c9iz?vvR%bwiUS(Wjm%0`lJ&S+B_Q z158|So-*LCr)vfQ(p+xe=fO$1M%>0CmeT97ho(AF+>@g75!L3e_|7MgnnJF(E zW>MiLg=|{;`hJuTDBc=2Jmj35lZY&cC~P1ybU`Sp4DtN550q*!?WKO2oph5oV`=lB zy9xZ(A6_+799~<#iiaLBE|a+%87t0TPhD3T8`_2hLLgQV1l&AdRm$Zp7#ggsE%SOy zfxnH(FlR`p!uw`{cNiiCUE?RS>*(sJVP=2PJ%6R(Bh6t|RX=sscdbx?v7>(2`vB~8 z(Lo~k)2bsFBG#`HwS(`ntuQaf)P0D&+e_f20Pf2Q= zHsu~4xh`-BKA-2ZFZ4z+d-c!tWYXKocQV(jj?>l>R9`;Z1Eq!riQ>;Umb&Z=^Atj0 z&)3xMdTbWd`7K|IeA7`sw(r35E)ah}?+SCLDIq9iDqRxjoc^tUEp@o^z0K)o9`S#C zj!|-1g2Kye-z`!}21!#4W)1H_X$=VFdCY|uLkJO3Kb)UId>Y)vtp&8MBX2v>(1C^R zQOf^pfBAij&${iI2C+Q+Yu7ew0JpV~`Sb#jWMiIrpNR@~fPUYgu>W+0jl zQ4l>0B1u}u+2G%;w)PJ&@x*_!zjwq8!6SO0M;tF#$S$=6OlqSy8k_7z<+-}K-e#>@ zBR8>wrp++7Zjou+Vwu<9Tg~?%i_?!X1MM5w!|SM2QUKu<778BYIjlyD%lC1whaOE2Ew_A{ z^b8j2t(p=Ra8pDNnpLD+K5QK(lx7btC8rUi@SzfNr3!qTJJDqzX$NbyUT;1hu}=Lv z4U;+9I2R`sC)2hHl|!bzw3hiA423Mfm3^)n>Dm9(#dM?;*F&{v zUF+*>rNyR*T+N$|^74IhTB;nD4kc#Y(s$Z7cx*LgezvZ}_eoVOo!ij){Tld;-q%FZU7UD6N<5B;)4 zYFk%JRd5F?mBERTA2`nRiJMN{m>COwyKRHbLLlSQOLG-3TLYb&1vB(nn>|x9dj7$`w$gQAOPjOEpmbSjyZfLO{QJoy zstFcN_1j89>gN4AMjkTo3Bl_6QPfOU+#2~*xOik$#D|^)AAq*0Qcy_DbPIV}k2c%i zYxaM&yMPEqT)*xBr6AB0iInElY$iPFZLdH6D3iBNoD3KgP0+Gj~I8G`E%;i)j#1BN>2lP`1(~82O$# zh7t)hG>Q;6J;}f=FKRl5R-@$zd|?GkmNZgmXh_ z>u1JkXu4lGd%dh^0u!*a?W(O|z8rbj_mT&3F8rI_I6=VJ)$m{nhZjfPFM-Juvghp3 z1Y?nCWpmMWHG*7fg%7u^7LMhEkE|^&Ay3}*X?BGOV;PpK6gzksQRQbh9cF4NJ~VbVlSu;A^!`uBLc(*QZ@FZ=D$RNC(Yi_t(X z{vVL=^$fUm{b>L48%`oyGeZUm>fp=6GV^g-6lsQc1;~(S@U_`iMjX&40n{qk;77-0 zR`$2{OlGsuD2GjihY*9jn%1KWt$;tE5^vBd%`q+>3cUTUU_h)uscck<`g=%0hYb}` z4-+X+N-a?Oe&^Kaum?cIAt&U|rw21&V;v2;vUXS;e}U5H1$J0<*&r}y6n@x+rUH>f z9S8PcE3Vq6k$3z189Ec)Hfcs^VLoy3`q1psDA^Rg~v=AyrVKFW7zA_SDq) zSUIT=P}FVM)vN;^u#H50jM7H1RGlB@9#;Q+rK8;Pd<+PyLSB_sO(zEsAy@a zpniYl&y8rS`1`Hp^z2|H+@N9FxTmiB%$bMUYl~7zuTnIxv)Jd$F1?-YZiK#^SXq6Y zd(Qhm&D_HI@9}!=R2qtJuJ(8w8<;8LsU~tbN=Y0bL$S-^G85EaE@w7>Jzj5ZV!=vo z`L5;c!74g&u(uYrHW%WRJQDCZN-@>%Vd=9?q+Wm%?_8DftlK*krKX!Lsb9dJt|u6a zia~p4J)M_d9FAXRSDgoSG)VQAgy;En)z0zTwXB)BVeJDR;Q$U}1>>v?-44o-h9`sJqMje|EjhILL`Pk8D&3oCOkNTKIY5_+)vs1JXQ-Up#7>V`qRyNQSgYn zLixa@1_t|h-t$dy$(STT?-9p^!S6Wo?Jqggc8obmh)6i60=-98b}JySeK<09IC&{Q z|7x?vM(kfcMY;jUxUCa{wj(vNkI9IduW{5$XmW`{`~9M1-)o|Y2k_Rl32J}5RbA9_ z&gH2Ht$T~lcC@M$j$w7Pz{>Bfnit?KeQ+;cFNp!4S!=CHuj0pPz=i{|R-_#*5kJyj ziKY1K>-wV^2}g{s-gh_YFv8uW9?8y&YHQLAK6k-BUkvc@dlX+ohW~8cWsINH0QlMn zd>o;=IJ{KM9c_{Ye7#z|zw~f27PX)6)%gAZ3UnN7n8c6d@|>^V9k#A}3SMyXUn_jo z*$UP^j*s+9PICG5&i~E^H8p&-#xlS@sm^7!XCgZo7xZuvn5p}_Faaym@O7KC(rS*8 zuID=gQf03n`%jgonFlZAPJP_E~_nLQo@8sGInQSP*XS4<;k{h1&heYktUN_(_h zcp>z4X*_(zZ+x#FD}E$jYkZWQV) z6%IJJaNlXeCY^8o6jN{#%;?uJMKter;h`Fi9-p(2^M0~cTGQ(>Ce6v;>hkfXsqZ1G zJMW1;M|Y5m^mkF9WYMA{0QNfb65i6X8MM1?6zO_TpY1-ZQ#%}q# zTXER*MASx@bvJjW+qHB%ls+*`hpm&Rmdt6j1rS_sIu*r{= z8pKRXNS24NrLOA2U;nxMHCC^ghd^?7C)l~LJmdTs!gm%xgD|idqzOOf1fQ`KBxu90 ziKGzx0*5PV_SMwsig0^8Qj#T%7N@SpZG5bCLxxG4HyMjOX-yUdsErB-D=H;A&>F8I(8Ee07Jf z3v}v!0|EN(X4VN+t*@6QOw{lzCa7?Hl#O=$<$s~LxhvrApKOEHEMfOGwUF=jbp|tN z`z&6o>Aoq~;(8vgnS$zD-XQSL6HHKwH)Qx5^^S7?Ub=&%0hOnZQIPi1t!S>mZ}O9Y znxQE`RQZ;h)=g&=sigVp0nfpg5M|(V$~#E>shi+=0%G!fKKZ9xkth9+F(&usb0ahmzp`ClwBO3>P=hW!03x}Gw>k|kw3X)J$ZE44r>`5|` zUvzgtJwj<%6dc+~|1wM{Kx0PsTvw$GTJF|77U6cQ91Q#e7t9U&a9{0B86VxSF`Lgb z1vj-5^VC@`Vw~ST#(+=5+u!|W1mi^k8Mb_A6ifWCCTf4(bx4Vh4DjtN%lUQ!ZAuUJ z^39J81**rZgCD-(7w8tzuuvS9{0~0o;ruF#1BC7iPT9X8TJ91%70r7ndg=}jfQeog z`?jB1V#G99?~kVd246=*Q_al;S4d{Wp7+PiwXmZo#x7p8{GQG%4l~8J+w6jY3tUz& z=GqI6q=Jc6k8TlC&BoJ*9*s*!EGR^E&c@IvNG?YhV!%w{(&W%ZRxQYYE=SErg#k8^ z|6XzTm>)p}v1`p%QNER7cboZQtYZ8GS;0gG03LXH!I)aOl4}aJGjKfOd%nJsZDoHw zOH}ii`RUnz;33~p1k8Yu&04!~g`u*eblhhojHJZoNZhva6t3?c8o~3s4A1NGpA3Sa z^>^E{VcfF%3>@XMyI$8$3soI9JaCi-OlQl~FTDhp=`P(|VB~*J!kOjo6?6xhx@kI7LMU3BPLeAYO=^eX(y}4j1 za%M>M!xDRRhR|F+eoV#wF)>LVm3URs8v35JeQY!^MfCT%W`z~sf6yMRNUoz zBDm6Yj$t8*h_mM*INYqed-2z1~0gLlRA z)v>jH6V7@xMYlr|>^eZ0K4#n>M(~|+*mAyK0y5f%oN zNzi2u82PPLg$iB!k;lE>^*M+v5r^+pgbfMyM!U_G%f|i^D$kK++M2v-I-rGy7ySr_ zhL?^O^C9JO&0zXqoa7^f2*Lehxk}!aZ+&4MT8N?*&r%E3xxRx?1#4`V%-Ia=7SBmO z$cJNW8`szOBitsi6zSa5)siYLqw~%f@tvyW2wzW;`}h)XWmxJR;-dMt6XRdJC%i zm3=;RV*Mks%ZPfW+oHLJ&(qhq07FP@Uvij`{-pBjrWr}o@4d%x^E8r> zUK8%ot#MeuFl7C6g(R-Z=nV_#cd=3W`MN&YU-Io_aCtDi>b$F|aae16K@!aJJB&rz zUHu>-ip%=Z#k86Kr?avZ3E%dDj8Is!jPr-i+dCDfo*gX2`;Hj7HF=f}(*C9rQ;=Y| zPa8Zv<(^ghT@*xo3d}qS)+45 z4`QeMum6=i*wpCr?N$s4K&HK)$d0*p-wu$~__cp-9NBk0Idn2BE%~b`y5^U+wl+2w z*K>OHkj2i_G9nL2-uCEvz|-e6bn)|;3^t&rO9LYIQ(JBW{@#p~8hYKV00dX2MeO1q znLoDnJ_PlDrDvuYYQ6LxhQ)0d!qbmRPtmvTO~_k2Y$T0@;#g@P(F4iT^im3a)hs&pYJL&{OTOKof>h&LEf_`H>b)d=M(=>VQRrbTF%*~Bm`a83Kp4J!$ znkpIVc#rPG`K!+nMuV@}>k5nE2Z}@c^vQV+} z7uxQyhqsBw>vODRd)CH@9Q%@41gQv0^>` zZ~;^#Bvz}6HJhjuR_8t{4XddY9u5!nz3v>Ub?dlzE6;1LuC6)lvZO{wx_3?(-*DaO z@YR0h=5}v;)a($`FL&*oa_@!5W;ri5FwaeO8#}Gwsby@G;RF@v&KF<|X?PM?3XXUVe<4h9=K%f+(|H)NG=JUv?1bvE)E=y!E`-#~wQ+mwPu# z(2Zz|<|V`Cu*7FBYKU%QBhm8xu@Uq|J0lc~=+oL^Xc1`;UY3B(X>z50Nby(GcJxQl zL1J3P-4KHOgSSME+e27zCmZYQR`N%vmif>B@DuM}GKXsTywIfXf89dJ@KeV1iQmO{ zvBjbIpbkQQW)7G}#&}X=%avWGpznYS%Eb+t1vl!(wad1ZoCfUS$ZG_UQ}jdWBTBG^ z_dDC>SW;JEPamAeQzejAcJx$6^DD~lS0>7W}6qR!FsC&%6&=ZFNTX{$R`j!XKdn$}5)xU~|D zC#F^68hI@yn2RPUj1T-)A`a2oG-l1KRf2;wP3mVz8XT(#RH#x@M#X2`g#=ajW@3_* zrG~=QP=}whYNyhL^eTqDL=dc*s<_TEy*<7dh36W=3B8ZMKFCBns2`4GmeEAMbNY%6 zCCTTc3(`g|nLdm_@-11Sx27JiM_4>hv`7Om2;!0#|1R56>0K!yM~=XJ=u@G-q{}`g z)QtdNlH1j=<9KJ)0_VxD_p?&gW#pQ4Q{)7bf>FuOl-n`mo2mri77P(x$Yb63BrhHF z-XoCBp3QhEPTp`3EBl@96K#=DW(5!F6aN9{`n6v z^~NoKAATM-xErU&HlRnJ;pmFx<1t z6M4(8+s~6Wl(>qn{Mj?jwzrfJ6D8KdpDw5Qo>R0y9d7IWvMqu79ar0vKTr-Wjt9Je zalzzNUWaUMr}gu@Pl}l+NU#E}U8v|rC`~!Jtk*NG?idOa0pM|I=jK<_ZniKPC1?59 zU_GmU-?DyQ=hMn7`>UchouIW=Zwcqtm#h3 z{24$cxc?MtGWwLZ$RTm%Q+{?hm`^Cc=O z^$0-SWr9MpYj!@ac>A0NywuYQ`0cR^9<@FHHFqCeem{ubvOP1>I@*q6cCm=J`n-K; z)~K1BW*zJF_plf_KS}+lk6N(%IBaL|Q)&&T62AbRv}!Ic{vz^ud7v9%vzmN|=fyhX zy&uGLa0lOR(UvWVrvc6UTF~5t7FV6rV`=u7lH58!$M#$NHwRT(^LD%v%ibGV&ydOW zPVQ1(v)N){sB6*dNDH-JEn4Gy&u%lR{cUM`jo;#1PSa{RpPh{%n#_lMboe~|aA*?I z;JFK;l|XN)m8`v~eB!*i%J4i4vi)YTdqdiSEG6zwf+#Ju=qjv$@H>bR(*^iy7B*o~gCvW%`}h@v)dIdVv#~ z%+PfmQ^-0|ex}*kZ2`!MZRBizo*nf2I@e7g*=3Dhx?}IYnIOCha4p>%Cbtj&cBA%c z`k3`+8?t$Bt|Z%ZdA|j#^UD62>MDtGHb)e2xkc_k924%OeSB{WN?$dm0)pxDK5qi#w;>i_`q%XJX`Qi@i@aV8u*`OU3IBgKx7miz92_= z5VTmTAa+T7Gdhe??4Xi^#w(s5aW1govE4_Bl2dpI5YCjEPvUu<-UU5OMD20cv>yk%dYsu0$?~de!KZ-u)7c@Uz{UkIVV?6{N7dliNWP0nrmctY3 zE@R*Lm*b@-2-LZ8(;X)-6!+8(+uu6Q=Q|AF4?hhJS%?_3eLk)h%ut8~-EI7ZFXcTp z>Rpe8t`fZPGEJmnKVQWa6X+~A_z>GA~IY}aFaF1tDhGFf&G0XM>& zsGn;!xknSU-5;Ofn%UZsq6ZKj{yZc=(7u1Uajlt0WhKTU%df9i)&i{Ts{q>^eOwl*RbFXqc zy&auLlP!nptwDWIlhxF7@k`kJ`l0kp^0R9LHP1`_?J+Z%syx1t9y^EK_Mhy>)+bx# zZ?o~L>ir{m#try@k5#NiNgta$|I3$6ttSy$Y_}DD>3`Oq*DL8GWs5t0YT?|tb=M7S$wi|s_u%VxccB5PGi=%#XmIQ+cC1hc+QoN zUeo7K;Nb0+G40CRW+x^j->ci+(gvlAh3Xo-Io+4NgryL15WKx#EV&ND z0)hp4xZx$1XkN8ogIwi8TWfv5yZ^j=DT_*3Z8jIHc6%K~@>eteF*0>gNd$G+hqZ)~ z+UjBwSLh1)60#34@NBA(RL@$9y$>+#`gdo(M!)ffxi+-)*MC=2fDx+m6skE8RW@ecX<2qp<;qp@*R5pF$W0VxlkK=?^Z@4(i564yI){x_$ z3s>ueHAx@e5V*6t6RL(}4Ay?7b!@6Jvgyvh^#`L@hc(iVNKK+H(^wqBW%uDdj)len z6`N-3M;Ji7Y>D!^_-2QQc53{EvW)dyUU?wKLJ4%5q|53qUn zmi8tCj;QYz&XxOSuhWO+7V5V}Vkvf8?eMCH-}vRxs}j!-5l-J*6f-P67D%_v-9y6N+GfA~ zC%$R==1i^Ip`>Yc`Vlkw1Iduh7h)BD&1Nk^+? zu(ez?0c}lD(Ez!$=hAhU((x9yHgPc97mDg3Jp)qdeXlecRgTjjPAbL=^I#8Tm`z`J zFjj=NON%_@w%6>>w4>Un+rC7L^i+Zq^&KZsoRaPzx3pt7KRotXH)(SP7YP#qe{$jT zIW>u_FFjWJ^!>6;9m68BMv^v;;<xNJfco9#&WP1)BXDxyhr*A#B{a?>&2J%@i`Z zUSdX)Z)fE}eva%(W=`A;#s9pjH9`7WZ!(LcS|W$dnFb)!GW1HvySFc|xF9d)SmI!3 z%g|di^$GDH_u{U-wp5jRbD9(LWlQ<9<_@3ZvGTTM>;JSE&Drs_+WZhjoN+w@E1p8s zNqs$nuVGD~X7*F6^rt8{LF&xG>&F_A&wWAc!>0#f_gV5nR(sHMrs`$4|7XL<(!=L6 z6N_>H!`hS0Iah75HNfVrdZY7ii6rkLJNx1S=ThT8$CP@PHOOfXqpQu=&pyC^z8Y8cs?|5w*}+^S#;PcJUtHSywde3tF9~F6Y3AOLnEUYzw zO}BkVPQp|MpU=Rh$I5%{b87xs?RbjD0)CB_`T!r##_YJFs zo-XY{jIQE7MrU3v=sURL*O+Z?-`|LU?}rDhB@-WhHJ}oT{5ApXz84tj?=N+dQ=P{E zC>@d5tj`$?K|(9*x;RD;+s&;mb3;`S$#fr&ZT^al?ze=%A7klqId%JktFLLnpY}6* zlg`e>?2M(uH@o_@4zCwcx}S~?0XnD$dHvspLIGah_KuEs!%ekIpO+J;&${+XPa&%& z>CI-3Zou^ZU-RGDwEM&s|tLMtTvtvxZ13%iEs`bD0$!+@fkk&b=3ASQeXGua48pBW9``{S01q%4; z1sSZr;lv69&^RsPImija>m_(>Kdvd*?SW!%QpfqQj3kvcyhNPCx4FH#i`n6_aq9E& zCt6L7_lbOeY6%spD5aXc{|Ej4L{O%IHn+tSmIL)9AG)ff+^=8WY~aV0YajmxgI6Fj zqS$Rz>K-~3HP+^we}h^r#`HCBe)gSAL`epx&H+~9HpfT+Iqk=`#THK$3pO73#~tr+ zrI#(XKi%^mt3I9s^2VAd`C7>!F+GQAm;v&C@MpapHPuCjBF5}Ht%Hh7$$E}rtMC(C z9#;UNtJWS@%Nxsw?Vs_A`rJUavEjUr54(M7Rg;<9x;d7l2QOzx`9E}PjaGj88zlY8 zxASm{>E7VUrIs?{k6k(KwGoW%FCP7{_%oA(*|#th+LF5~X~B4c%bqP|(-S-{gX!K| zZ;q)W$!KQ~-#c~PJD(O*Y;5^GZS4HIYkJGg7Gxu+0nIdxuD`!A?q-$x|0<7;t}I36xQGNN(3~9{6514hwrb&oki#efkcPs zopyzWSKh~g9KOL0*6J7P(B9^f*e|F!MF|l@+#MV-R##6jLnR5vHUrTX&4kppbgVLJ z+=aL?`X$F_#7>gC;B-QlaVfgw23A|uOZ<5$Yu{0A@H7rM*8m=! z5s32XXeatWc5&6fpOwgKY-7hloYFxI zFwS&wwf>fn{m!^xYX7DY^poV^Gh9{JWs{6d$UZ@u{J;Z^61f7^y~>7V(9bZCz=z3$ ztl6@asw@mla74plCKC1%OcSV?6#A!yYfGVojGR|NH!-cX$cRbj@J_z7vdae9S&~sP zX)uivMTkKWz~E5#$+9VidAKQlOTOlVvZWq0a`pTU0#R|LBh2h$;-QV8tS=zNj)lXW zXG7o&W;fvx&7zGu zmO(rg^+SpY*{Be5*>c3y0v`-Vnn?{I8qpn~6*t5X@tc}1ngFv(rUkwuH9t#UhpsoF zJT`#Zkx!ITrOzM9odg_GBv6w(2cY%6-x(NKU0(iQc!o?Ya^-2Yb7UCkH$^Qy&)q5z zmbF4qkVjL`hzE)O%ZPvtDj^G+xx`-P<@DZEm=2>lM|^jFHR%+sNmy6nF_xQd_>lZS z8_MJXV@(8yg0gI45vgoEg`Pi$I0kH5h|%!XL3`pXv}n5^@u{kZIMh;<41`CYBQcif zuoGkNQygRk5IxPl@)|fGZV+2jBpe!$ycAO5W-2=P4VLgz*g}BebqZ)}o=2*PG)rS#W~MQrOoBODV#Umu`2V@Mi_F?YCRj|PM`SE%^5GugR5_jKv%ZTVj59GXgunG#N5k*iuD2Sn2W)DP zy6hZQER0nWEZD?2g^qea4e)jdEl7Ae)QEpi-seHv-nHx|z#k~_AwuW)*cE}UxkGW# z8K78ahztnZf>ngeC4o_eD1TFe#r&^1=s5fbjM77);Z*9L6HaWL(8G$sbvdiEEn(xP zYef<>oy?{E0s|~fR6r4OO(ViU^tW#Wm*0%I6#6oM8+Z1$!Q7jrh4yY@4T*HH0I<0n z`&Y#*Vg^Z5va>LkLJ05|dqz{yDd_mQ4Enc7GV)O$rexqw7Q_p(!$!BWxRYb3q(s!` zuuW_RfJU{{AW2xl16eb*21X7&#FSBufy->lxDx&Li0&k{_GJ}vCEgg|dYQu6Sfsei zd^jDEf%2P1(%V5B5FN~zXgSYfAEe(R#lo9c{qd@C5H;pgv{o178OFfxDRDU*$DTe9p2 zA|#YRmW$}*;z%yu@vDd};Sw7Wk8~grvdN~3qM~H?;5T)mW9Ts|3Z?B7m*uYOIS9@V zliDN-GJ@gLqCyxrkV?>V&TDcOk{Pr(kL!4N_o7-tl+=D>I1SD;^bq!lXKAtfi0}ba zBzQOs1GIL&zm%-x_2fe5+$YPufu#M{Vw-6 zZ$UZuWj2rlfs(V*#HvGhu(IAM+(pUc^wAiS%J2}R(&nku^Ej!!{vcCjFd9Z~sDw8O zs@S^#PhvcYAWBe;UI8!@aYSKhV>4J3zeu#t67*%8ku6k)FG2DiSake$oY1_ zlNy+$rbE8i)Wc$ix7$0T$guE#5z|r7(VA3Ja7p^0YfJtEnlShiu;h7?b|C0jyVc!nzB{e_LGg^4c zqk$F%jkJi3IF=nqCJ;;}oF-&KE1r5of)bf)j4n=ggS*T1U!Uvyxj+&V-Qh=mVe^eB zYzsjpb%0m8&?TbI@{6hTEhA0Wh6g*m!|ytQh`u^{TGlQjyCK$$l4?I?)pgb*773$_ zl0Fj8+l!yYRqCjvHkJuXOmllfC__Vv8***zuBT_&Aq*7J>*~@%PA))@ka!dU1}2&! zKurQvKk%)&T&atDE*qQwk=llL_x1S{td4PL``Lux=g3q z(3#IDP*RXJkEpISd#~)JY>&g~*_8@hP><_<6&@T<7>6dG0VC%Z!tDW9e2V!A2Nbhzh;}Y6e4#xFwV`v!NAe@qDiza=m37^ zgv+k3Z!8F45jUH#ZM??60<0K-YMV0C^T$Sy-E0b(DV38JwLRi| zdmrp}WLLY##gFnFVdjI8B&v6i6Ol^dRKqX;wC5?8JJ{RhS3vNrwvj{l71D38Ya1!cHx8R^o=4mO8v}<>NCNZgzSsdl}j2E zyv^kFb8QcMVNnfw)LCY&{Oqa+5DeI8kG5N^b)@{fL%(rhv7W+B7jqpY)lA{p=f(lf zKeEm%51m>{nEl$q5+r8XxggEJdv*q4okgNqg?fxpG_Nr)s@xr6@#1+mfz7Hn*{7cargYL?G99rNox@zjag?CmNW` z!_!8{@!~v%ye6DCkx6~|g(L$w z8zGjS^bicL{As6Y^1o(g0ys&(lZ`v}Z^VU6euDb2_x^I`s<>qHLWD~Fme_9aOmb8?(v+Qc84 zL`70NcM@78E5V@&Zum=MGD%FCJAE%E!IVo|AIXfS+)F$L*jkKQOeqJ%^bc-LBMUep z-;^X>+P9dh27`o%Lh*VrBpPCmkMRyW+aM9VHdU4ubIupD7!OdvYd|G{h8dONLs8t` zqYLp(Q4o!>C4ptdemVsYwD%j6OAaES=@XAtY)qHP%&H^IGsUz zW^wE)t)AM*jXEwqk482nu>SN@WifHBkxq%hx3At;UW5R82b zOV9-dE^pqpES;{&(G4q?3z)&mJ&70;2n{m?QPE6j1mz{vW!+w7j7Q7iJ@f>2HhiW; zK2EZpeJMN^J{+j9``h12Jy!Q-$<6rCBZ+?@w~2$XMU6@3!6hO{nA0M>xba0JlnHT4 z@>OgCHkkDRWcCJAX?!#i4H>d!J@#@L87~*7Vecqj+7y9cK6Lt^lG!&Dq_AhZtfQ*B zI`lJym7-6u!s#^X$)UTAYmec+0?ow%JM{R_&?bgK9=m1YfpxhWXr>P}0_$}TYf6AW z2dCPmYIUDN^-j}_S6lh}m`L-38Z{34=PL)MDz8cos^M0nI4j{i?+>x3%d=(w zs+u3D+n;REh7c9mS6Sgqp|mfyL0ya!Rn>SslWIof$kENnK^&;2IB;O%=4#t^r>bI* zOR+nG$Y_0;l!DBfPY%9kcX6W$;n)ZRWMw4C!9fzq7d5Gpp1Rik71ICZF+x*nNjK6omo{juCtYW6ddWHLY->Wv*iJ*Hjn2Kq?*XYj9u zpRcz~c|)Ztx|FaFg(@*+K3!z$M3dji)sTaek;saT)agWXPmDPG{-6LMbD?9J=Zf|O z^KpjH^OZ_3v@Xm=3!LFjb3xbcX+~3j?34 zh<q2Z2$L!^;Bq=&r3ZJnb+g}^^L7d?7sf}g60-J9c z^XpeHj2{WGdBwz0B|y~Oz$Fw+SwCc$5D8C!MI}z!(N|6wC7BmR<4lER<{g4Hjb1w? z-6DF_TP(5;6~~<{A{&QCXxYvrW!Bkf>O69Ia5HBnrok319W%ZxG&F7eHYSA1epHla zX;O=4d?k&24X?ipFe_&xoLE!Kq{Y)PbhvVaL>LwnoamZ!Lq=ke0EIzZm{8brgBngo z%W|*OyOUx+{GWbs!Z(z1E*nKw1hyX#1|=ymlK!Xc?{55HCEct-9bS?&c)hQk_2t!acNQElfn0~kO_8RMc%_t!l6vteuIpuEyAEEnNXa2@s>XmueeOd zYngwoV(HJS`9*Jk>l!c}89*2(VNzyyJS;*DXD>Zm*M6js4X=GL=kR~g^bHP~#!K7T zuFbZMr#9QRx!K;@da|Ev*Jj(+X4huhwOL>1eCPcWe)rrnbIn{c*Oa@47QdZW_un9r zr&B$o80sxYUu5(=fab+(0r>?WooS{~GS3;_i|r!>kN zATz*$1`6w|nEvN8D2iD)%|N1!l>W`_y9ua{h~wwYJ7FydJS?a;R&j7F*K@Q@Cc{wR zrd|EpC?Csc=_#eM3RhZ2bD-$!z zRYh0X8WBpKzmbD=BHgTDanOajVMtd^Z6Kj#PY0J2jFf2IzEM-p#-r@@k^7G`$bvuA zW|Udc*;`~3ZR&8JybgDKpp_UI_!5ngDYQTbd++92oJWcR;~M59aqv9-ad53g62eF< zg>~#>`}RzA86c(*$?V%L>u`np_av6gUBJ#o|9XBLaKE@mdqSLRpyD{$ za86h4@w2x-uHv>VzwiAyKGQ}ACOM$%<4}~Na|rdbplYGukzKHj#UTP7TPXVYb!i|d z(nw9CUi$b=L7~^#$9DODe~m%t0gAm z(hYh2ysUorQXr0qAw!Va9jU~dJrrkDz1kK)A|iHLGfIn}gBBEQAFpgU#=?rPRu=_k zinQ4uPz5l_N?PyErgj_aP4?90>bZ1OCN8U4w>lgWHG2$7aRK=Kzqo4%cP1|)gfkXw zc!nB1YXNe9J3Riwym7SdeBa{4MbEwzF|= zU7oOFXDpuBEPp}_Ix0s>+yf^GN=6I)p#ciG%dQu9O2^D6Cm9~?fll83Lz}8%LG#~E z;hKe&`$%mD3R3Sd zTCQ)DI)pW!cM~E6a7fgW8(8Y3avLMTC(lYw>KIE}lZ;Lp$4k*aNXBx_?*=h=3|EhU zYY3>VEUoY2J>CbDfV~-%^>jV$nIyt4EiFy!ae8mlk`X)GJ@KDATevj`^VB$ujuFuP zZVWaye}yS_&J>`avcHCMGtTJr>n()^YeUH0W9n7Oo$I0= zj}+i36EL)qAy69BLjQ{?pYiUxg~Z0N#iNI)c&ZdvUm4JA8b8U1dCKOM7;pxrtilC- zOAb3hhz&1!pj}D^n&|jVff7ek;zcoR!V}iXBb$gMN#jV!4FDS;_l_Z+PJ}J-hSMQ( z6x|d=if4wK1&8LwT{>XJ-_GDOQ{DvGzj{&H>wG)4xr-q(((l+x+FM($$1c2pvFyE3DMm+p zq=S~6HwH!u2jrgx!(BjJjlk) zZb0~zMl6zLy2VmOLZ`{wFobca9A}JX@XDdf=&rgK`7CU1@=O8=o%wH%+=s+g@Nm3t zVYD~>%gajox>wNc9ZxnJm^iHm7uJy&@vWlki4!-GG6Km~MIAlC^VVim zD<={5kB(T>FdniCpCgzE2Pu}02Ew1vO9kn6bb_pG)%N3rl!wiUtUf)DFO6Laz0?h5 z6LE#yuC<%KwY5+XJ)vN}@%&+P`)al86w!ij9!~{nMGT zlhm%l>FC*mK+!MumaX>DxE2P02Zal%sFHE( zG>HmvY*OjUZjGPxU{~L>nbZv>+kTXR70|60>#c$`!Y2Y_A~QqELZ%@sN{i%k9{4>! z)5fA&k`2G`1{kTn38jNrYZY41n}cR|QI5+Q=dRNM@e$0J*obIKH7Z&R68nRwQA61V z)rY`KV~c@N&r24v9}LpgJixnkaJgM_5sQUGGS=WwMWffuCyCU@4>LV?(Qdue}9hQ0&f0=WW zp4w<%B9}GqKd_3_6e)Wi2%TR_nGr{LfINWBqC#Hp4$Lu3d)ZZ6DSgKQwQs*Ea>JO+1)H#X>x zQ_u{-l*o**5Eq~0iiBA)rX3WfwsOBAj8o9nw!j5(rB8Wq*4CuHHd7& z2j-D8)R!`LgMkKaj!XqU_@$e|^Eu1dH8rsLUcII1bFbMoHP=v+6+%vTiDj+A&ZO52 z0gsWO4TmQF+y{(@hR-AQ7Y2isMjMd}r2Vn`hm~};o;zUx&jovGiDO<;y)WN=JD`w@;4`!Q-#)Bi<|CX>d}sK1xw#3J?1sC>gqA*5aV8lON}g zeixpCZ7*ft&i_P=RL6eYPf2+Gn`PQLoEB_QiFl^bda6iztWY2P8Jo>1wwrGRH12Im8+B);UQD3VhyctBx`vK|L6jq$81BIwHQ(i)?QFWp zrl{4x&u?VCv`s!rdY@!H`Khheq4Q= zuXFV9e_VIP`oBKr8Vb~VyjG182(>;u_BJQ2@Yf}bQ|6{hh#DxQXwH$9C>BFh{dS!4AVIK zGO!ATyvJY|t`4YkVzGLt%%AC?WjgqUU+TQ}FLgMUSu9`*9&VZ^2{g=f&sE%d+9i z<}Jc9Rb07lq}!!Tf@RK#;rG)lRi;$y!WhUrq$ypoH3j&WAh)-%2R~)$rZQhxl$I7!%@= z5`kU+_E%^W1${quV?J+sKIX%ws)_MC-xda@|JqP4gg1=g=c&Uvtnwk_6q;|IG{$NX z*b@TB^KNRAMLC6u?aWTCGdykq4=MNO6gYlA4}yQ5ryD)L$@-@+Xbjdm;$aIiH7e6h zb){(HGn8+?#Yv#2o@rG)Rk{4E-elIvp&b0X(cU;{`b$p3>kN61OtDGpt~~9p>1C#k zAU^!A8}bYrQj)umoK&+SYcdSLY<;J(1e-WN;I4q1T_jXheSQR$$neKaF!p@RZzl<7 z>(|=kFbP6lQo%miR+efAF$?yv%N|(p@dqw3FLxr(u843m}c~G<$H4~paDT|QuKGQ-p_jn&Ce4mZv6;E z2Y<2p9PVfsbx_m1yIH`}u!_EhYAOAOJuW?3-Fa86tSYIJ;hu^j3OyJrC!lopOxw&>pifw)?ov{v}IUk*?bknB8jCcQV{mRElLAc+(T@x4H1oy13ATl z_LBzd{ccXGj!67fer_E*kKgs1r6;RZ?%a1i=JAmU4%NQM>3mYy5uhDExQ-y}`!-{e^#` zDN`3C3I-r5Q+cQUf|lXJPv;@k@E(tMfvd*L91^)l8I|hV2fj>MODrE4JeO5W=CQT9nW92ey4-w%${GfLGzMHF}9u4d}sS!S9=vl%MC@8 zQ2p6XNUic>*;>q_gvJGIMclwjnQbud984wW?y6z)gff99M))r!G4HIuGgtfB4y(~W znj=?7Dq^@%dM$9HC`dWE0i@`>+yo|VnI_R_mS1;?go#DzY>3-yVPMvGv_0gck@<%Q zgFK@@?^e?{VGx_>LfzYH&N7yD)Ogno91skUqi(u>a>KWyEJ39Y1|=U%PR3MWp5)1S zV_BwGpL|TYu^#{X8E=1heHmTX<>M*kd3nCRvAMRg)%}W-cZlL>-}N*%9(g*N9oCmxMig!5C#b(OgBGnm4HGC!rm}eNX7++`x}hphmtrb% z{oX#B#&MWCA73`2t_*&DUWDbmK%6mF0Ln8~8q+DuEfI{I*zZ6tgds9r4NXn)qZ}lz zYn*p^B8){@gGnyT1X2W%Fg;D+*K8FstNC_T(#Z$TEtz=pNq4-8zieCnlSD{q#S8|{ z<6f(KIU~_2;X%Ceu&(KtH&9Ls@9|{c=(zG2;R6Xo;38hpi znTIu4lphh~)aR4YOZ#5}=_{@+)+dCwk9HN0&yKmH0SDZ!g=Z`95~a`kOK zo(CC}{4IbZPv((EXBUOD6B1;CI0%75H)7G&)ADO1{!U+f!|-aQB=>Ez=KW=|BGv!l zFf%vX=WME~V!G$;w1LI1x}|&J#I3wz{-&SQN*2_9H8J)D2sH5{ow;MAD|G~qJ7p0gw+nv>?3u*WW$6-z zZ+P{YQd@6B(aL0qi{>dnp@A_6L%@-b{obAHB-*Xj?r0>JUxXKtr_W% z5b`CW@>y_fb$Gk-4K5%xA-8Z2c-tb1&4kcc83Wv6m@$L_5e_%V&C&?ll-CdrH%eM4 zk4CRi{;wxKK_fYQuh~~0W3N|!UYF}3E&fkO=!-1xa|||d3LN)4ZlA}ib1HIfX{(AW zMv?Hwiq<>6q9(*RY7$M5DTA4d_mpqGkG@FQDh+l<3V^fcPqcbbB zSb!6hP366+1(s*2tzHdp|h9rcg~2Sb*1hw#Y;;Xf#?9H#2dph;Z8yiAr_G${ec=R<~?8`bam6@^&kd z8tzpur=*+XX_oYYB?zEZvg9yK)=ebW$JYb5QyEQ{7RjZJ!7~DT<5GOA>zGaso%jhl zMze|ZF16L_wsG#}!c{wMB4=aBus8Y8==0RKk5DWLR=~n2ByMXr>*R4j+VV5djOg%{ zZk+Hj25_r@8D5Qf&fa{qmF;~j6`6kc#E$Pi0~;i{f_|nJwQgodmnFG=?LuXWLia}4=$BA1K^t;a3 zT?6@X#D_=n-b(8>(#u#PO&Qu{w-O#?E}URz;G^a;Wwvq~QC% zJ;j>ki^IG2j0-H79xtOyF8DIgwBXAjV^MifuGLG6{D)-?KuW<2cd!Ow zY$|X0GKW*Vb?DwG;pZRa&seP~aRt9RSFM5w^9&`?F}S7%_)-&mPK$tCNKlYm=xBsQ zcIyhA4c)V~Zxqx(aP+LowG`dn-Y1<)qj1!GY79m@ye!j&JJYc9-%3me z4~u@g+r=SMp$HH9q0LxCxb*x4t(H?$^{fvMvpY|H>+*)i;(#riaFIi}I^bb&M@WS= z#w5!dk#uiQF~?&r^qDrnNz`DPF6Fs?TbPy2z?Q}rqoiPC%%LzQC@)%>QIX;Zm_I|Q z7QA$PwP9r$lz>jtSsmG!xIZ2=x=CD1@RS~rMCPtg?l6~ZM&!n1HdT28@fY62>Lu9d zYa6t%=lV9)?>=)&u)Z_Cj1tXgm2WH|no8INsB6qXq04{$ni1hm$_AAODXqe&QNZ^b zl775a?0j}URxxU2Xgqc6>G}JS;PdfPRVLPWyg(vSlwTH3u$*EH(ME@d#X&v?pYDz` zVX@kJ7YJY_teD2#Tbs4b&IuZL_JKFnKw9n(s+QeSUx)N_XS}b5XazqGJgb0r%&q<} z0A;ndz;8W+G6lAY*OH3Gd~75XL>LNB%vx;V{o6IvjF#+|*(R(tZfe3CpRRWFV}F~O zMe69N0{~dXfJlAuODB&02VW8&%O9I_x9oKeb@mf{1+gnAUUUNj7J)04p&j3&cGA)^ z`!*b(ki*F*a8>w`{KUZB%z3(vR`C=O*wl@f*4}>^VLG{xp9XLDemaF*dp(oGK27n!4fMRC7rI{h=a{ z41R_7t{t=;?El#d;AmhaZa$~~hqfHQakoevq7xVwfa(X*>#45(A^6vq4mA?jAij5Q zN|khxg9c{Hdq;(bpbbn;XSY-~lpn@zDz77Jq^&}ru2&Uzh+YU#MVi9`2K|`TPyVs7 z$Y^|oGjsb1>q0^)6umtG8A)3Ts&e?cZNBw((Q~I4)OZ!GmjyAskDjsa^{QAW1R(+) z7_|u106eq49YD8E!sDmF)^a(R` zI}jO?cm$^wSkymfhN&Tc;Ht#`x^EWiZGY86tY`L)lr>MW|3JD+o7 z_DVg{>CIQpC@7oMXJ6+@#2`hj9;ac$p6RvdzaJAv7{&R!C`n+?-)eemb&iF znJeyXE>@ee*X>3LK@q41jWuZd#4={Of<84-nG-2~-Kz!vs?`0S%);*+n1)A#9WIBK zK+nYx<*mbLj@B*-sLT)fGz*&R@$vjAL=kk7`U+ke$mI&dOt$W5o#zGi9@45?N(+R> z2C@bqVWMXHdAYmCFiCckQo}opuiPow5$UNF|FyK*m)a=+PV|=T$R(B12H@!8<9}z^ z&i1uZhq$(gu}vbU@Be8uaqHBpDX%!&Y*_qNyaclM3Ob#4Ra8~kelL=>%!bpBUdo@f zT195Lu7+<$=Tx@<&;8WliLl+6EhAjL-3dPk_tJ zE$Gjv_q{G=q|KZpP?r6>9+Hafyd5kg9=9YyvOG3F2%4&Bt;WOg zlqD4}KhCezSGFwubX~g`51*IWrc~?*EE~pmfYz7*Kmx(HnDp(Q-hZ=fOK7{HkdC#2 znZn!J_Xjoy*FGfz0T56SngRO|5vorTcZmn^)7eGI6&6VHQG5g6$Db2XndV>U(XvBp zoU(@+@V0Xj;~@xli%NWwj+KvcB%A1KDQUqxZ&W3wmO*+6beC#tY0{V%5zS)g!xwvB z&an^1teN(yOm|VAghmS6T*ehu4!{gXRFlmz5hbFCa!CSaN^5A)kV9hR84O92C4lbZ zDISKa^u(R^*}yk2Uf#ivAbpJS24RFtUz^MBM454uMkaP zr-KxSWq5&5CR#9ca!+BZ9IG2+nUPY;+0M15 zmL6Me$iL%YWI|!nFHtoSiHlA`*o4#8NOFUFE4Wo3cumQ}frR|s?-BHHWAonz;vZ~M z?E9=CUK&Q3`r)P3REstm@`OjtQ(7zzOzeh=01~HZQ$i%*XB7G2dD2{jJhvDl!oQF} z99`kxVIV=bw?CtJOXp|7mND=H8{dV+__7u8i|{;{s0fK@YI(u52Y(q&Y}~NMB=V25 z>d2R>N3xk-Lj;(abi;HfN1NpnCQHk3e(!QWO+GSu{y^A`6JH!Ku)QET znr7S;h3tFyC!BRsJoZH!Ua4(JKW5j#8D1r!f9+(LU9J>%B3-4~%90$^LOU->04stg zpV1G|)S4f3U>^uimVF>!TU=(YE?MTpSv8ix$D&-jEf*e4bVY`?Uz9P3(qrx z$j1VRmCf&>>TKAaq1@fT(dl&3pd=^|+lGxZM`<|RMiWF47Hj9=FsyptZm>;%SO0WA zcHmdDeB#!TO?a$Gnap+=6h&g#;r)v{Qx*k7ibz*42vX~H96d&>gTOf_OTe95?Rf%! zef)4P(XN`}8)G|`>k}$-KBX@RD^hNkGKG-cL4IgQ5k~=8C1)1Q^Fq1g8R2gIn!vUc zO*^x66+7q)pGg}I?={EfvAG`?i8{TeNTaji1w7D2#Utn>QEz@Xz!qk8N~K{9H3thv zQikNoMRknv!0&c>h___f_%#ql9#LqRv8;g?-0i(LrL^_a)yH2;at<7{h%dsF*CdY7 zcRB?d)F)OlO{v0@<_9Z7)~N{NeYiUWj~>0KD^KVXPz z@+5;e6|W@%H|E3@vx4VA(NZiUr3WAV=5_Wq^JPKdbfctpUhv$tKb&BSNC)KDlopkB zCWgrkq^%R=oNo?pq{aE#)y3lS0fOP9of#Y5TH(IW<3>-1BdJ%uF82nDMn77AOqw_Q z-1K_`GyC#jOF~;1=&U0X#I5vrs>XMG+j)pKR(fC&5EQC~b@IKFb0&W*dE?B4Cgz7x zi)F%vGARbs`@9Zp%nH7}BwKd(!jt@a8J8Q+-RPoHe@p&SQMo>FP2Kdl6>ljdq;gf( zi3V+RD%N18I!iP%RPD(YI~^U*j{d&?YqQgIsI9J6_@D~LUuV)AT^XMEAFo5c-EQg$ z9AzAyC12tgF_FOtTWm?u<(%5*72zp?cTS{r=T{Sybt1txqy-}X7JZU_YG-aL{V~2DV8*3jjDx# zhGnPD=6c=583VRlT5-j>q7DXxgJ!Y-R}Zi6iidU{%0h@<>^^ZXt23K-H8ic29P1>*(j5$DW0X$L0{73`DK7?Om52AEDOVYHVIiB zDG5lDqW^|_R1mu`hB|%)q2OEu%%y3m@F(P@RaK0b6kkdN@KUL7SzUJpeYBtOhshL? zN`lAyK~c{2;KtfkVHRBum2*x}I*Ny8cAui5FkGy#EQJ(c4l>4+nt~);C_^ zST^0|;@J(__qij%&lr}s+rkoJj41Z4kY%r9a~;PrA(rt}Bky}xmd^DBU0XGt$yMWv z<3ntH2HG+}B)8^r!2Q3UI-5hF2@V>R1B2F8y!g;s>bQya;5%VnX{wqzhq;q$&VCTB z6n`n@SBkOHm9Yq7LZL5azmbvJ|3!wek@nx%`6UVymGNsBn2)y8$TdYkB0rzQXsV5Y;UL}HY~MbH()RM*foXT(=umpme%_FVK;C)xO$ z)&A`8vE<8+E><&Lcd7ZD5wkSSFWz%LjaClid$~TDXA$@`6&epWC-Hp~;c@_^OnWhh zL??=cq1f9Kb$I%`KE<15HTd;-KIBVH<@kBodmnUvdbO;DeChqR;pFnYCS^=1=E(eB zZ}{V1TY)e|A`_A`Kz7X;)j&)&hBs2VSUiZH0a3D|lBXoEg37Z@gXi=cL>WPZa&JEO zzqUQ(m;?{XySeHRg%(f9o$mG$yUqj$>r(x;8b%rgXf6W^*-nHqft#=~8j%p}=#L~H zvxv?<$uEA+WIQ)m^jLUT+aP(We}g-PBe8^C?ynE#f?P{k{-63nXK>7?-gR~D!y$P~ zLLW0Li<_$C3wxGRIRd{t{$1+DL&;*LOPI^t?o4mt$b+@I-CY{b_2lqe90t(-vS@|M)vv|3BOq8Ym2h8m}o5xSJ zu$%U}?TkrJ>o`kPlNfve>U26=YJ1!~8+;x$qk-0sHO))@U7#wtqPr^hT|xsSxmQ#v zl%W*)>|5*39=SK1!6*xIAS^f@+ujy1^!{+&dv2Ul_?rFhaA<+;mu2m)Z*+M(URv5Q zlgWBW&{xg+S)bNqtVkl{e)>1!ar5mtQK}_Jz;@ni_tbPJEksO{P%*ZV5tP`789YPU zfqy~3RBAZ}DH|%W#Dms5oHYurhR1N|;QzaXstf^G|KG^t0xa(gDGVG)5s#Gv$yW1g zE}021;{bBtHQ7zZyod0qq-6`n)Ge?U*)fu<$9G0o0FJs&)8>;v|udM z8kHblM5i@oT~g7{*_4pr3_)rQuO~kqI(}YC3$Cg*IdZuP%GMF7(+(|m{x3HnqWq&S z1d?<* zvQpq4Kn@I1eMa4NM=4A}j0|28Mi2)9D_LaxdqEwnN}&oBv=bcF47^tp8u@5|17kLT z+MQz@(*(JXcR2?iQFssMhiAa1XRMC)k#iqi%Aad%E|#VteU^fFUg_izB}&@LY~?J&^`Jv+b~=epsJ<7 zRRN~7rwzPp5S}UR$A-jnjn5l0RN=g9t1MQ@s#k|biv_dcx^KV#4_O`Lgl7oN-N?=i}kA!u{d04bGgces>tUW?GUznMuGr1am4*6QS;u4cWGql!!& zpvwSOtUyFNr<5h!(5Y@K8jzk=Ah;sfCGJ(L>V^Z4B1fGQ$79q56BX`HNP^glgIA zcZei{5D1EWi?*vt#nrP&XmAQpJR2sIE!5@3L!A%mI5Jjk@?RVYn1y&{f=Gd{y#f3# zOiA`NQdJ?gt3KOZUmZC3Anei?-83&)t;*d1E?;J$o6{kmGEs*B_LKSV%tzN)ru zCpSBTgO4XS2{X@KKqux*4)x&;kcM}rt{jh7=wKooPKwm4 zBE|r%n0C91ldH=4Z>DObcmhqtoLqa}oet5MWZnUO#cin*6K|^E zs+@%oybJKuCdFsoJ^xs@%fqbA;yQHmE)2k*!IQe5r$I3;W-yPpoVRu^!qRI1b3$KIc8HiUsji>3^Nl%XHzx~kuMSL?p3%_OJl2Pl z3Sv+CTL$)Tj7L{XG!P+4zBvB8BT#Wf!2rUyOq;J5Hzf7uf5SX5QrQ8r{qLmM&)NY$ zt%QxB!#-o0U3*@(-_Lmgo%q6+c)6EmL;9p(Dp z52Y3WOrh*Osib+U*nFb16@a|0sa4=lY1aky|8`$quK%)wQPb8lN8Jr2<2y#jVO!eh z$?rl8gXh47z#W{*LdE>>laVh3F`IYU%ZS9x&<_Quql4UUKwLR3-Txu4(1s}0@gGgB z@zuPyNUbB_VcU(t9YP})lH9|?sE8o{q6Mscv&9sN$m_39Z}4%VErC=@U_{ULFLt$0 z?S7cz40oTAl?{@tmyIA@7xm9?YV9Sn6IpgI$xKM|eX9{_Z}Loxd44e0lCXK*L~*G6 zj%sJciVN037X{Hfgp24KipX5lTSZNRzl;k^K*Q5|fW2QSWOQx{Z`ZH%Iv>S{y`a)( z)0f)Iq6QWKVl#ECGIg~86QGj3KS(?CCT2g}?bK7B<&U@+I%8d4W#*0f?yPu z8_Lw>gns&L22(+w|IwvMn4QPtv|KOR zz09h#j0-Kk07ZYX9vckdr^@k_sCLqBp1tMy$oy=_mEY5lq#`X-o}w!5Kd%LT z&hrAJ9qkL_SMK6^V#TR!jo2TCSJer>xtOU4!MDtfnN!6@q zFvrufF`=LjElkUlX4UJmPcCEDcs9LWEtehiMO>Be&9O|*c={j= z5v+^}+k{xK^-3vyyZp|EH?p%Ig+7k|4#!*O`tBSb?);^aL9$`=Qf0P#4_-n>0sb3Q zx6nqi8PHV9cOphGCV0`&2E!xU$suQkhCCRN*Ipo0oeu`v{p0$BHV;Xb^8hC~IEm@h zMIB6Y;s2@-+xa*M!BgH?@*I~eT6Z1`4_FWwXSlHh zM;swQOAmb(j0H~#5m_7B%L1RyWaUFEa-0yM^b?f!`ea8)M|KNjPm(XLEXdpjP zP*W!5$7>)_P#uqa=|IkfyMEWgG(luoD3h z4x8h5cAD6$x{WJhJrNnvY7$NhJ7z|Se)p9Z3`x2K2& zh-)dqD z-MCTk9j;v*0#XH1JXt_qe?)7(&KJ8AS)3IG-WHh00OcxPkPJWuvS5KE{(<`yCSe&& z1r_`%BTDrCPdta=?L`XuyGC5;16z>}2_~Io3ZYH~b<$aL6#6C2G5yFd+fgR(Hqf*L zI6;>(uvO+l(ujqRqPA4bFsym)ms9d{xzAP->M#xpHma9c=0;zq_yNWTPe|N*TuBcu zo8!AXnrifuPIY#(YoomUMGmrT-{}3`=$FR{d3Rd9G*zoq6WVvqg2W#WdoBLAD@At< z36MKYWZ^#_2b`a(;3OH zr&&98M>he6qm;kWbgj(x8}}Dy%UAkURZ4SDsfNE^ilzlj@9nF>#&FAt>~0$e_4*0( zPzoV#5E8qI^$GwF7S@*FW&+aG=Tfm$N@hzthPy~|Z(3-ZNfumX4_9SwfBzFiL{Q@1 zn?R{q=HLK$IOIOS(n&$bL_rxV0$BnjIBk3|dPP%}K+I)_>f*5WggKbewLJcTDl^|P zYf;I>WA2x}?vY_H9(?V26_;&=Ezl@&^f%+UB8~ssO@mY{F+(JIOyP)%T&0wQF-+4z`5OJbp~-3jH3 z5rz%jsZItwZYr5|J5zuvxS9|%V}{U;Y?stBfjIGCp?CmsG%M3k;6F{=#+Lo%iqd{~fw$X=W~4%7MO2i`5Qy4oXMJQp315BV@XS07HGygoN863x^#h z-ROgk?q+d;XJpS~d6FdNpV172(r}A$QA~@b3 zXzhd51fDktwoB%2X(ML4(k8OHjVCY2;2qPaikh7N%9< zPEPi{xBRJ|-wDnL=3QW3j^|f~?vAEutY2|=TuvIIS{$~{-Cr3PDzfUz?F@Y`Mx;Rc;HJ(8w~N!vzfvr$)p*t(o2B+lHoPhj z9iNv@s-%bo)wN=x&{*(BS#dD24r`oo=il2@5zpKjJA>A&ffGPu(dT_L(Mr^&#|*eI z?tUZ(YEu9^VHsh*a31zSnElrh1-O2tZ#WPfx4^x3mB$X!MdUliOmHNVJ}VJ2qR}-P z(xoYjmE6;30^J{RT;uo|nAeh+JDDW@+hZ77(6euQ$9ITI@HV%L)5Y;rW(gIy*N2PP zY5(Z;FjcyPX}^aCfDCz2=m5HM+IVU;Ls>MJ1l#9%gB&7AJi3oJeu>$|LprQtZR^98x&}WasD;MQi*7o1{T;aIy+nd zl}%r(jaD*vO-gwmiL12gF#5$I#hID{$);S6iYyl9CB_SkD9x{~lnajl!l;!}K@dMw z8qct0Avoa_wGs6D>v`JYQzQdrsRG_vhqacMUb?~pl%1wn^q(57PgmTUTUuZX5aST{ zl?t6-R@F4T&TPn8{QuZW|qHnhH3`K_)NjK+jT5mT`@P|K)-f|aI}^+8^Jv)C#&+_z-~_2p+InV4*u+cU+Pn+3 zjSMa*6@3`69RNvEP-M*)tX5wRbzosf`t1&Wk2IMdyZ33xLB98=w$w9C%jCuP1F^6> zOor%_gl$I5Hd-&SD4dfkoD~=|0+4;!+zNjyt~O-pHv_3`MQt5}sX5D~CCyZr@#SiL zNUp~2I{3l;^$`+-9_ROKlc!Axvz3jFwGD!rYR37Y6b@w^Qh<`+hj~)utU1!ZgGDVv z@BsIV)%*MVn1T%XVjl^}nkZ;RLl+TRA)KaadR3|%NfFLKD+kQRvT#mEsAJ*&H0XFr z0%OBUvf1d4qy&9NiO=)g&ugWR{f85dk&nGCzx(G&jSczoMiXXHYMQnG+D_UK<}nXG zW)>bN8M3bi&@;R0;CU}~weYz@^0mp5OlY+CIpF_#5Egq5Bj6%97r;dvMo*^*sKI3r zHh^Mj%(TubwGWOAp3~=+7uPP>t-aTw|M@m(B7400BAHP%Uh)3jQ%T@?A5$kM(5=0r zivu5oLc)tQF+|{bG-dB~uvEvimzmk(05p#@)#0K#>UKD^dIPrUz#zeuNU>RpiDV_) zIfxy^hgeWjlGC0N3ZsJboT4 zeOy2G+|R`Sb?KcXzt#t{3urlIUIN(2u2e>iY03JCEK|tu*BnW@#U6(x+#>qy9G9P9jpyaUeWzIyJ9Zj6 zCc9$2yaal)scS#hWjd_s9lwE|9*BGho#r@iO-~1(Qr1Ey;fKuT=q}^%QYo-%j(C0y znUIPi-~t2~1{O9p5L-&2R}@GdI58oBO&$1d-jKPXTa`9?bej9g@~;QjNCfpPak?1P14~L?+YdjB7mP6Swryu( zJ2|oKWWtGU8z**7jEQYyf{ATRY)?-FvUqKP|`?S-Q1_6(DcU zM2%6e*Y#WKYF9p(@McPnm_l?Vqqb48(LWr zJhB;C?&KLMK%AkeKFA1t`)A@`3hz?o5RN+=xktff-E3X{hw9%i;{_mD-Ya7Nm(x=2 z!H=iMfXDW~cJ(QhImO3U?=R`Od=z7?IRvK-9bl?m{F=N4K&z zB(PcnvPoYXwc1oFnKo+oY3;ygGop}|g&`(mWgkpJ^)kXoG({*bgoMGY~V?SQyhe2z|5 z8xc5*Bt`W~V6*;z(yBnV*2m1eJmxt|R_?x)ZAVy2RCuKk^{bZ@LHCS~8JYRF0fOg6 zqP>cp()7xY)31ik4ev__Y3O+s+kHPkuUF|G*37@K4F_#i?p!LB)h+NBDS8kCoi6vMql)ANv+ZHRJCu=Gt5)4(He;_ z{4|J%*Op}AF*&~nX2>RIz}TFE=%{b4J6MjIWTiuH8$=C;WRjd}q)FdDNags&9Kk?5 zKz*X;OlT|Iqg*PS+SH&)*e)`a@b+J}9kCy8^UU_SeBKVuM}HpA=JQ^6BMD!A_dboU zPG%YTe}G8dhVpW}kE5cm^xyK_J$i2#jMUy1JpHSA^s9t#kb1j?z4k&@S9A(fPfr|6 z8P`hxa|R`)@36`(TXme@@82y&iAyOOw0nNMr9NL%L`WC(JWNE#3%s3Yk>m!PAJCKp z@M>;WN7C{o2|4e!HN@^Fr&76pyo6z)U~N>otE{ds;UMo;Ce|S5wc!Aojt-} z8ze%blwiPkRT~+aoKFZ_^o!yTR{HMYLyil7`ksG-^Z9Y9*3{qky9X?Lv!42pUY%Df)H1?I^xRI z*3Gy5XQ}Dj&trI&6qCbj6&*~q!!k>rR5ww-98Wqzh?IOGR6=eALJW=;Ml^uRQ$aLO zDd`M2-I%rEVj!Ku-qC@r;c2m`uu`KvGXy3Y{a9m0J3fzMuJnvs2^(cm9AGnC1fK^> zi<&@Nj}FyZ7d^3VQaq&jO9SL;S#>#esaUB(6Km*yT|e5qWAyp&{>uL zr013<$3C1&k+|)BWS&%JjeooXrr55UmwG9+hHF$3|d@Tv)>$TMEr&78$YGe2)E`G{sTYj zC$D`F2L33mT%(Az23HIamZhprlT(xL!WCPpQf3*ypjzscNuhGbR&PG%qOQ-f1UASKsv31`8Wf-JS@``#dMa?I zZ%r%2zSJ83J7hv3W!x;e+%AcT*&HSGJ}^|a$diq*AQdT92HoqFp;l%F!GRv;-+UJ5 zgMD`j*cWV2R^#VscRw_I@Ur$$h1ct%aKC`W-h*Dg4WUCQY71ghW0X7WeQm&GZW zXLoXGih%>`4|18Z-bJ>iyqQc1s=Z?d2H#ycDjif)Y1Yp_9i$Y6krEM%bb(sZpt3>e z+U=V*02n*pB-@Npb89BwQ2o>&uN-#W^G$wwWCzW}O#+CDMB{rL;iuWZ;e&4Xu^2Q` z1KlNSUXP{1DU#EYVHDv{jwUW=m>nYOD!U_va;iUEpjiK)$?MC_dr~`!_xw){0Y*!q zQ_5hXJw(4Kij(}j8qu?$cK6cEd)*-|*2PG7|E3<0eTv`_juQ<^Jiq++K=OtY@DJs4 zCx8M*mbUyVRN!bB#g3RS)8p0P??&VC9h}L)PJUpR6B14p+nU$hg*z+7ZWVW&S}2AI z9BoyYd_8HKNNTYTy`v&HD^eLDad}wI$#K`^19Ot#<0 zbN?i>_$D(9OBCWG)kdPsic)^YmsZ9jpkaM7`&@mi(b6bEx@um!bP(=dUPv~S5rYqn zE1-49t&h1NIl9?<%~8sk1vwn5{*;s;!b4aRRmW8KK9+$cBO~j6ocHlLtEqgmxp<_6 zgiJ{;6K-&5+ZH@JZ}^g0cRaoeoY57M*vYC1)EE&qr)Wqh7nck&(A%g|$?PL`TFGfL zl6V*5adY6_N)TYhV^D0P!#hGKhwtoRkq_?cNTv*gsIx{%A#l#CM(3K-Qjx{@CX%Jz!H2k@J$|(Prk~)R_RCHiI`I8BtlLP7#|N5INcy1AI#PrLwK2 zHUz7v$J6K|<>S+#Rw?@44SJaR?NzCjC&0z%GZItgt=>N)4o{ube-Nszj*cbBx_^ik zwlRe&NY=ieU|`9R7Hlj)P^2GisZL1~#L#xsg4qI72?L)KgAU=72mmD2_# zr{k#zgq`8y{1RQ#k|alK>@gdgs0i0o{@0ec#FwsU=H>#iL;Up7iNk&L^P zqCLY!z&fTA9vZI|iF&k?u42w^O^zwit&Mk`R;%s!tNQTYtZCIUoyM47dNT=0)12}x z(qtK}g65t1>x;KynmS%0yrqm)KG={JmeL_)FlL3!L<>bGEf?QaG%x z>MK@Bs#RE%)66-w!yUlW)G2d>|5l*>3kl}z{{?k_Ltn-gqR24*1*XEf;jBZ9cuoLL z!^(m1%$E&J9afcLC!U2R+6)lc%A#JCUfq3G&@z;oICk8MWY5+})L&mnkxg}ZDe{t1 z+mpjFx;ejHCw{qTOxIubmADYVbtEg58m9W0#SjXM)-Yj4nq7-3VUl>dsP@yq#p#c8 z$+WHScEPa8B-Nyxp46*PtXULDmA!3-lM6Qrf7RFc<&Ca|ObNXW_~PeB>5 z@FZNjo{MvF{{?actb;hMt(c0Cr4L0{>>A<;6Fokp!>S+JIZ2E5T:o^BDRnp;no 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ï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 diff --git a/docs/index.rst b/docs/index.rst index 1270a643..6ecef3ae 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -14,58 +14,59 @@ Release v\ |release| (:ref:`Installation `) What it can do -------------- -.. |img| image:: /_static/img/example-docx-01.png +.. |img| image:: /_static/img/example-docx-01.png Here's an example of what |docx| can do: -============================================ =============================================================== -|img| :: +:: - from docx import Document - from docx.shared import Inches + from docx import Document + from docx.shared import Inches - document = Document() + document = Document() - document.add_heading('Document Title', 0) + document.add_heading('Document Title', 0) - p = document.add_paragraph('A plain paragraph having some ') - p.add_run('bold').bold = True - p.add_run(' and some ') - p.add_run('italic.').italic = True + p = document.add_paragraph('A plain paragraph having some ') + p.add_run('bold').bold = True + p.add_run(' and some ') + p.add_run('italic.').italic = True - document.add_heading('Heading, level 1', level=1) - document.add_paragraph('Intense quote', style='Intense Quote') + document.add_heading('Heading, level 1', level=1) + document.add_paragraph('Intense quote', style='Intense Quote') - document.add_paragraph( - 'first item in unordered list', style='List Bullet' - ) - document.add_paragraph( - 'first item in ordered list', style='List Number' - ) + document.add_paragraph( + 'first item in unordered list', style='List Bullet' + ) + document.add_paragraph( + 'first item in ordered list', style='List Number' + ) - document.add_picture('monty-truth.png', width=Inches(1.25)) + document.add_picture('monty-truth.png', width=Inches(1.25)) - records = ( - (3, '101', 'Spam'), - (7, '422', 'Eggs'), - (4, '631', 'Spam, spam, eggs, and spam') - ) + records = ( + (3, '101', 'Spam'), + (7, '422', 'Eggs'), + (4, '631', 'Spam, spam, eggs, and spam') + ) - table = document.add_table(rows=1, cols=3) - hdr_cells = table.rows[0].cells - hdr_cells[0].text = 'Qty' - hdr_cells[1].text = 'Id' - hdr_cells[2].text = 'Desc' - for qty, id, desc in records: - row_cells = table.add_row().cells - row_cells[0].text = str(qty) - row_cells[1].text = id - row_cells[2].text = desc + table = document.add_table(rows=1, cols=3) + hdr_cells = table.rows[0].cells + hdr_cells[0].text = 'Qty' + hdr_cells[1].text = 'Id' + hdr_cells[2].text = 'Desc' + for qty, id, desc in records: + row_cells = table.add_row().cells + row_cells[0].text = str(qty) + row_cells[1].text = id + row_cells[2].text = desc - document.add_page_break() + document.add_page_break() - document.save('demo.docx') -============================================ =============================================================== + document.save('demo.docx') + + +|img| User Guide diff --git a/docs/user/shapes.rst b/docs/user/shapes.rst index ec5d2279..ba592a42 100644 --- a/docs/user/shapes.rst +++ b/docs/user/shapes.rst @@ -19,9 +19,10 @@ will cause it to move to the right. Often, a picture is placed in a paragraph by itself, but this is not required. It can have text before and after it in the paragraph in which it's placed. -At the time of writing, |docx| only supports inline pictures. Floating pictures -can be added. If you have an active use case, submit a feature request on the -issue tracker. The ``Document.add_picture()`` method adds a specified picture +The ``Document.add_picture()`` method adds a specified picture to the end of the document in a paragraph of its own. However, by digging a little deeper into the API you can place text on either side of the picture in its paragraph, or both. + +If width and height are not specified in svg, the default size is *72px*. +The ratio of width and height is kept the same as viewbox attribute. diff --git a/docx/__init__.py b/docx/__init__.py index 189315c4..0c147d20 100644 --- a/docx/__init__.py +++ b/docx/__init__.py @@ -1,10 +1,4 @@ -from docx.api import Document # noqa - -__version__ = "0.0.8" - - -# register custom Part classes with opc package reader - +from docx.api import Document from docx.opc.constants import CONTENT_TYPE as CT from docx.opc.constants import RELATIONSHIP_TYPE as RT from docx.opc.part import PartFactory @@ -16,7 +10,12 @@ from docx.parts.image import ImagePart from docx.parts.numbering import NumberingPart from docx.parts.settings import SettingsPart -from docx.parts.styles import StylesPart +from docx.parts.styles import StylesPart # noqa + +__version__ = "0.0.9" + + +# register custom Part classes with opc package reader def part_class_selector(content_type, reltype): From fc5ed80737542afd073dc0e8f4276f1f7f96d732 Mon Sep 17 00:00:00 2001 From: Ethan Date: Tue, 26 Nov 2024 10:25:32 +0800 Subject: [PATCH 071/115] update docs --- docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index 6ecef3ae..8382d0a9 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -42,7 +42,7 @@ Here's an example of what |docx| can do: 'first item in ordered list', style='List Number' ) - document.add_picture('monty-truth.png', width=Inches(1.25)) + document.add_picture('500miles.png', width=Inches(5.9)) records = ( (3, '101', 'Spam'), From 8e566e7e6bb2b0a8c2ff8885ee00163ac1840737 Mon Sep 17 00:00:00 2001 From: Stephen Reindl <4533301+steven-r@users.noreply.github.com> Date: Thu, 6 Nov 2025 03:34:12 +0100 Subject: [PATCH 072/115] Fix modern bool representations in .docx files (#29) * fix: fix font checks as for recent values the font name is not a string but a dict * fix: allow bool properties (both recent and legacy) to be read from custom properties fixes bool custom properties are translated to `False` in any case Fixes #28 --- docx/opc/customprops.py | 6 +++--- features/doc-customprops.feature | 6 ++++++ features/steps/customprops.py | 7 +++++-- features/steps/font.py | 7 ++++++- .../test_files/doc-customprops-legacy.docx | Bin 0 -> 7922 bytes .../steps/test_files/doc-customprops.docx | Bin 7922 -> 13400 bytes 6 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 features/steps/test_files/doc-customprops-legacy.docx diff --git a/docx/opc/customprops.py b/docx/opc/customprops.py index 8b1c6fe4..be2e61ec 100644 --- a/docx/opc/customprops.py +++ b/docx/opc/customprops.py @@ -24,7 +24,7 @@ def __getitem__(self, item): except ValueError: return elm.text elif elm.tag == "{%s}bool" % NS_VT: - return elm.text == "1" + return elm.text.lower() in ["1", "true"] return elm.text def __setitem__(self, key, value): @@ -33,7 +33,7 @@ def __setitem__(self, key, value): elmType = "lpwstr" if isinstance(value, bool): elmType = "bool" - value = str(1 if value else 0) + value = 'true' if value else 'false' elif isinstance(value, numbers.Number): elmType = "i4" value = str(int(value)) @@ -48,7 +48,7 @@ def __setitem__(self, key, value): if elm.tag == "{%s}i4" % NS_VT: elm.text = str(int(value)) elif elm.tag == "{%s}bool" % NS_VT: - elm.text = str(1 if value else 0) + elm.text = 'true' if value else 'false' else: elm.text = f"{str(value)}" diff --git a/features/doc-customprops.feature b/features/doc-customprops.feature index 2dcec28a..2ca53a17 100644 --- a/features/doc-customprops.feature +++ b/features/doc-customprops.feature @@ -10,6 +10,12 @@ Feature: Read and write custom document properties And the custom property values match the known values + Scenario: read the custom properties of a document for legacy files + Given a document having known custom properties in legacy format + Then I can access the custom properties object + And the custom property values match the known values + + Scenario: change the custom properties of a document Given a document having known custom properties When I assign new values to the custom properties diff --git a/features/steps/customprops.py b/features/steps/customprops.py index 3ae029bf..91de1381 100644 --- a/features/steps/customprops.py +++ b/features/steps/customprops.py @@ -6,8 +6,6 @@ from __future__ import absolute_import, division, print_function, unicode_literals -from datetime import datetime, timedelta - from behave import given, then, when from docx import Document @@ -24,6 +22,11 @@ def given_a_document_having_known_custom_properties(context): context.document = Document(test_docx("doc-customprops")) +@given("a document having known custom properties in legacy format") +def given_a_document_having_known_custom_properties_legacy(context): + context.document = Document(test_docx("doc-customprops-legacy")) + + @given("a document having no custom properties part") def given_a_document_having_no_custom_properties_part(context): context.document = Document(test_docx("doc-no-customprops")) diff --git a/features/steps/font.py b/features/steps/font.py index ed6e51f2..720b29c5 100644 --- a/features/steps/font.py +++ b/features/steps/font.py @@ -195,8 +195,13 @@ def then_font_highlight_color_is_value(context, value): @then("font.name is {value}") def then_font_name_is_value(context, value): font = context.font + fontname = font.name + if isinstance(fontname, dict): + # word started differentiating typefaces for different regions of the world in 2025 + # font.name is a dict of typeface names for different scripts + fontname = font.name['ascii'] # test against ascii name value = None if value == "None" else value - assert font.name == value + assert fontname == value, f"expected '{value}', got '{fontname}'" @then("font.size is {value}") diff --git a/features/steps/test_files/doc-customprops-legacy.docx b/features/steps/test_files/doc-customprops-legacy.docx new file mode 100644 index 0000000000000000000000000000000000000000..a3dc7a027350607fc79dee5ef7aa29355665a7fc GIT binary patch literal 7922 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�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 Date: Thu, 13 Nov 2025 16:02:50 +0800 Subject: [PATCH 073/115] FIX: Handle 'pt' units in SVG dimensions --- docx/image/svg.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docx/image/svg.py b/docx/image/svg.py index 0aea2627..9ef36ae7 100644 --- a/docx/image/svg.py +++ b/docx/image/svg.py @@ -43,8 +43,8 @@ def _dimensions_from_stream(cls, stream): if root.attrib.get("width") is None: return cls._calculate_scaled_dimensions(root.attrib["viewBox"]) - width = int(root.attrib["width"]) - height = int(root.attrib["height"]) + width = int(float(root.attrib["width"].replace("pt", ""))) + height = int(float(root.attrib["height"].replace("pt", ""))) return width, height @classmethod From a5d502c61c77b02f6d20471ecb69ebea706e144e Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 13 Nov 2025 16:20:00 +0800 Subject: [PATCH 074/115] fix test_customprops --- tests/opc/test_customprops.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/opc/test_customprops.py b/tests/opc/test_customprops.py index e9c5c256..1d5e1838 100644 --- a/tests/opc/test_customprops.py +++ b/tests/opc/test_customprops.py @@ -38,7 +38,7 @@ def prop_get_fixture(self, request, custom_properties_default): @pytest.fixture( params=[ ("CustomPropString", "lpwstr", "Hi there!", "Hi there!"), - ("CustomPropBool", "bool", "0", False), + ("CustomPropBool", "bool", "false", False), ("CustomPropInt", "i4", "5", 5), ] ) From 00c0c86b7b8938822cfaaa82a2030f63676c90c6 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 13 Nov 2025 16:29:27 +0800 Subject: [PATCH 075/115] 0.0.10 --- HISTORY.md | 53 ++++++++++++++++++++++++++---------------------- docx/__init__.py | 2 +- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 9ba210c4..17c5785a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,52 +1,57 @@ ## Release History +**0.0.10 (2025-11-13)** + +- Fix modern bool representations in .docx files. #29 +- Fix \_dimensions_from_stream doesn't handle units properly from svg. #30 + **0.0.9 (2024-11-26)** -- svg file support in add_picture. #27 -- update docs. +- svg file support in add_picture. #27 +- update docs. **0.0.8 (2024-11-22)** -- EastAsia font support fixes. #25 -- Update README.md. #26 +- EastAsia font support fixes. #25 +- Update README.md. #26 **0.0.7 (2022-10-29)** -- add emf image file support. #24 +- add emf image file support. #24 **0.0.6 (2022-10-21)** -- change default custom xml file name to item1. #23 +- change default custom xml file name to item1. #23 **0.0.5 (2022-8-08)** -- minor refactor custom-properties. -- add add_float_picture in Document. #21 +- minor refactor custom-properties. +- add add_float_picture in Document. #21 **0.0.4 (2022-7-21)** -- public python-docx-oss docs @ readthedocs. -- add delete_item in CustomXmlPart. #17 +- public python-docx-oss docs @ readthedocs. +- add delete_item in CustomXmlPart. #17 **0.0.3 (2022-7-01)** -- Change method text to texts in CT_R. #14 -- Add external target_ref setter. #15 -- Blacken all Python files. +- Change method text to texts in CT_R. #14 +- Add external target_ref setter. #15 +- Blacken all Python files. **0.0.2 (2022-06-24)** -- Add custom xml support. #10 -- Add Part **eq**. -- Add Part element setter. -- Add Relationships parts_with_reltype. +- Add custom xml support. #10 +- Add Part **eq**. +- Add Part element setter. +- Add Relationships parts_with_reltype. **0.0.1 (2022-06-16)** -- Only support Python3.8, 3.9 and 3.10. -- Add custom properties support. #2 -- Add drop_rels in Package. #5 -- Add drop_rels in Part. #5 -- Add default NumberingPart. #4 -- Fix Python3.8+ **dict** TypeError. #6 -- Add some typehint. +- Only support Python3.8, 3.9 and 3.10. +- Add custom properties support. #2 +- Add drop_rels in Package. #5 +- Add drop_rels in Part. #5 +- Add default NumberingPart. #4 +- Fix Python3.8+ **dict** TypeError. #6 +- Add some typehint. diff --git a/docx/__init__.py b/docx/__init__.py index 0c147d20..654e934a 100644 --- a/docx/__init__.py +++ b/docx/__init__.py @@ -12,7 +12,7 @@ from docx.parts.settings import SettingsPart from docx.parts.styles import StylesPart # noqa -__version__ = "0.0.9" +__version__ = "0.0.10" # register custom Part classes with opc package reader From 1c09999a73208997a9f84286b0a2aa947679c237 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 13 Nov 2025 18:20:16 +0800 Subject: [PATCH 076/115] DOCS: Add donation link to README.md\n\nFIX: Update custom properties test for modern bool representation --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 9c62fc76..4eeed83c 100644 --- a/README.md +++ b/README.md @@ -25,4 +25,8 @@ _As a Brazilian jiu-jitsu player, OSS means anything and everything. It's a term More information is available in the [python-docx-oss documentation](https://python-docx-oss.readthedocs.io/en/latest/) +### Donation + +If you find this project useful, please consider donating to support its continued development: [https://lsaint.github.io/donation/](https://lsaint.github.io/donation/) + This project is based on the original work by [Steve Canny](https://github.com/scanny) and has been modified by [Ethan St. Lee](https://github.com/lsaint). From a77c11f8e6fd0187c2f39381ece734d8e69f1ff5 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 13 Nov 2025 18:23:22 +0800 Subject: [PATCH 077/115] donation --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4eeed83c..ecec01b6 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ _As a Brazilian jiu-jitsu player, OSS means anything and everything. It's a term License: MIT

    ---- +______________________________________________________________________ ### FAQ @@ -21,12 +21,12 @@ _As a Brazilian jiu-jitsu player, OSS means anything and everything. It's a term **A:** [HISTORY](https://github.com/lsaint/python-docx-oss/blob/master/HISTORY.md) ---- +______________________________________________________________________ More information is available in the [python-docx-oss documentation](https://python-docx-oss.readthedocs.io/en/latest/) ### Donation -If you find this project useful, please consider donating to support its continued development: [https://lsaint.github.io/donation/](https://lsaint.github.io/donation/) +[https://lsaint.github.io/donation/](https://lsaint.github.io/donation/) This project is based on the original work by [Steve Canny](https://github.com/scanny) and has been modified by [Ethan St. Lee](https://github.com/lsaint). From 4836951e3c7e80e3ef9cd62f63af5585cb2ca4ee Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 14 Nov 2025 09:31:23 +0800 Subject: [PATCH 078/115] mv --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ecec01b6..07c2356b 100644 --- a/README.md +++ b/README.md @@ -25,8 +25,8 @@ ______________________________________________________________________ More information is available in the [python-docx-oss documentation](https://python-docx-oss.readthedocs.io/en/latest/) +This project is based on the original work by [Steve Canny](https://github.com/scanny) and has been modified by [Ethan St. Lee](https://github.com/lsaint). + ### Donation [https://lsaint.github.io/donation/](https://lsaint.github.io/donation/) - -This project is based on the original work by [Steve Canny](https://github.com/scanny) and has been modified by [Ethan St. Lee](https://github.com/lsaint). From b5b582e282be497e9813fea74e6ab71e041aa4da Mon Sep 17 00:00:00 2001 From: Ethan St Lee Date: Mon, 17 Nov 2025 15:47:00 +0800 Subject: [PATCH 079/115] round-float viewbox data in _calculate_scaled_dimensions (#31) * round-float viewbox data in _calculate_scaled_dimensions * Enhance SVG unit parsing --- docx/image/svg.py | 67 ++++++++++++++++++++++++++++++++++++----- tests/image/test_svg.py | 38 +++++++++++++++++++++++ 2 files changed, 98 insertions(+), 7 deletions(-) diff --git a/docx/image/svg.py b/docx/image/svg.py index 9ef36ae7..307b797b 100644 --- a/docx/image/svg.py +++ b/docx/image/svg.py @@ -1,3 +1,4 @@ +import re import xml.etree.ElementTree as ET from .constants import MIME_TYPE @@ -18,7 +19,7 @@ def from_stream(cls, stream): in *stream*. """ px_width, px_height = cls._dimensions_from_stream(stream) - return cls(px_width, px_height, 72, 72) + return cls(px_width, px_height, BASE_PX, BASE_PX) @property def content_type(self): @@ -35,23 +36,75 @@ def default_ext(self): """ return "svg" + @classmethod + def _parse_svg_unit_value(cls, value_str: str) -> float: + """ + Parse an SVG length value and return it in points (which are 1/72 of an inch). + Handles units like px, pt, cm, mm, in, pc. + """ + if not value_str: + return 0.0 + + value_str = value_str.strip().lower() + + # Regex to separate the numeric value from the unit, allowing for spaces + match = re.match(r"^(-?\d*\.?\d+)\s*([a-z%]*)$", value_str) + if not match: + # Handle case where there is no unit (treat as px, as per SVG spec) + try: + return float(value_str) + except ValueError: + return 0.0 + + value, unit = match.groups() + numeric_value = float(value) + + # ---conversion factors to points (assuming 72 DPI, where 1pt = 1px)--- + # This matches the existing behavior of the Svg class. + # 1 inch = BASE_PX points + # 1 cm = 1/2.54 inch = BASE_PX/2.54 points + # 1 mm = 1/25.4 inch = BASE_PX/25.4 points + # 1 pc = 12 points + # 1 px = 1 point (at BASE_PX DPI) + + if unit in ("pt", "px", ""): + return numeric_value + elif unit == "in": + return numeric_value * float(BASE_PX) + elif unit == "pc": + return numeric_value * 12.0 + elif unit == "cm": + return numeric_value * float(BASE_PX) / 2.54 + elif unit == "mm": + return numeric_value * float(BASE_PX) / 25.4 + # ---treat other units as px for now--- + else: + return numeric_value + @classmethod def _dimensions_from_stream(cls, stream): stream.seek(0) data = stream.read() root = ET.fromstring(data) - if root.attrib.get("width") is None: + + width_str = root.attrib.get("width") + height_str = root.attrib.get("height") + + if width_str and height_str: + width = round(cls._parse_svg_unit_value(width_str)) + height = round(cls._parse_svg_unit_value(height_str)) + return width, height + + if root.attrib.get("viewBox"): return cls._calculate_scaled_dimensions(root.attrib["viewBox"]) - width = int(float(root.attrib["width"].replace("pt", ""))) - height = int(float(root.attrib["height"].replace("pt", ""))) - return width, height + return 0, 0 @classmethod def _calculate_scaled_dimensions( cls, viewbox: str, base_px: int = BASE_PX ) -> tuple[int, int]: - _, _, logical_width, logical_height = map(int, viewbox.split()) + _, _, logical_width, logical_height = map(float, viewbox.split()) aspect_ratio = logical_width / logical_height @@ -62,4 +115,4 @@ def _calculate_scaled_dimensions( final_height = base_px final_width = base_px * aspect_ratio - return int(final_width), int(final_height) + return round(final_width), round(final_height) diff --git a/tests/image/test_svg.py b/tests/image/test_svg.py index bc18b6e5..9f45d4fb 100644 --- a/tests/image/test_svg.py +++ b/tests/image/test_svg.py @@ -25,6 +25,7 @@ def svg_with_viewbox(): ("0 0 400 200", 72, 36, 72), # Landscape ("0 0 200 400", 100, 200, 200), # Portrait ("0 0 100 100", 50, 50, 50), # Square + ("0 0 100.5 100.5", 50, 50, 50), # Float ] ) def viewbox_data(request): @@ -35,13 +36,49 @@ def viewbox_data(request): @pytest.fixture( params=[ (b'', 200, 100), + (b'', 200, 100), # round-half-to-even (b'', BASE_PX, BASE_PX // 2), + (b'', BASE_PX, 36), + (b'', 72, 36), + (b'', 72, 36), + (b'', 72, 36), + (b'', 72, 36), + (b'', 72, 36), + (b'', 96, 48), + (b"", 0, 0), ] ) def svg_stream_data(request): return request.param +@pytest.fixture( + params=[ + ("100", 100.0), + ("150.5", 150.5), + ("100pt", 100.0), + ("100px", 100.0), + ("1in", 72.0), + ("1pc", 12.0), + ("2.54cm", 72.0), + ("25.4mm", 72.0), + (" 150.5 px ", 150.5), + ("-20.5", -20.5), + ("", 0.0), + ("invalid", 0.0), + ("12em", 12.0), # fallback to px + ] +) +def unit_value_data(request): + """Fixture for different SVG unit value strings.""" + return request.param + + +def test_parse_svg_unit_value(unit_value_data): + value_str, expected_value = unit_value_data + assert Svg._parse_svg_unit_value(value_str) == pytest.approx(expected_value) + + def test_dimensions_from_stream(svg_stream_data): stream_data, expected_width, expected_height = svg_stream_data stream = io.BytesIO(stream_data) @@ -55,3 +92,4 @@ def test_calculate_scaled_dimensions(viewbox_data): width, height = Svg._calculate_scaled_dimensions(viewbox, base_px) assert width == expected_width assert height == expected_height + From 89e1d9db7e07aed1dee56b9f02e7eb16bc9e35c8 Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 17 Nov 2025 15:49:49 +0800 Subject: [PATCH 080/115] 0.0.11 --- HISTORY.md | 4 ++++ docx/__init__.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 17c5785a..3b06bfc6 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,9 @@ ## Release History +0.0.11 (2025-11-17) + +- round-float viewbox and enhance svg unit parsing #31 + **0.0.10 (2025-11-13)** - Fix modern bool representations in .docx files. #29 diff --git a/docx/__init__.py b/docx/__init__.py index 654e934a..5453942e 100644 --- a/docx/__init__.py +++ b/docx/__init__.py @@ -12,7 +12,7 @@ from docx.parts.settings import SettingsPart from docx.parts.styles import StylesPart # noqa -__version__ = "0.0.10" +__version__ = "0.0.11" # register custom Part classes with opc package reader From aa6b33ae3fac4aa53999954b1961596ac8b8aa79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=B7=E8=B4=BC-=E7=8E=8B=E8=B7=AF=E9=A3=9E?= <34393196+xgkk@users.noreply.github.com> Date: Wed, 3 Dec 2025 11:58:54 +0800 Subject: [PATCH 081/115] Feature enhance compatibility for jpeg (#33) * feature: enhance Compatibility for Jpeg --- docx/image/__init__.py | 3 +- docx/image/jpeg.py | 45 ++++++++++ tests/image/test_jpeg.py | 81 ++++++++++++++++++ .../test_files/jpeg_without_app0_and_app1.jpg | Bin 0 -> 54631 bytes 4 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 tests/test_files/jpeg_without_app0_and_app1.jpg diff --git a/docx/image/__init__.py b/docx/image/__init__.py index 3b0f0979..47576c49 100644 --- a/docx/image/__init__.py +++ b/docx/image/__init__.py @@ -10,7 +10,7 @@ from docx.image.bmp import Bmp from docx.image.emf import Emf from docx.image.gif import Gif -from docx.image.jpeg import Exif, Jfif +from docx.image.jpeg import Exif, Jfif, Jpeg from docx.image.png import Png from docx.image.svg import Svg from docx.image.tiff import Tiff @@ -21,6 +21,7 @@ (Png, 0, b"\x89PNG\x0D\x0A\x1A\x0A"), (Jfif, 6, b"JFIF"), (Exif, 6, b"Exif"), + (Jpeg, 0, b"\xff\xd8"), (Gif, 0, b"GIF87a"), (Gif, 0, b"GIF89a"), (Tiff, 0, b"MM\x00*"), # big-endian (Motorola) TIFF diff --git a/docx/image/jpeg.py b/docx/image/jpeg.py index 40354e97..513287d0 100644 --- a/docx/image/jpeg.py +++ b/docx/image/jpeg.py @@ -29,6 +29,51 @@ def default_ext(self): """ return "jpg" + DEFAULT_DPI = 72 + + @classmethod + def from_stream(cls, stream): + """ + If APP0 or APP1 is missing, the DPI values will be set to the default value of |DEFAULT_DPI|(72). + """ + markers = _JfifMarkers.from_stream(stream) + px_width = markers.sof.px_width + px_height = markers.sof.px_height + horz_dpi, vert_dpi = cls._get_horz_dpi_and_vert_dpi(markers) + return cls(px_width, px_height, horz_dpi, vert_dpi) + + @classmethod + def _get_horz_dpi_and_vert_dpi(cls, markers): + horz_dpi, vert_dpi = cls._try_get_dpi_from_app0(markers) + if horz_dpi is None or vert_dpi is None: + horz_dpi, vert_dpi = cls._try_get_dpi_from_app1(markers) + if horz_dpi is None or vert_dpi is None: + horz_dpi = vert_dpi = cls.DEFAULT_DPI + # DPI values in APP0 or APP1 may be 0, which is invalid. should use default value. + if horz_dpi == 0: + horz_dpi = cls.DEFAULT_DPI + if vert_dpi == 0: + vert_dpi = cls.DEFAULT_DPI + return horz_dpi, vert_dpi + + @staticmethod + def _try_get_dpi_from_app0(markers): + try: + horz_dpi = markers.app0.horz_dpi + vert_dpi = markers.app0.vert_dpi + return horz_dpi, vert_dpi + except KeyError: + return None, None + + @staticmethod + def _try_get_dpi_from_app1(markers): + try: + horz_dpi = markers.app1.horz_dpi + vert_dpi = markers.app1.vert_dpi + return horz_dpi, vert_dpi + except KeyError: + return None, None + class Exif(Jpeg): """ diff --git a/tests/image/test_jpeg.py b/tests/image/test_jpeg.py index 759bd94c..824ef393 100644 --- a/tests/image/test_jpeg.py +++ b/tests/image/test_jpeg.py @@ -31,6 +31,8 @@ initializer_mock, instance_mock, method_mock, + MagicMock, + PropertyMock ) @@ -43,6 +45,14 @@ def it_knows_its_default_ext(self): jpeg = Jpeg(None, None, None, None) assert jpeg.default_ext == "jpg" + def it_not_contains_app0_or_app1(self): + with open("tests/test_files/jpeg_without_app0_and_app1.jpg", "rb") as f: + jpeg = Jpeg.from_stream(f) + assert jpeg.horz_dpi == 72 + assert jpeg.vert_dpi == 72 + assert jpeg.px_width == 1190 + assert jpeg.px_height == 1190 + class DescribeExif(object): def it_can_construct_from_an_exif_stream(self, from_exif_fixture): # fixture ---------------------- @@ -637,3 +647,74 @@ def StreamReader_(self, request, stream_reader_): @pytest.fixture def stream_reader_(self, request): return instance_mock(request, StreamReader) + + +class TestJpegMethods: + def test_get_horz_dpi_and_vert_dpi_from_app0(self, mocker): + markers = MagicMock() + mocker.patch.object(Jpeg, "_try_get_dpi_from_app0", return_value=(96, 96)) + horz_dpi,vert_dpi = Jpeg._get_horz_dpi_and_vert_dpi(markers) + assert horz_dpi == 96 + assert vert_dpi == 96 + + def test_get_horz_dpi_and_vert_dpi_from_app0_but_return_zero(self, mocker): + markers = MagicMock() + mocker.patch.object(Jpeg, "_try_get_dpi_from_app0", return_value=(0, 0)) + horz_dpi,vert_dpi = Jpeg._get_horz_dpi_and_vert_dpi(markers) + assert horz_dpi == 72 + assert vert_dpi == 72 + + + def test_get_horz_dpi_and_vert_dpi_from_app1(self, mocker): + markers = MagicMock() + mocker.patch.object(Jpeg, "_try_get_dpi_from_app0", return_value=(None, None)) + mocker.patch.object(Jpeg, "_try_get_dpi_from_app1", return_value=(96, 96)) + horz_dpi,vert_dpi = Jpeg._get_horz_dpi_and_vert_dpi(markers) + assert horz_dpi == 96 + assert vert_dpi == 96 + + def test_get_horz_dpi_and_vert_dpi_from_app1_but_return_zero(self, mocker): + markers = MagicMock() + mocker.patch.object(Jpeg, "_try_get_dpi_from_app0", return_value=(None, None)) + mocker.patch.object(Jpeg, "_try_get_dpi_from_app1", return_value=(0, 0)) + horz_dpi,vert_dpi = Jpeg._get_horz_dpi_and_vert_dpi(markers) + assert horz_dpi == 72 + assert vert_dpi == 72 + + def test_get_horz_dpi_and_vert_dpi_from_DEFAULT_DPI(self, mocker): + markers = MagicMock() + mocker.patch.object(Jpeg, "_try_get_dpi_from_app0", return_value=(None, None)) + mocker.patch.object(Jpeg, "_try_get_dpi_from_app1", return_value=(None, None)) + horz_dpi,vert_dpi = Jpeg._get_horz_dpi_and_vert_dpi(markers) + assert horz_dpi == 72 + assert vert_dpi == 72 + + def test__try_get_dpi_from_app0_returns_None(self, mocker): + markers = MagicMock() + type(markers).app0 = PropertyMock(side_effect=KeyError("APP0 not found")) + horz_dpi,vert_dpi = Jpeg._try_get_dpi_from_app0(markers) + assert horz_dpi is None + assert vert_dpi is None + + def test__try_get_dpi_from_app0(self, mocker): + markers = MagicMock() + markers.app0.horz_dpi = 96 + markers.app0.vert_dpi = 96 + horz_dpi,vert_dpi = Jpeg._try_get_dpi_from_app0(markers) + assert horz_dpi == 96 + assert vert_dpi == 96 + + def test__try_get_dpi_from_app1_returns_None(self, mocker): + markers = MagicMock() + type(markers).app1 = PropertyMock(side_effect=KeyError("APP1 not found")) + horz_dpi,vert_dpi = Jpeg._try_get_dpi_from_app1(markers) + assert horz_dpi is None + assert vert_dpi is None + + def test__try_get_dpi_from_app1(self, mocker): + markers = MagicMock() + markers.app1.horz_dpi = 96 + markers.app1.vert_dpi = 96 + horz_dpi,vert_dpi = Jpeg._try_get_dpi_from_app1(markers) + assert horz_dpi == 96 + assert vert_dpi == 96 diff --git a/tests/test_files/jpeg_without_app0_and_app1.jpg b/tests/test_files/jpeg_without_app0_and_app1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d17bca1a0928d61d4dda3fc7a1686f8196f9d502 GIT binary patch literal 54631 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 IRrb37A3um@Gynhq literal 0 HcmV?d00001 From 97965bc79154483a273a15a42e08a47b1c2aada0 Mon Sep 17 00:00:00 2001 From: Ethan Date: Wed, 3 Dec 2025 12:04:33 +0800 Subject: [PATCH 082/115] 0.0.12 --- HISTORY.md | 4 ++++ docx/__init__.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 3b06bfc6..ce138268 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,9 @@ ## Release History +0.0.12 (2025-12-03) + +- default dpi for jpeg #33 + 0.0.11 (2025-11-17) - round-float viewbox and enhance svg unit parsing #31 diff --git a/docx/__init__.py b/docx/__init__.py index 5453942e..4a173f6a 100644 --- a/docx/__init__.py +++ b/docx/__init__.py @@ -12,7 +12,7 @@ from docx.parts.settings import SettingsPart from docx.parts.styles import StylesPart # noqa -__version__ = "0.0.11" +__version__ = "0.0.12" # register custom Part classes with opc package reader From 448abc42e007aa3531cc1a5abd795561cc24c0ca Mon Sep 17 00:00:00 2001 From: Ethan Date: Wed, 4 Feb 2026 09:56:43 +0800 Subject: [PATCH 083/115] Squash merge 0.1.0 into master --- .fdignore | 7 + .gitignore | 5 +- .projections.json | 14 + .readthedocs.yaml | 15 +- .rgignore | 9 + .travis.yml | 8 +- HISTORY.md | 5 + MANIFEST.in | 5 +- Makefile | 59 +- README.md | 2 +- docs/_static/img/comment-parts.png | Bin 0 -> 30058 bytes docs/api/comments.rst | 27 + docs/conf.py | 12 + docs/dev/analysis/features/comments.rst | 419 ++++++ docs/dev/analysis/features/coreprops.rst | 4 +- docs/dev/analysis/features/text/hyperlink.rst | 383 +++++ docs/dev/analysis/features/text/index.rst | 1 + docs/dev/analysis/index.rst | 1 + docs/index.rst | 3 + docs/user/comments.rst | 168 +++ docs/user/install.rst | 2 +- docs/user/tables.rst | 202 +++ docx/api.py | 37 - docx/blkcntnr.py | 77 - docx/compat.py | 39 - docx/dml/color.py | 114 -- docx/document.py | 214 --- docx/enum/__init__.py | 17 - docx/enum/base.py | 371 ----- docx/enum/dml.py | 113 -- docx/enum/section.py | 91 -- docx/enum/shape.py | 23 - docx/enum/style.py | 196 --- docx/enum/table.py | 147 -- docx/enum/text.py | 279 ---- docx/exceptions.py | 27 - docx/image/exceptions.py | 23 - docx/image/image.py | 265 ---- docx/opc/compat.py | 49 - docx/opc/constants.py | 559 ------- docx/opc/exceptions.py | 19 - docx/opc/packuri.py | 118 -- docx/opc/part.py | 245 --- docx/opc/parts/coreprops.py | 51 - docx/opc/pkgwriter.py | 127 -- docx/opc/rel.py | 181 --- docx/opc/shared.py | 46 - docx/oxml/document.py | 69 - docx/oxml/exceptions.py | 16 - docx/oxml/section.py | 370 ----- docx/oxml/shared.py | 58 - docx/oxml/table.py | 948 ------------ docx/oxml/text/font.py | 377 ----- docx/oxml/text/paragraph.py | 79 - docx/oxml/text/run.py | 164 --- docx/parts/document.py | 181 --- docx/parts/image.py | 88 -- docx/parts/settings.py | 52 - docx/parts/story.py | 84 -- docx/parts/styles.py | 53 - docx/settings.py | 28 - docx/shared.py | 259 ---- docx/styles/__init__.py | 48 - docx/styles/latent.py | 222 --- docx/styles/style.py | 263 ---- docx/styles/styles.py | 150 -- docx/table.py | 467 ------ docx/text/font.py | 424 ------ docx/text/paragraph.py | 142 -- docx/text/run.py | 192 --- docx/text/tabstops.py | 142 -- features/blk-iter-inner-content.feature | 24 + features/cmt-mutations.feature | 59 + features/cmt-props.feature | 35 + features/doc-add-comment.feature | 13 + features/doc-comments.feature | 36 + features/environment.py | 7 +- features/hlk-props.feature | 54 + features/par-access-inner-content.feature | 49 + features/pbk-split-para.feature | 24 + features/run-access-content.feature | 9 - features/run-access-inner-content.feature | 25 + features/run-add-content.feature | 2 +- features/sct-section.feature | 5 + features/steps/api.py | 8 +- features/steps/block.py | 68 +- features/steps/cell.py | 57 - features/steps/comments.py | 284 ++++ features/steps/coreprops.py | 44 +- features/steps/document.py | 19 +- features/steps/font.py | 25 +- features/steps/hdrftr.py | 7 +- features/steps/helpers.py | 26 +- features/steps/hyperlink.py | 116 ++ features/steps/image.py | 9 +- features/steps/numbering.py | 7 +- features/steps/pagebreak.py | 135 ++ features/steps/paragraph.py | 151 +- features/steps/parfmt.py | 13 +- features/steps/section.py | 86 +- features/steps/settings.py | 32 +- features/steps/shape.py | 16 +- features/steps/shared.py | 7 +- features/steps/styles.py | 12 +- features/steps/table.py | 228 ++- features/steps/tabstops.py | 9 +- .../test_files/blk-paras-and-tables.docx | Bin 0 -> 15649 bytes .../steps/test_files/comments-rich-para.docx | Bin 0 -> 20023 bytes .../steps/test_files/par-hlink-frags.docx | Bin 0 -> 12071 bytes features/steps/test_files/par-hyperlinks.docx | Bin 0 -> 12385 bytes .../test_files/par-rendered-page-breaks.docx | Bin 0 -> 12244 bytes .../steps/test_files/sct-inner-content.docx | Bin 0 -> 12051 bytes features/steps/test_files/tbl-cell-props.docx | Bin 0 -> 13773 bytes features/steps/test_files/tbl-props.docx | Bin 20178 -> 20419 bytes features/steps/text.py | 71 +- ...ble.feature => tbl-cell-add-table.feature} | 0 features/tbl-cell-props.feature | 11 + ...cel-text.feature => tbl-cell-text.feature} | 0 features/tbl-row-props.feature | 22 + pyproject.toml | 114 ++ ref/xsd/vml-wordprocessingDrawing.xsd | 9 +- requirements-dev.txt | 12 +- requirements-docs.txt | 6 + requirements-test.txt | 8 + requirements.txt | 2 +- setup.py | 79 - {docx => src/docx}/__init__.py | 37 +- src/docx/api.py | 37 + src/docx/blkcntnr.py | 101 ++ src/docx/comments.py | 163 ++ {docx => src/docx}/dml/__init__.py | 0 src/docx/dml/color.py | 112 ++ src/docx/document.py | 285 ++++ src/docx/drawing/__init__.py | 59 + {docx/opc => src/docx/enum}/__init__.py | 0 src/docx/enum/base.py | 150 ++ src/docx/enum/dml.py | 103 ++ src/docx/enum/section.py | 86 ++ src/docx/enum/shape.py | 19 + src/docx/enum/style.py | 452 ++++++ src/docx/enum/table.py | 136 ++ src/docx/enum/text.py | 367 +++++ src/docx/exceptions.py | 18 + {docx => src/docx}/image/__init__.py | 11 +- {docx => src/docx}/image/bmp.py | 30 +- {docx => src/docx}/image/constants.py | 166 +-- {docx => src/docx}/image/emf.py | 2 +- src/docx/image/exceptions.py | 13 + {docx => src/docx}/image/gif.py | 28 +- {docx => src/docx}/image/helpers.py | 54 +- src/docx/image/image.py | 237 +++ {docx => src/docx}/image/jpeg.py | 279 ++-- {docx => src/docx}/image/png.py | 156 +- {docx => src/docx}/image/svg.py | 0 {docx => src/docx}/image/tiff.py | 234 ++- {docx/opc/parts => src/docx/opc}/__init__.py | 0 src/docx/opc/constants.py | 307 ++++ {docx => src/docx}/opc/coreprops.py | 56 +- {docx => src/docx}/opc/customprops.py | 0 src/docx/opc/exceptions.py | 12 + {docx => src/docx}/opc/oxml.py | 199 +-- {docx => src/docx}/opc/package.py | 210 ++- src/docx/opc/packuri.py | 109 ++ src/docx/opc/part.py | 267 ++++ .../text => src/docx/opc/parts}/__init__.py | 0 src/docx/opc/parts/coreprops.py | 48 + {docx => src/docx}/opc/parts/customprops.py | 0 {docx => src/docx}/opc/phys_pkg.py | 103 +- {docx => src/docx}/opc/pkgreader.py | 175 +-- src/docx/opc/pkgwriter.py | 115 ++ src/docx/opc/rel.py | 169 +++ src/docx/opc/shared.py | 31 + {docx => src/docx}/opc/spec.py | 9 +- {docx => src/docx}/oxml/__init__.py | 242 ++- src/docx/oxml/comments.py | 124 ++ {docx => src/docx}/oxml/coreprops.py | 191 ++- {docx => src/docx}/oxml/customprops.py | 0 src/docx/oxml/dml/CT_ExtensionList.py | 48 + src/docx/oxml/document.py | 88 ++ src/docx/oxml/drawing.py | 11 + src/docx/oxml/exceptions.py | 10 + {docx => src/docx}/oxml/ns.py | 88 +- {docx => src/docx}/oxml/numbering.py | 82 +- src/docx/oxml/parser.py | 62 + src/docx/oxml/section.py | 537 +++++++ {docx => src/docx}/oxml/settings.py | 31 +- {docx => src/docx}/oxml/shape.py | 374 ++--- src/docx/oxml/shared.py | 52 + {docx => src/docx}/oxml/simpletypes.py | 241 +-- {docx => src/docx}/oxml/styles.py | 166 +-- src/docx/oxml/table.py | 977 ++++++++++++ .../parts => src/docx/oxml/text}/__init__.py | 0 src/docx/oxml/text/font.py | 358 +++++ src/docx/oxml/text/hyperlink.py | 45 + src/docx/oxml/text/pagebreak.py | 278 ++++ src/docx/oxml/text/paragraph.py | 106 ++ {docx => src/docx}/oxml/text/parfmt.py | 207 +-- src/docx/oxml/text/run.py | 316 ++++ {docx => src/docx}/oxml/xmlchemy.py | 561 +++---- {docx => src/docx}/package.py | 68 +- {docx/text => src/docx/parts}/__init__.py | 0 src/docx/parts/comments.py | 51 + {docx => src/docx}/parts/customxml.py | 0 src/docx/parts/document.py | 193 +++ {docx => src/docx}/parts/hdrftr.py | 30 +- src/docx/parts/image.py | 80 + {docx => src/docx}/parts/numbering.py | 37 +- src/docx/parts/settings.py | 50 + src/docx/parts/story.py | 113 ++ src/docx/parts/styles.py | 42 + src/docx/py.typed | 0 {docx => src/docx}/section.py | 288 ++-- src/docx/settings.py | 35 + {docx => src/docx}/shape.py | 68 +- src/docx/shared.py | 382 +++++ src/docx/styles/__init__.py | 40 + src/docx/styles/latent.py | 198 +++ src/docx/styles/style.py | 254 ++++ src/docx/styles/styles.py | 136 ++ src/docx/table.py | 537 +++++++ src/docx/templates/default-comments.xml | 12 + .../default-docx-template/[Content_Types].xml | 0 .../default-docx-template/_rels/.rels | 0 .../customXml/_rels/item1.xml.rels | 0 .../default-docx-template/customXml/item1.xml | 0 .../customXml/itemProps1.xml | 0 .../default-docx-template/docProps/app.xml | 0 .../default-docx-template/docProps/core.xml | 0 .../docProps/thumbnail.jpeg | Bin .../word/_rels/document.xml.rels | 0 .../default-docx-template/word/document.xml | 0 .../default-docx-template/word/fontTable.xml | 0 .../default-docx-template/word/numbering.xml | 0 .../default-docx-template/word/settings.xml | 0 .../default-docx-template/word/styles.xml | 0 .../word/stylesWithEffects.xml | 0 .../word/theme/theme1.xml | 0 .../word/webSettings.xml | 0 .../docx}/templates/default-footer.xml | 0 .../docx}/templates/default-header.xml | 0 .../docx}/templates/default-numbering.xml | 0 .../docx}/templates/default-settings.xml | 0 .../docx}/templates/default-styles.xml | 0 {docx => src/docx}/templates/default.docx | Bin src/docx/text/__init__.py | 0 src/docx/text/font.py | 466 ++++++ src/docx/text/hyperlink.py | 121 ++ src/docx/text/pagebreak.py | 104 ++ src/docx/text/paragraph.py | 173 +++ {docx => src/docx}/text/parfmt.py | 187 ++- src/docx/text/run.py | 272 ++++ src/docx/text/tabstops.py | 123 ++ src/docx/types.py | 34 + tests/conftest.py | 21 + tests/dml/test_color.py | 159 +- tests/image/test_bmp.py | 19 +- tests/image/test_emf.py | 49 +- tests/image/test_gif.py | 13 +- tests/image/test_helpers.py | 19 +- tests/image/test_image.py | 39 +- tests/image/test_jpeg.py | 178 +-- tests/image/test_png.py | 71 +- tests/image/test_svg.py | 35 +- tests/image/test_tiff.py | 81 +- tests/opc/parts/test_coreprops.py | 52 +- tests/opc/test_coreprops.py | 268 ++-- tests/opc/test_customprops.py | 50 +- tests/opc/test_oxml.py | 18 +- tests/opc/test_package.py | 206 +-- tests/opc/test_packuri.py | 12 +- tests/opc/test_part.py | 412 +++--- tests/opc/test_phys_pkg.py | 51 +- tests/opc/test_pkgreader.py | 73 +- tests/opc/test_pkgwriter.py | 104 +- tests/opc/test_rel.py | 63 +- tests/opc/unitdata/rels.py | 35 +- tests/opc/unitdata/types.py | 8 +- tests/oxml/parts/test_document.py | 15 +- tests/oxml/parts/unitdata/document.py | 6 +- tests/oxml/test__init__.py | 30 +- tests/oxml/test_comments.py | 31 + tests/oxml/test_document.py | 19 + tests/oxml/test_ns.py | 10 +- tests/oxml/test_section.py | 19 + tests/oxml/test_styles.py | 13 +- tests/oxml/test_table.py | 503 ++++--- tests/oxml/test_xmlchemy.py | 113 +- tests/oxml/text/test_hyperlink.py | 45 + tests/oxml/text/test_run.py | 73 +- tests/oxml/unitdata/numbering.py | 6 +- tests/oxml/unitdata/section.py | 6 +- tests/oxml/unitdata/shared.py | 6 +- tests/oxml/unitdata/styles.py | 6 +- tests/oxml/unitdata/text.py | 6 +- tests/parts/test_comments.py | 87 ++ tests/parts/test_document.py | 320 ++-- tests/parts/test_hdrftr.py | 21 +- tests/parts/test_image.py | 23 +- tests/parts/test_numbering.py | 16 +- tests/parts/test_settings.py | 14 +- tests/parts/test_story.py | 34 +- tests/parts/test_styles.py | 10 +- tests/styles/test_latent.py | 16 +- tests/styles/test_style.py | 73 +- tests/styles/test_styles.py | 35 +- tests/test_api.py | 78 +- tests/test_blkcntnr.py | 197 +-- tests/test_comments.py | 275 ++++ tests/test_document.py | 507 ++++--- tests/test_drawing.py | 74 + tests/test_enum.py | 136 +- tests/test_files/blk-inner-content.docx | Bin 0 -> 11949 bytes tests/test_files/sct-inner-content.docx | Bin 0 -> 12051 bytes tests/test_files/snippets/inline.txt | 4 +- tests/test_files/sonic.emf | Bin 0 -> 40 bytes tests/test_package.py | 156 +- tests/test_section.py | 848 ++++++----- tests/test_settings.py | 71 +- tests/test_shape.py | 281 ++-- tests/test_shared.py | 146 +- tests/test_table.py | 1309 ++++++++--------- tests/text/test_font.py | 473 +++--- tests/text/test_hyperlink.py | 149 ++ tests/text/test_pagebreak.py | 141 ++ tests/text/test_paragraph.py | 159 +- tests/text/test_parfmt.py | 13 +- tests/text/test_run.py | 567 +++---- tests/text/test_tabstops.py | 15 +- tests/unitdata.py | 16 +- tests/unitutil/cxml.py | 65 +- tests/unitutil/file.py | 41 +- tests/unitutil/mock.py | 124 +- tox.ini | 24 +- typings/behave/__init__.pyi | 17 + typings/behave/runner.pyi | 3 + uv.lock | 1090 ++++++++++++++ 336 files changed, 20825 insertions(+), 15870 deletions(-) create mode 100644 .fdignore create mode 100644 .projections.json create mode 100644 .rgignore create mode 100644 docs/_static/img/comment-parts.png create mode 100644 docs/api/comments.rst create mode 100644 docs/dev/analysis/features/comments.rst create mode 100644 docs/dev/analysis/features/text/hyperlink.rst create mode 100644 docs/user/comments.rst create mode 100644 docs/user/tables.rst delete mode 100644 docx/api.py delete mode 100644 docx/blkcntnr.py delete mode 100644 docx/compat.py delete mode 100644 docx/dml/color.py delete mode 100644 docx/document.py delete mode 100644 docx/enum/__init__.py delete mode 100644 docx/enum/base.py delete mode 100644 docx/enum/dml.py delete mode 100644 docx/enum/section.py delete mode 100644 docx/enum/shape.py delete mode 100644 docx/enum/style.py delete mode 100644 docx/enum/table.py delete mode 100644 docx/enum/text.py delete mode 100644 docx/exceptions.py delete mode 100644 docx/image/exceptions.py delete mode 100644 docx/image/image.py delete mode 100644 docx/opc/compat.py delete mode 100644 docx/opc/constants.py delete mode 100644 docx/opc/exceptions.py delete mode 100644 docx/opc/packuri.py delete mode 100644 docx/opc/part.py delete mode 100644 docx/opc/parts/coreprops.py delete mode 100644 docx/opc/pkgwriter.py delete mode 100644 docx/opc/rel.py delete mode 100644 docx/opc/shared.py delete mode 100644 docx/oxml/document.py delete mode 100644 docx/oxml/exceptions.py delete mode 100644 docx/oxml/section.py delete mode 100644 docx/oxml/shared.py delete mode 100644 docx/oxml/table.py delete mode 100644 docx/oxml/text/font.py delete mode 100644 docx/oxml/text/paragraph.py delete mode 100644 docx/oxml/text/run.py delete mode 100644 docx/parts/document.py delete mode 100644 docx/parts/image.py delete mode 100644 docx/parts/settings.py delete mode 100644 docx/parts/story.py delete mode 100644 docx/parts/styles.py delete mode 100644 docx/settings.py delete mode 100644 docx/shared.py delete mode 100644 docx/styles/__init__.py delete mode 100644 docx/styles/latent.py delete mode 100644 docx/styles/style.py delete mode 100644 docx/styles/styles.py delete mode 100644 docx/table.py delete mode 100644 docx/text/font.py delete mode 100644 docx/text/paragraph.py delete mode 100644 docx/text/run.py delete mode 100644 docx/text/tabstops.py create mode 100644 features/blk-iter-inner-content.feature create mode 100644 features/cmt-mutations.feature create mode 100644 features/cmt-props.feature create mode 100644 features/doc-add-comment.feature create mode 100644 features/doc-comments.feature create mode 100644 features/hlk-props.feature create mode 100644 features/par-access-inner-content.feature create mode 100644 features/pbk-split-para.feature delete mode 100644 features/run-access-content.feature create mode 100644 features/run-access-inner-content.feature delete mode 100644 features/steps/cell.py create mode 100644 features/steps/comments.py create mode 100644 features/steps/hyperlink.py create mode 100644 features/steps/pagebreak.py create mode 100644 features/steps/test_files/blk-paras-and-tables.docx create mode 100644 features/steps/test_files/comments-rich-para.docx create mode 100644 features/steps/test_files/par-hlink-frags.docx create mode 100644 features/steps/test_files/par-hyperlinks.docx create mode 100644 features/steps/test_files/par-rendered-page-breaks.docx create mode 100644 features/steps/test_files/sct-inner-content.docx create mode 100644 features/steps/test_files/tbl-cell-props.docx rename features/{cel-add-table.feature => tbl-cell-add-table.feature} (100%) rename features/{cel-text.feature => tbl-cell-text.feature} (100%) create mode 100644 pyproject.toml create mode 100644 requirements-docs.txt create mode 100644 requirements-test.txt delete mode 100644 setup.py rename {docx => src/docx}/__init__.py (66%) create mode 100644 src/docx/api.py create mode 100644 src/docx/blkcntnr.py create mode 100644 src/docx/comments.py rename {docx => src/docx}/dml/__init__.py (100%) create mode 100644 src/docx/dml/color.py create mode 100644 src/docx/document.py create mode 100644 src/docx/drawing/__init__.py rename {docx/opc => src/docx/enum}/__init__.py (100%) create mode 100644 src/docx/enum/base.py create mode 100644 src/docx/enum/dml.py create mode 100644 src/docx/enum/section.py create mode 100644 src/docx/enum/shape.py create mode 100644 src/docx/enum/style.py create mode 100644 src/docx/enum/table.py create mode 100644 src/docx/enum/text.py create mode 100644 src/docx/exceptions.py rename {docx => src/docx}/image/__init__.py (74%) rename {docx => src/docx}/image/bmp.py (59%) rename {docx => src/docx}/image/constants.py (50%) rename {docx => src/docx}/image/emf.py (95%) create mode 100644 src/docx/image/exceptions.py rename {docx => src/docx}/image/gif.py (53%) rename {docx => src/docx}/image/helpers.py (59%) create mode 100644 src/docx/image/image.py rename {docx => src/docx}/image/jpeg.py (66%) rename {docx => src/docx}/image/png.py (62%) rename {docx => src/docx}/image/svg.py (100%) rename {docx => src/docx}/image/tiff.py (52%) rename {docx/opc/parts => src/docx/opc}/__init__.py (100%) create mode 100644 src/docx/opc/constants.py rename {docx => src/docx}/opc/coreprops.py (67%) rename {docx => src/docx}/opc/customprops.py (100%) create mode 100644 src/docx/opc/exceptions.py rename {docx => src/docx}/opc/oxml.py (50%) rename {docx => src/docx}/opc/package.py (51%) create mode 100644 src/docx/opc/packuri.py create mode 100644 src/docx/opc/part.py rename {docx/oxml/text => src/docx/opc/parts}/__init__.py (100%) create mode 100644 src/docx/opc/parts/coreprops.py rename {docx => src/docx}/opc/parts/customprops.py (100%) rename {docx => src/docx}/opc/phys_pkg.py (50%) rename {docx => src/docx}/opc/pkgreader.py (59%) create mode 100644 src/docx/opc/pkgwriter.py create mode 100644 src/docx/opc/rel.py create mode 100644 src/docx/opc/shared.py rename {docx => src/docx}/opc/spec.py (77%) rename {docx => src/docx}/oxml/__init__.py (63%) create mode 100644 src/docx/oxml/comments.py rename {docx => src/docx}/oxml/coreprops.py (59%) rename {docx => src/docx}/oxml/customprops.py (100%) create mode 100644 src/docx/oxml/dml/CT_ExtensionList.py create mode 100644 src/docx/oxml/document.py create mode 100644 src/docx/oxml/drawing.py create mode 100644 src/docx/oxml/exceptions.py rename {docx => src/docx}/oxml/ns.py (52%) rename {docx => src/docx}/oxml/numbering.py (56%) create mode 100644 src/docx/oxml/parser.py create mode 100644 src/docx/oxml/section.py rename {docx => src/docx}/oxml/settings.py (80%) rename {docx => src/docx}/oxml/shape.py (53%) create mode 100644 src/docx/oxml/shared.py rename {docx => src/docx}/oxml/simpletypes.py (51%) rename {docx => src/docx}/oxml/styles.py (67%) create mode 100644 src/docx/oxml/table.py rename {docx/parts => src/docx/oxml/text}/__init__.py (100%) create mode 100644 src/docx/oxml/text/font.py create mode 100644 src/docx/oxml/text/hyperlink.py create mode 100644 src/docx/oxml/text/pagebreak.py create mode 100644 src/docx/oxml/text/paragraph.py rename {docx => src/docx}/oxml/text/parfmt.py (58%) create mode 100644 src/docx/oxml/text/run.py rename {docx => src/docx}/oxml/xmlchemy.py (53%) rename {docx => src/docx}/package.py (59%) rename {docx/text => src/docx/parts}/__init__.py (100%) create mode 100644 src/docx/parts/comments.py rename {docx => src/docx}/parts/customxml.py (100%) create mode 100644 src/docx/parts/document.py rename {docx => src/docx}/parts/hdrftr.py (66%) create mode 100644 src/docx/parts/image.py rename {docx => src/docx}/parts/numbering.py (55%) create mode 100644 src/docx/parts/settings.py create mode 100644 src/docx/parts/story.py create mode 100644 src/docx/parts/styles.py create mode 100644 src/docx/py.typed rename {docx => src/docx}/section.py (65%) create mode 100644 src/docx/settings.py rename {docx => src/docx}/shape.py (58%) create mode 100644 src/docx/shared.py create mode 100644 src/docx/styles/__init__.py create mode 100644 src/docx/styles/latent.py create mode 100644 src/docx/styles/style.py create mode 100644 src/docx/styles/styles.py create mode 100644 src/docx/table.py create mode 100644 src/docx/templates/default-comments.xml rename {docx => src/docx}/templates/default-docx-template/[Content_Types].xml (100%) rename {docx => src/docx}/templates/default-docx-template/_rels/.rels (100%) rename {docx => src/docx}/templates/default-docx-template/customXml/_rels/item1.xml.rels (100%) rename {docx => src/docx}/templates/default-docx-template/customXml/item1.xml (100%) rename {docx => src/docx}/templates/default-docx-template/customXml/itemProps1.xml (100%) rename {docx => src/docx}/templates/default-docx-template/docProps/app.xml (100%) rename {docx => src/docx}/templates/default-docx-template/docProps/core.xml (100%) rename {docx => src/docx}/templates/default-docx-template/docProps/thumbnail.jpeg (100%) rename {docx => src/docx}/templates/default-docx-template/word/_rels/document.xml.rels (100%) rename {docx => src/docx}/templates/default-docx-template/word/document.xml (100%) rename {docx => src/docx}/templates/default-docx-template/word/fontTable.xml (100%) rename {docx => src/docx}/templates/default-docx-template/word/numbering.xml (100%) rename {docx => src/docx}/templates/default-docx-template/word/settings.xml (100%) rename {docx => src/docx}/templates/default-docx-template/word/styles.xml (100%) rename {docx => src/docx}/templates/default-docx-template/word/stylesWithEffects.xml (100%) rename {docx => src/docx}/templates/default-docx-template/word/theme/theme1.xml (100%) rename {docx => src/docx}/templates/default-docx-template/word/webSettings.xml (100%) rename {docx => src/docx}/templates/default-footer.xml (100%) rename {docx => src/docx}/templates/default-header.xml (100%) rename {docx => src/docx}/templates/default-numbering.xml (100%) rename {docx => src/docx}/templates/default-settings.xml (100%) rename {docx => src/docx}/templates/default-styles.xml (100%) rename {docx => src/docx}/templates/default.docx (100%) create mode 100644 src/docx/text/__init__.py create mode 100644 src/docx/text/font.py create mode 100644 src/docx/text/hyperlink.py create mode 100644 src/docx/text/pagebreak.py create mode 100644 src/docx/text/paragraph.py rename {docx => src/docx}/text/parfmt.py (53%) create mode 100644 src/docx/text/run.py create mode 100644 src/docx/text/tabstops.py create mode 100644 src/docx/types.py create mode 100644 tests/conftest.py create mode 100644 tests/oxml/test_comments.py create mode 100644 tests/oxml/test_document.py create mode 100644 tests/oxml/test_section.py create mode 100644 tests/oxml/text/test_hyperlink.py create mode 100644 tests/parts/test_comments.py create mode 100644 tests/test_comments.py create mode 100644 tests/test_drawing.py create mode 100644 tests/test_files/blk-inner-content.docx create mode 100644 tests/test_files/sct-inner-content.docx create mode 100644 tests/test_files/sonic.emf create mode 100644 tests/text/test_hyperlink.py create mode 100644 tests/text/test_pagebreak.py create mode 100644 typings/behave/__init__.pyi create mode 100644 typings/behave/runner.pyi create mode 100644 uv.lock diff --git a/.fdignore b/.fdignore new file mode 100644 index 00000000..41bdd382 --- /dev/null +++ b/.fdignore @@ -0,0 +1,7 @@ +.tox +Session.vim +build/ +docs/.build +features/_scratch +__pycache__/ +src/*.egg-info diff --git a/.gitignore b/.gitignore index f400bd3f..5aabfd8c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,10 @@ -local.txt +/build/ .coverage /dist/ /docs/.build/ -/*.egg-info +/src/*.egg-info *.pyc .pytest_cache/ _scratch/ Session.vim /.tox/ -/build/ diff --git a/.projections.json b/.projections.json new file mode 100644 index 00000000..7d68dd4c --- /dev/null +++ b/.projections.json @@ -0,0 +1,14 @@ +{ + "src/docx/*.py" : { + "alternate" : [ + "tests/{dirname}/test_{basename}.py" + ], + "type" : "source" + }, + "tests/**/test_*.py" : { + "alternate" : [ + "src/docx/{dirname}/{basename}.py" + ], + "type" : "test" + } +} diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 9eafe51e..fd76890a 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -1,10 +1,19 @@ version: 2 +# -- set the OS, Python version and other tools you might need -- build: - os: "ubuntu-22.04" + os: ubuntu-22.04 tools: python: "3.12" +# -- build documentation in the "docs/" directory with Sphinx -- +sphinx: + configuration: docs/conf.py + # -- fail on all warnings to avoid broken references -- + # fail_on_warning: true + +# -- package versions required to build your documentation -- +# -- see https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html -- python: - install: - - requirements: docs/requirements.txt + install: + - requirements: requirements-docs.txt diff --git a/.rgignore b/.rgignore new file mode 100644 index 00000000..12d71b5b --- /dev/null +++ b/.rgignore @@ -0,0 +1,9 @@ +.tox +Session.vim +build/ +docs/.build +features/_scratch +__pycache__/ +ref/ +src/*.egg-info +tests/test_files diff --git a/.travis.yml b/.travis.yml index a64ba631..efb33c3b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: python python: - - "3.8" - - "3.9" - - "3.10" + - "3.12" +# command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors install: pip install -r requirements.txt -script: pytest +# command to run tests, e.g. python setup.py test +script: py.test diff --git a/HISTORY.md b/HISTORY.md index ce138268..12e34db8 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,10 @@ ## Release History +0.1.0 (2026-02-02) + +- UPSTREAM MERGE with python-docx 1.2.0. +- Backward Compatibility: Fixed a regression where `Font.name` returned a dictionary. It now correctly returns a string (ASCII name) while supporting multi-script assignment via setter. Added `Font.eastAsia` and `Font.hAnsi` properties for fine-grained font control. + 0.0.12 (2025-12-03) - default dpi for jpeg #33 diff --git a/MANIFEST.in b/MANIFEST.in index eb96f5e2..b2d3fadc 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,6 @@ -include HISTORY.md LICENSE README.md tox.ini -graft docx/templates +include HISTORY.rst LICENSE README.rst tox.ini +include requirements*.txt +graft src/docx/templates graft features graft tests graft docs diff --git a/Makefile b/Makefile index d1f057b3..2b2fb412 100644 --- a/Makefile +++ b/Makefile @@ -1,47 +1,64 @@ BEHAVE = behave MAKE = make PYTHON = python -TWINE = twine -SETUP = $(PYTHON) ./setup.py +TWINE = $(PYTHON) -m twine -.PHONY: accept clean coverage docs readme register build test upload +.PHONY: accept build clean cleandocs coverage docs install opendocs sdist test +.PHONY: test-upload wheel help: @echo "Please use \`make ' where is one or more of" - @echo " accept run acceptance tests using behave" - @echo " clean delete intermediate work product and start fresh" - @echo " cleandocs delete intermediate documentation files" - @echo " coverage run nosetests with coverage" - @echo " docs generate documentation" - @echo " opendocs open browser to local version of documentation" - @echo " register update metadata (README.rst) on PyPI" - @echo " build generate a source distribution into dist/" - @echo " upload upload distribution tarball to PyPI" + @echo " accept run acceptance tests using behave" + @echo " build generate both sdist and wheel suitable for upload to PyPI" + @echo " clean delete intermediate work product and start fresh" + @echo " cleandocs delete intermediate documentation files" + @echo " coverage run pytest with coverage" + @echo " docs generate documentation" + @echo " opendocs open browser to local version of documentation" + @echo " register update metadata (README.rst) on PyPI" + @echo " sdist generate a source distribution into dist/" + @echo " test run unit tests using pytest" + @echo " test-upload upload distribution to TestPyPI" + @echo " upload upload distribution tarball to PyPI" + @echo " wheel generate a binary distribution into dist/" accept: - $(BEHAVE) --stop + uv run $(BEHAVE) --stop + +build: + uv build clean: - find . -type f -name \*.pyc -exec rm {} \; + # find . -type f -name \*.pyc -exec rm {} \; + fd -e pyc -I -x rm rm -rf dist *.egg-info .coverage .DS_Store cleandocs: $(MAKE) -C docs clean coverage: - pytest --cov-report term-missing --cov=docx tests/ + uv run pytest --cov-report term-missing --cov=docx tests/ docs: $(MAKE) -C docs html +install: + pip install -Ue . + opendocs: open docs/.build/html/index.html -register: - $(SETUP) register +sdist: + uv build --sdist -build: - $(SETUP) sdist +test: + uv run pytest -x + +test-upload: sdist wheel + uv run $(TWINE) upload --repository testpypi dist/* + +upload: clean sdist wheel + uv run $(TWINE) upload dist/* -upload: - $(TWINE) upload dist/* +wheel: + uv build --wheel diff --git a/README.md b/README.md index 07c2356b..d554149b 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ _As a Brazilian jiu-jitsu player, OSS means anything and everything. It's a term

    PyPI - Code style: black + Code style: ruff License: MIT

    diff --git a/docs/_static/img/comment-parts.png b/docs/_static/img/comment-parts.png new file mode 100644 index 0000000000000000000000000000000000000000..c7db1be54bbbb04abf5286053f9aaea94c26eab9 GIT binary patch literal 30058 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 PY)xeab@|fA#sU8aWL~ea literal 0 HcmV?d00001 diff --git a/docs/api/comments.rst b/docs/api/comments.rst new file mode 100644 index 00000000..a54ecc9c --- /dev/null +++ b/docs/api/comments.rst @@ -0,0 +1,27 @@ + +.. _comments_api: + +Comment-related objects +======================= + +.. currentmodule:: docx.comments + + +|Comments| objects +------------------ + +.. autoclass:: Comments() + :members: + :inherited-members: + :exclude-members: + part + + +|Comment| objects +------------------ + +.. autoclass:: Comment() + :members: + :inherited-members: + :exclude-members: + part diff --git a/docs/conf.py b/docs/conf.py index 07819c16..d97fbacc 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -155,6 +155,18 @@ .. |True| replace:: :class:`True` .. |ValueError| replace:: :class:`ValueError` + +.. |CharacterStyle| replace:: :class:`.CharacterStyle` + +.. |Comment| replace:: :class:`.Comment` + +.. |Comments| replace:: :class:`.Comments` + +.. |Hyperlink| replace:: :class:`.Hyperlink` + +.. |ParagraphStyle| replace:: :class:`.ParagraphStyle` + +.. |RenderedPageBreak| replace:: :class:`.RenderedPageBreak` """ # -- General configuration --------------------------------------------------- diff --git a/docs/dev/analysis/features/comments.rst b/docs/dev/analysis/features/comments.rst new file mode 100644 index 00000000..1988c106 --- /dev/null +++ b/docs/dev/analysis/features/comments.rst @@ -0,0 +1,419 @@ + +Comments +======== + +Word allows *comments* to be added to a document. This is an aspect of the *reviewing* +feature-set and is typically used by a second party to provide feedback to the author +without changing the document itself. + +The procedure is simple: + +- You select some range of text with the mouse or Shift+Arrow keys +- You press the *New Comment* button (Review toolbar) +- You type or paste in your comment + +.. image:: /_static/img/comment-parts.png + +**Comment Anatomy.** Each comment has two parts, the *comment-reference* and the +*comment-content*: + +The *comment-refererence*, sometimes *comment-anchor*, is the text you selected before +pressing the *New Comment* button. It is a *range* in the document content delimited by +a start marker and an end marker, and containing the *id* of the comment that refers to +it. + +The *comment-content* is whatever content you typed or pasted in. The content for each +comment is stored in the separate *comments-part* (part-name ``word/comments.xml``) as a +distinct comment object. Each comment has a unique id, allowing a comment reference to +be associated with its content and vice versa. + +**Comment Reference.** The comment-reference is a *range*. A range must both start and +end at an even *run* boundary. Intuitively, a range corresponds to a *selection* of text +in the Word UI, one formed by dragging with the mouse or using the *Shift-Arrow* keys. + +In general a range can span "run containers", such as paragraphs, such that the range +begins in one paragraph and ends in a later paragraph. However, a range must enclose +*contiguous* runs, such that a range that contains only two vertically adjacent cells in +a multi-column table is not possible (even though such a selection with the mouse is +possible). + +**Comment Content.** Interestingly, although commonly used to contain a single line of +plain text, the comment-content can contain essentially any content that can appear in +the document body. This includes rich text with emphasis, runs with a different typeface +and size, both paragraph and character styles, hyperlinks, images, and tables. Note that +tables do not appear in the comment as displayed in the *comment-sidebar* although they +do apper in the *reviewing-pane*. + +**Comment Metadata.** Each comment can be assigned *author*, *initals*, and *date* +metadata. In Word, these fields are assigned automatically based on values in ``Settings +> User`` of the installed Word application. These may be configured automatically in an +enterprise installation, based on the user account, but by default they are empty. + +*author* metadata is required, although silently assigned the empty string by Word if +the user name is not configured. *initials* is optional, but always set by Word, to the +empty string if not configured. *date* is also optional, but always set by Word to the +date and time the comment was added (seconds resolution, UTC). + +**Additional Features.** Later versions of Word allow a comment to be *resolved*. A +comment in this state will appear grayed-out in the Word UI. Later versions of Word also +allow a comment to be *replied to*, forming a *comment thread*. Neither of these +features is supported by the initial implementation of comments in *python-docx*. + +The resolved-status and replies features are implemented as *extensions* and involve two +additional comment-related parts: + +- `commentsExtended.xml` - contains completion (resolved) status and parent-id for + threading comment responses; keys to `w15:paraId` of comment paragraph in + `comments.xml` +- `commentsIds.xml` - maps `w16cid:paraId` to `w16cid:durableId`, not sure what that is + exactly. + +**Applicability.** Note that comments cannot be added to a header or footer and cannot +be nested inside a comment itself. In general the *python-docx* API will not allow these +operations but if you outsmart it then the resulting comment will either be silently +removed or trigger a repair error when the document is loaded by Word. + + +Word Behavior +------------- + +- A DOCX package does not contain a ``comments.xml`` part by default. It is added to the + package when the first comment is added to the document. + +- A newly-created comment contains a single paragraph + +- Word starts `w:id` at 0 and increments from there. It appears to use a + `max(comment_ids) + 1` algorithm rather than aggressively filling in id numbering + gaps. + +- Word-behavior: looks like Word doesn't allow a "zero-length" comment reference; if you + insert a comment when no text is selected, the word prior to the insertion-point is + selected. + +- Word allows a comment to be applied to a range that starts before any character and + ends after any later character. However, the XML range-markers can only be placed + between runs. Word accommodates this be breaking runs as necessary to start and stop + at the desired character positions. + + +MS API +------ + +.. highlight:: python + +**Document**:: + + Document.Comments + +**Comments** + +https://learn.microsoft.com/en-us/office/vba/api/word.comments:: + + Comments.Add(Range, Text) -> Comment + + # -- retrieve comment by array idx, not comment_id key -- + Comments.Item(idx: Long) -> Comment + + Comments.Count() -> Long + + # -- restrict visible comments to those by a particular reviewer + Comments.ShowBy = "Travis McGuillicuddy" + +**Comment** + +https://learn.microsoft.com/en-us/office/vba/api/word.comment:: + + # -- delete comment and all replies to it -- + Comment.DeleteRecursively() -> void + + # -- open OLE object embedded in comment for editing -- + Comment.Edit() -> void + + # -- get the "parent" comment when this comment is a reply -- + Comment.Ancestor() -> Comment | Nothing + + # -- author of this comment, with email and name fields -- + Comment.Contact -> CoAuthor + + Comment.Date -> Date + Comment.Done -> bool + Comment.IsInk -> bool + + # -- content of the comment, contrast with `Reference` below -- + Comment.Range -> Range + + # -- content within document this comment refers to -- + Comment.Reference -> Range + + Comment.Replies -> Comments + + # -- described in API docs like the same thing as `Reference` -- + Comment.Scope -> Range + + +Candidate Protocol +------------------ + +.. highlight:: python + +The critical required reference for adding a comment is the *range* referred to by the +comment; i.e. the "selection" of text that is being commented on. Because this range +must start and end at an even run boundary, it is enough to specify the first and last +run in the range, where a single run can be both the start and end run:: + + >>> paragraph = document.add_paragraph("Hello, world!") + >>> document.add_comment( + ... runs=paragraph.runs, + ... text="I have this to say about that" + ... author="Ethan St. Lee", + ... initials="SC", + ... ) + + +A single run can be provided when that is more convenient:: + + >>> paragraph = document.add_paragraph("Summary: ") + >>> run = paragraph.add_run("{{place-summary-here}} + >>> document.add_comment( + ... run, text="The AI model will replace this placeholder with a summary" + ... ) + + +Note that `author` and `initials` are optional parameters; both default to the empty +string. + +`text` is also an optional parameter and also defaults to the empty string. Omitting a +`text` argument (or passing `text=""`) produces a comment containing a single paragraph +you can immediately add runs to and add additional paragraphs after: + + >>> paragraph = document.add_paragraph("Summary: ") + >>> run = paragraph.add_run("{{place-summary-here}}") + >>> comment = document.add_comment(run) + >>> paragraph = comment.paragraphs[0] + >>> paragraph.add_run("The ") + >>> paragraph.add_run("AI model").bold = True + >>> paragraph.add_run(" will replace this placeholder with a ") + >>> paragraph.add_run("summary").bold = True + + +A method directly on |Run| may also be convenient, since you will always have the first +run of the range in hand when adding a comment but may not have ready access to the +``document`` object:: + + >>> runs = find_sequence_of_one_or_more_runs_to_comment_on() + >>> runs[0].add_comment( + ... last_run=runs[-1], + ... text="The AI model will replace this placeholder with a summary", + ... ) + + +However, in this situation we would need to qualify the runs as being inside the +document part and not in a header or footer or comment, and perhaps other invalid +comment locations. I believe comments can be applied to footnotes and endnotes though. + + +Specimen XML +------------ + +.. highlight:: xml + +``comments.xml`` (namespace declarations may vary):: + + + + > + + + + + + + + + + I have this to say about that + + + + + + +Comment reference in document body:: + + + + + Hello, world! + + + + + + + + + + + +**Notes** + +- `w:comment` is a *block-item* container, and can contain any content that can appear + in a document body or table cell, including both paragraphs and tables (and whatever + can go inside those, like images, hyperlinks, etc. + +- Word places the `w:annotationRef`-containing run as the first run in the first + paragraph of the comment. I haven't been able to detect any behavior change caused by + leaving this out or placing it elsewhere in the comment content. + +- Relationships referenced from within `w:comment` content are relationships *from the + comments part* to the image part, hyperlink, etc. + +- `w:commentRangeStart` and `w:commentRangeEnd` elements are *optional*. The + authoritative position of the comment is the required `w:commentReference` element. + This means the *ending* location of a comment anchor can be efficiently found using + XPath. + + +Schema Excerpt +-------------- + +**Notes:** + +- `commentRangeStart` and `commentRangeEnd` are both type `CT_MarkupRange` and both + belong to `EG_RunLevelElts` (peers of `w:r`) which gives them their positioning in the + document structure. + +- These two markers can occur at the *block* level, at the *run* level, or at the *table + row* or *cell* level. However Word only seems to use them as peers of `w:r`. These can + occur as a sibling to: + + - a *paragraph* (`w:p`) + - a *table* (`w:tbl`) + - a *run* (`w:r`) + - a *table row* (`w:tr`) + - a *table cell* (`w:tc`) + +.. code-block:: xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/dev/analysis/features/coreprops.rst b/docs/dev/analysis/features/coreprops.rst index 0bc4ac32..45dc4d78 100644 --- a/docs/dev/analysis/features/coreprops.rst +++ b/docs/dev/analysis/features/coreprops.rst @@ -115,7 +115,7 @@ core.xml produced by Microsoft Word:: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> Core Document Properties Exploration PowerPoint core document properties - Steve Canny + Ethan St. Lee powerpoint; open xml; dublin core; microsoft office One thing I'd like to discover is just how line wrapping is handled @@ -123,7 +123,7 @@ core.xml produced by Microsoft Word:: line._x000d__x000d_This is a second paragraph separated from the first by two line feeds. - Steve Canny + Ethan St. Lee 2 2013-04-06T06:03:36Z 2013-06-15T06:09:18Z diff --git a/docs/dev/analysis/features/text/hyperlink.rst b/docs/dev/analysis/features/text/hyperlink.rst new file mode 100644 index 00000000..cfd451fe --- /dev/null +++ b/docs/dev/analysis/features/text/hyperlink.rst @@ -0,0 +1,383 @@ + +Hyperlink +========= + +Word allows a hyperlink to be placed in a document wherever a paragraph can appear. The +actual hyperlink element is a peer of |Run|. + +The link may be to an external resource such as a web site, or internal, to another +location in the document. The link may also be a `mailto:` URI or a reference to a file +on an accessible local or network filesystem. + +The visible text of a hyperlink is held in one or more runs. Technically a hyperlink can +have zero runs, but this occurs only in contrived cases (otherwise there would be +nothing to click on). As usual, each run can have its own distinct text formatting +(font), so for example one word in the hyperlink can be bold, etc. By default, Word +applies the built-in `Hyperlink` character style to a newly inserted hyperlink. Like +other text, the hyperlink text may often be broken into multiple runs as a result of +edits in different "revision-save" editing sessions (between "Save" commands). + +Note that rendered page-breaks can occur in the middle of a hyperlink. + +A |Hyperlink| is a child of |Paragraph|, a peer of |Run|. + + +TODO: What about URL-encoding/decoding (like %20) behaviors, if any? + + +Candidate protocol +------------------ + +An external hyperlink has an address and an optional anchor. An internal hyperlink has +only an anchor. An anchor is more precisely known as a *URI fragment* in a web URL and +follows a hash mark ("#"). The fragment-separator hash character is not stored in the +XML. + +Note that the anchor and address are stored in two distinct attributes, so you need to +concatenate `.address` and `.anchor` like `f"{address}#{anchor}"` if you want the whole +thing. + +Also note that Word does not rigorously separate a fragment in a web URI so it may +appear as part of the address or separately in the anchor attribute, depending on how +the hyperlink was authored. Hyperlinks inserted using the dialog-box seem to separate it +and addresses typed into the document directly don't, based on my limited experience. + +.. highlight:: python + +**Access hyperlinks in a paragraph**:: + + >>> hyperlinks = paragraph.hyperlinks + [] + +**Access hyperlinks in a paragraph in document order with runs**:: + + >>> list(paragraph.iter_inner_content()) + [ + + + + ] + +**Access hyperlink address**:: + + >>> hyperlink.address + 'https://google.com/' + +**Access hyperlink fragment**:: + + >>> hyperlink.fragment + 'introduction' + +**Access hyperlink history (visited or not, True means not visited yet)**:: + + >>> hyperlink.history + True + +**Access hyperlinks runs**:: + + >>> hyperlink.runs + [ + + + + ] + +**Access hyperlink URL**:: + + >>> hyperlink.url + 'https://us.com#introduction' + +**Determine whether a hyperlink contains a rendered page-break**:: + + >>> hyperlink.contains_page_break + False + +**Access visible text of a hyperlink**:: + + >>> hyperlink.text + 'an excellent Wikipedia article on ferrets' + +**Add an external hyperlink** (not yet implemented):: + + >>> hyperlink = paragraph.add_hyperlink( + ... 'About', address='http://us.com', fragment='about' + ... ) + >>> hyperlink + + >>> hyperlink.text + 'About' + >>> hyperlink.address + 'http://us.com' + >>> hyperlink.fragment + 'about' + >>> hyperlink.url + 'http://us.com#about' + +**Add an internal hyperlink (to a bookmark)**:: + + >>> hyperlink = paragraph.add_hyperlink('Section 1', fragment='Section_1') + >>> hyperlink.text + 'Section 1' + >>> hyperlink.fragment + 'Section_1' + >>> hyperlink.address + '' + +**Modify hyperlink properties**:: + + >>> hyperlink.text = 'Froogle' + >>> hyperlink.text + 'Froogle' + >>> hyperlink.address = 'mailto:info@froogle.com?subject=sup dawg?' + >>> hyperlink.address + 'mailto:info@froogle.com?subject=sup%20dawg%3F' + >>> hyperlink.anchor = None + >>> hyperlink.anchor + None + +**Add additional runs to a hyperlink**:: + + >>> hyperlink.text = 'A ' + >>> # .insert_run inserts a new run at idx, defaults to idx=-1 + >>> hyperlink.insert_run(' link').bold = True + >>> hyperlink.insert_run('formatted', idx=1).bold = True + >>> hyperlink.text + 'A formatted link' + >>> [r for r in hyperlink.iter_runs()] + [, + , + ] + +**Iterate over the run-level items a paragraph contains**:: + + >>> paragraph = document.add_paragraph('A paragraph having a link to: ') + >>> paragraph.add_hyperlink(text='github', address='http://github.com') + >>> [item for item in paragraph.iter_run_level_items()]: + [, ] + +**Paragraph.text now includes text contained in a hyperlink**:: + + >>> paragraph.text + 'A paragraph having a link to: github' + + +Word Behaviors +-------------- + +* What are the semantics of the w:history attribute on w:hyperlink? I'm + suspecting this indicates whether the link should show up blue (unvisited) + or purple (visited). I'm inclined to think we need that as a read/write + property on hyperlink. We should see what the MS API does on this count. + +* We probably need to enforce some character-set restrictions on w:anchor. + Word doesn't seem to like spaces or hyphens, for example. The simple type + ST_String doesn't look like it takes care of this. + +* We'll need to test URL escaping of special characters like spaces and + question marks in Hyperlink.address. + +* What does Word do when loading a document containing an internal hyperlink + having an anchor value that doesn't match an existing bookmark? We'll want + to know because we're sure to get support inquiries from folks who don't + match those up and wonder why they get a repair error or whatever. + + +Specimen XML +------------ + +.. highlight:: xml + + +External links +~~~~~~~~~~~~~~ + +The address (URL) of an external hyperlink is stored in the document.xml.rels +file, keyed by the w:hyperlink@r:id attribute:: + + + + This is an external link to + + + + + + + Google + + + + +... mapping to relationship in document.xml.rels:: + + + + + +A hyperlink can contain multiple runs of text (and a whole lot of other stuff, at least +as far as the schema indicates):: + + + + + + + + A hyperlink containing an + + + + + + + italicized + + + + + + word + + + + + +Internal links +~~~~~~~~~~~~~~ + +An internal link provides "jump to another document location" behavior in the +Word UI. An internal link is distinguished by the absence of an r:id +attribute. In this case, the w:anchor attribute is required. The value of the +anchor attribute is the name of a bookmark in the document. + +Example:: + + + + See + + + + + + + Section 4 + + + + for more details. + + + +... referring to this bookmark elsewhere in the document:: + + + + + Section 4 + + + + + +Schema excerpt +-------------- + +.. highlight:: xml + +:: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/dev/analysis/features/text/index.rst b/docs/dev/analysis/features/text/index.rst index 2fff0392..c87732c1 100644 --- a/docs/dev/analysis/features/text/index.rst +++ b/docs/dev/analysis/features/text/index.rst @@ -13,3 +13,4 @@ Text underline run-content breaks + hyperlink diff --git a/docs/dev/analysis/index.rst b/docs/dev/analysis/index.rst index b32bf5cc..425fa350 100644 --- a/docs/dev/analysis/index.rst +++ b/docs/dev/analysis/index.rst @@ -19,6 +19,7 @@ Feature Analysis features/coreprops features/numbering features/sections + features/comments Schema Analysis diff --git a/docs/index.rst b/docs/index.rst index 8382d0a9..a9d906cf 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -78,12 +78,14 @@ User Guide user/install user/quickstart user/documents + user/tables user/text user/sections user/hdrftr user/api-concepts user/styles-understanding user/styles-using + user/comments user/shapes user/custom-properties user/custom-xml @@ -101,6 +103,7 @@ API Documentation api/text api/table api/section + api/comments api/shape api/dml api/shared diff --git a/docs/user/comments.rst b/docs/user/comments.rst new file mode 100644 index 00000000..5c32b3b1 --- /dev/null +++ b/docs/user/comments.rst @@ -0,0 +1,168 @@ +.. _comments: + +Working with Comments +===================== + +Word allows *comments* to be added to a document. This is an aspect of the *reviewing* +feature-set and is typically used by a second party to provide feedback to the author +without changing the document itself. + +The procedure is simple: + +- You select some range of text with the mouse or Shift+Arrow keys +- You press the *New Comment* button (Review toolbar) +- You type or paste in your comment + +.. image:: /_static/img/comment-parts.png + +A comment can only be added to the main document. A comment cannot be added in a header, +a footer, or within a comment. A comment _can_ be added to a footnote or endnote, but +those are not yet supported by *python-docx*. + +**Comment Anatomy.** Each comment has two parts, the *comment-reference* and the +*comment-content*: + +The **comment-refererence**, sometimes *comment-anchor*, is the text in the main +document you selected before pressing the *New Comment* button. It is a so-called +*range* in the main document that starts at the first selected character and ends after +the last one. + +The **comment-content**, sometimes just *comment*, is whatever content you typed or +pasted in. The content for each comment is stored in a separate comment object, and +these comment objects are stored in a separate *comments-part* (part-name +``word/comments.xml``), not in the main document. Each comment is assigned a unique id +when it is created, allowing the comment reference to be associated with its content and +vice versa. + +**Comment Reference.** The comment-reference is a *range*. A range must both start and +end at an even *run* boundary. Intuitively, a range corresponds to a *selection* of text +in the Word UI, one formed by dragging with the mouse or using the *Shift-Arrow* keys. + +In the XML, this range is delimited by a start marker `` and an +end marker ``, both of which contain the *id* of the comment they +delimit. The start marker appears before the run starting with the first character of +the range and the end marker appears immediately after the run ending with the last +character of the range. Adding a comment that references an arbitrary range of text in +an existing document may require splitting runs on the desired character boundaries. + +In general a range can span paragraphs, such that the range begins in one paragraph and +ends in a later paragraph. However, a range must enclose *contiguous* runs, such that a +range that contains only two vertically adjacent cells in a multi-column table is not +possible (even though Word allows such a selection with the mouse). + +**Comment Content.** Interestingly, although commonly used to contain a single line of +plain text, the comment-content can contain essentially any content that can appear in +the document body. This includes rich text with emphasis, runs with a different typeface +and size, both paragraph and character styles, hyperlinks, images, and tables. Note that +tables do not appear in the comment as displayed in the *comment-sidebar* although they +do apper in the *reviewing-pane*. + +**Comment Metadata.** Each comment can be assigned *author*, *initals*, and *date* +metadata. In Word, these fields are assigned automatically based on values in ``Settings +> User`` of the installed Word application. These might be configured automatically in +an enterprise installation, based on the user account, but by default they are empty. + +*author* metadata is required, although silently assigned the empty string by Word if +the user name is not configured. *initials* is optional, but always set by Word, to the +empty string if not configured. *date* is also optional, but always set by Word to the +UTC date and time the comment was added, with seconds resolution (no milliseconds or +microseconds). + +**Additional Features.** Later versions of Word allow a comment to be *resolved*. A +comment in this state will appear grayed-out in the Word UI. Later versions of Word also +allow a comment to be *replied to*, forming a *comment thread*. Neither of these +features is supported by the initial implementation of comments in *python-docx*. + +**Applicability.** Note that comments cannot be added to a header or footer and cannot +be nested inside a comment itself. In general the *python-docx* API will not allow these +operations but if you outsmart it then the resulting comment will either be silently +removed or trigger a repair error when the document is loaded by Word. + + +Adding a Comment +---------------- + +A simple example is adding a comment to a paragraph:: + + >>> from docx import Document + >>> document = Document() + >>> paragraph = document.add_paragraph("Hello, world!") + + >>> comment = document.add_comment( + ... runs=paragraph.runs, + ... text="I have this to say about that" + ... author="Ethan St. Lee", + ... initials="SC", + ... ) + >>> comment + + >>> comment.id + 0 + >>> comment.author + 'Ethan St. Lee' + >>> comment.initials + 'SC' + >>> comment.date + datetime.datetime(2025, 6, 11, 20, 42, 30, 0, tzinfo=datetime.timezone.utc) + >>> comment.text + 'I have this to say about that' + +The API documentation for :meth:`.Document.add_comment` provides further details. + + +Accessing and using the Comments collection +------------------------------------------- + +The comments collection is accessed via the :attr:`.Document.comments` property:: + + >>> comments = document.comments + >>> comments + + >>> len(comments) + 1 + +The comments collection supports random access to a comment by its id:: + + >>> comment = comments.get(0) + >>> comment + + + +Adding rich content to a comment +-------------------------------- + +A comment is a block-item container, just like the document body or a table cell, so +it can contain any content that can appear in those places. It does not contain +page-layout sections and cannot contain a comment reference, but it can contain multiple +paragraphs and/or tables, and runs within paragraphs can have emphasis such as bold or +italic, and have images or hyperlinks. + +A comment created with `text=""` will contain a single paragraph with a single empty run +containing the so-called *annotation reference* but no text. It's probably best to leave +this run as it is but you can freely add additional runs to the paragraph that contain +whatever content you like. + +The methods for adding this content are the same as those used for the document and +table cells:: + + >>> paragraph = document.add_paragraph("The rain in Spain.") + >>> comment = document.add_comment( + ... runs=paragraph.runs, + ... text="", + ... ) + >>> cmt_para = comment.paragraphs[0] + >>> cmt_para.add_run("Please finish this thought. I believe it should be ") + >>> cmt_para.add_run("falls mainly in the plain.").bold = True + + +Updating comment metadata +------------------------- + +The author and initials metadata can be updated as desired:: + + >>> comment.author = "John Smith" + >>> comment.initials = "JS" + >>> comment.author + 'John Smith' + >>> comment.initials + 'JS' diff --git a/docs/user/install.rst b/docs/user/install.rst index 248ced71..c63da3d9 100644 --- a/docs/user/install.rst +++ b/docs/user/install.rst @@ -26,5 +26,5 @@ but if you use this last method you will need to install those yourself. Dependencies ------------ -* Python >= 3.10 +* Python >= 3.12 * lxml >= 4.6.5 diff --git a/docs/user/tables.rst b/docs/user/tables.rst new file mode 100644 index 00000000..40ef2093 --- /dev/null +++ b/docs/user/tables.rst @@ -0,0 +1,202 @@ +.. _tables: + +Working with Tables +=================== + +Word provides sophisticated capabilities to create tables. As usual, this power comes with +additional conceptual complexity. + +This complexity becomes most apparent when *reading* tables, in particular from documents drawn from +the wild where there is limited or no prior knowledge as to what the tables might contain or how +they might be structured. + +These are some of the important concepts you'll need to understand. + + +Concept: Simple (uniform) tables +-------------------------------- + +:: + + +---+---+---+ + | a | b | c | + +---+---+---+ + | d | e | f | + +---+---+---+ + | g | h | i | + +---+---+---+ + +The basic concept of a table is intuitive enough. You have *rows* and *columns*, and at each (row, +column) position is a different *cell*. It can be described as a *grid* or a *matrix*. Let's call +this concept a *uniform table*. A relational database table and a Pandas dataframe are both examples +of a uniform table. + +The following invariants apply to uniform tables: + +* Each row has the same number of cells, one for each column. +* Each column has the same number of cells, one for each row. + + +Complication 1: Merged Cells +---------------------------- + +:: + + +---+---+---+ +---+---+---+ + | a | b | | | b | c | + +---+---+---+ + a +---+---+ + | c | d | e | | | d | e | + +---+---+---+ +---+---+---+ + | f | g | h | | f | g | h | + +---+---+---+ +---+---+---+ + +While very suitable for data processing, a uniform table lacks expressive power desireable for +tables intended for a human reader. + +Perhaps the most important characteristic a uniform table lacks is *merged cells*. It is very common +to want to group multiple cells into one, for example to form a column-group heading or provide the +same value for a sequence of cells rather than repeat it for each cell. These make a rendered table +more *readable* by reducing the cognitive load on the human reader and make certain relationships +explicit that might easily be missed otherwise. + +Unfortunately, accommodating merged cells breaks both the invariants of a uniform table: + +* Each row can have a different number of cells. +* Each column can have a different number of cells. + +This challenges reading table contents programatically. One might naturally want to read the table +into a uniform matrix data structure like a 3 x 3 "2D array" (list of lists perhaps), but this is +not directly possible when the table is not known to be uniform. + + +Concept: The layout grid +------------------------ + +:: + + + - + - + - + + | | | | + + - + - + - + + | | | | + + - + - + - + + | | | | + + - + - + - + + +In Word, each table has a *layout grid*. + +- The layout grid is *uniform*. There is a layout position for every (layout-row, layout-column) + pair. +- The layout grid itself is not visible. However it is represented and referenced by certain + elements and attributes within the table XML +- Each table cell is located at a layout-grid position; i.e. the top-left corner of each cell is the + top-left corner of a layout-grid cell. +- Each table cell occupies one or more whole layout-grid cells. A merged cell will occupy multiple + layout-grid cells. No table cell can occupy a partial layout-grid cell. +- Another way of saying this is that every vertical boundary (left and right) of a cell aligns with + a layout-grid vertical boundary, likewise for horizontal boundaries. But not all layout-grid + boundaries need be occupied by a cell boundary of the table. + + +Complication 2: Omitted Cells +----------------------------- + +:: + + +---+---+ +---+---+---+ + | a | b | | a | b | c | + +---+---+---+ +---+---+---+ + | c | d | | d | + +---+---+ +---+---+---+ + | e | | e | f | g | + +---+ +---+---+---+ + +Word is unusual in that it allows cells to be omitted from the beginning or end (but not the middle) +of a row. A typical practical example is a table with both a row of column headings and a column of +row headings, but no top-left cell (position 0, 0), such as this XOR truth table. + +:: + + +---+---+ + | T | F | + +---+---+---+ + | T | F | T | + +---+---+---+ + | F | T | F | + +---+---+---+ + +In `python-docx`, omitted cells in a |_Row| object are represented by the ``.grid_cols_before`` and +``.grid_cols_after`` properties. In the example above, for the first row, ``.grid_cols_before`` +would equal ``1`` and ``.grid_cols_after`` would equal ``0``. + +Note that omitted cells are not just "empty" cells. They represent layout-grid positions that are +unoccupied by a cell and they cannot be represented by a |_Cell| object. This distinction becomes +important when trying to produce a uniform representation (e.g. a 2D array) for an arbitrary Word +table. + + +Concept: `python-docx` approximates uniform tables by default +------------------------------------------------------------- + +To accurately represent an arbitrary table would require a complex graph data structure. Navigating +this data structure would be at least as complex as navigating the `python-docx` object graph for a +table. When extracting content from a collection of arbitrary Word files, such as for indexing the +document, it is common to choose a simpler data structure and *approximate* the table in that +structure. + +Reflecting on how a relational table or dataframe represents tabular information, a straightforward +approximation would simply repeat merged-cell values for each layout-grid cell occupied by the +merged cell:: + + + +---+---+---+ +---+---+---+ + | a | b | -> | a | a | b | + +---+---+---+ +---+---+---+ + | | d | e | -> | c | d | e | + + c +---+---+ +---+---+---+ + | | f | g | -> | c | f | g | + +---+---+---+ +---+---+---+ + +This is what ``_Row.cells`` does by default. Conceptually:: + + >>> [tuple(c.text for c in r.cells) for r in table.rows] + [ + (a, a, b), + (c, d, e), + (c, f, g), + ] + +Note this only produces a uniform "matrix" of cells when there are no omitted cells. Dealing with +omitted cells requires a more sophisticated approach when maintaining column integrity is required:: + + # +---+---+ + # | a | b | + # +---+---+---+ + # | c | d | + # +---+---+ + # | e | + # +---+ + + def iter_row_cell_texts(row: _Row) -> Iterator[str]: + for _ in range(row.grid_cols_before): + yield "" + for c in row.cells: + yield c.text + for _ in range(row.grid_cols_after): + yield "" + + >>> [tuple(iter_row_cell_texts(r)) for r in table.rows] + [ + ("", "a", "b"), + ("c", "d", ""), + ("", "e", ""), + ] + + +Complication 3: Tables are Recursive +------------------------------------ + +Further complicating table processing is their recursive nature. In Word, as in HTML, a table cell +can itself include one or more tables. + +These can be detected using ``_Cell.tables`` or ``_Cell.iter_inner_content()``. The latter preserves +the document order of the table with respect to paragraphs also in the cell. diff --git a/docx/api.py b/docx/api.py deleted file mode 100644 index 4cf6acd1..00000000 --- a/docx/api.py +++ /dev/null @@ -1,37 +0,0 @@ -# encoding: utf-8 - -""" -Directly exposed API functions and classes, :func:`Document` for now. -Provides a syntactically more convenient API for interacting with the -OpcPackage graph. -""" - -from __future__ import absolute_import, division, print_function - -import os - -from docx.opc.constants import CONTENT_TYPE as CT -from docx.package import Package - - -def Document(docx=None): - """ - Return a |Document| object loaded from *docx*, where *docx* can be - either a path to a ``.docx`` file (a string) or a file-like object. If - *docx* is missing or ``None``, the built-in default document "template" - is loaded. - """ - docx = _default_docx_path() if docx is None else docx - document_part = Package.open(docx).main_document_part - if document_part.content_type != CT.WML_DOCUMENT_MAIN: - tmpl = "file '%s' is not a Word file, content type is '%s'" - raise ValueError(tmpl % (docx, document_part.content_type)) - return document_part.document - - -def _default_docx_path(): - """ - Return the path to the built-in default .docx package. - """ - _thisdir = os.path.split(__file__)[0] - return os.path.join(_thisdir, "templates", "default.docx") diff --git a/docx/blkcntnr.py b/docx/blkcntnr.py deleted file mode 100644 index b4d4d8b0..00000000 --- a/docx/blkcntnr.py +++ /dev/null @@ -1,77 +0,0 @@ -# encoding: utf-8 - -"""Block item container, used by body, cell, header, etc. - -Block level items are things like paragraph and table, although there are a few other -specialized ones like structured document tags. -""" - -from __future__ import absolute_import, division, print_function, unicode_literals - -from docx.oxml.table import CT_Tbl -from docx.shared import Parented -from docx.text.paragraph import Paragraph - - -class BlockItemContainer(Parented): - """Base class for proxy objects that can contain block items. - - These containers include _Body, _Cell, header, footer, footnote, endnote, comment, - and text box objects. Provides the shared functionality to add a block item like - a paragraph or table. - """ - - def __init__(self, element, parent): - super(BlockItemContainer, self).__init__(parent) - self._element = element - - def add_paragraph(self, text="", style=None): - """ - Return a paragraph newly added to the end of the content in this - container, having *text* in a single run if present, and having - paragraph style *style*. If *style* is |None|, no paragraph style is - applied, which has the same effect as applying the 'Normal' style. - """ - paragraph = self._add_paragraph() - if text: - paragraph.add_run(text) - if style is not None: - paragraph.style = style - return paragraph - - def add_table(self, rows, cols, width): - """ - Return a table of *width* having *rows* rows and *cols* columns, - newly appended to the content in this container. *width* is evenly - distributed between the table columns. - """ - from .table import Table - - tbl = CT_Tbl.new_tbl(rows, cols, width) - self._element._insert_tbl(tbl) - return Table(tbl, self) - - @property - def paragraphs(self): - """ - A list containing the paragraphs in this container, in document - order. Read-only. - """ - return [Paragraph(p, self) for p in self._element.p_lst] - - @property - def tables(self): - """ - A list containing the tables in this container, in document order. - Read-only. - """ - from .table import Table - - return [Table(tbl, self) for tbl in self._element.tbl_lst] - - def _add_paragraph(self): - """ - Return a paragraph newly added to the end of the content in this - container. - """ - return Paragraph(self._element.add_p(), self) diff --git a/docx/compat.py b/docx/compat.py deleted file mode 100644 index 1e3012d9..00000000 --- a/docx/compat.py +++ /dev/null @@ -1,39 +0,0 @@ -# encoding: utf-8 - -""" -Provides Python 2/3 compatibility objects -""" - -from __future__ import absolute_import, division, print_function, unicode_literals - -import sys - -# =========================================================================== -# Python 3 versions -# =========================================================================== - -if sys.version_info >= (3, 0): - - from collections.abc import Sequence - from io import BytesIO - - def is_string(obj): - """Return True if *obj* is a string, False otherwise.""" - return isinstance(obj, str) - - Unicode = str - -# =========================================================================== -# Python 2 versions -# =========================================================================== - -else: - - from collections import Sequence # noqa - from StringIO import StringIO as BytesIO # noqa - - def is_string(obj): - """Return True if *obj* is a string, False otherwise.""" - return isinstance(obj, basestring) # noqa - - Unicode = unicode # noqa diff --git a/docx/dml/color.py b/docx/dml/color.py deleted file mode 100644 index cfdf097a..00000000 --- a/docx/dml/color.py +++ /dev/null @@ -1,114 +0,0 @@ -# encoding: utf-8 - -""" -DrawingML objects related to color, ColorFormat being the most prominent. -""" - -from __future__ import absolute_import, division, print_function, unicode_literals - -from ..enum.dml import MSO_COLOR_TYPE -from ..oxml.simpletypes import ST_HexColorAuto -from ..shared import ElementProxy - - -class ColorFormat(ElementProxy): - """ - Provides access to color settings such as RGB color, theme color, and - luminance adjustments. - """ - - __slots__ = () - - def __init__(self, rPr_parent): - super(ColorFormat, self).__init__(rPr_parent) - - @property - def rgb(self): - """ - An |RGBColor| value or |None| if no RGB color is specified. - - When :attr:`type` is `MSO_COLOR_TYPE.RGB`, the value of this property - will always be an |RGBColor| value. It may also be an |RGBColor| - value if :attr:`type` is `MSO_COLOR_TYPE.THEME`, as Word writes the - current value of a theme color when one is assigned. In that case, - the RGB value should be interpreted as no more than a good guess - however, as the theme color takes precedence at rendering time. Its - value is |None| whenever :attr:`type` is either |None| or - `MSO_COLOR_TYPE.AUTO`. - - Assigning an |RGBColor| value causes :attr:`type` to become - `MSO_COLOR_TYPE.RGB` and any theme color is removed. Assigning |None| - causes any color to be removed such that the effective color is - inherited from the style hierarchy. - """ - color = self._color - if color is None: - return None - if color.val == ST_HexColorAuto.AUTO: - return None - return color.val - - @rgb.setter - def rgb(self, value): - if value is None and self._color is None: - return - rPr = self._element.get_or_add_rPr() - rPr._remove_color() - if value is not None: - rPr.get_or_add_color().val = value - - @property - def theme_color(self): - """ - A member of :ref:`MsoThemeColorIndex` or |None| if no theme color is - specified. When :attr:`type` is `MSO_COLOR_TYPE.THEME`, the value of - this property will always be a member of :ref:`MsoThemeColorIndex`. - When :attr:`type` has any other value, the value of this property is - |None|. - - Assigning a member of :ref:`MsoThemeColorIndex` causes :attr:`type` - to become `MSO_COLOR_TYPE.THEME`. Any existing RGB value is retained - but ignored by Word. Assigning |None| causes any color specification - to be removed such that the effective color is inherited from the - style hierarchy. - """ - color = self._color - if color is None or color.themeColor is None: - return None - return color.themeColor - - @theme_color.setter - def theme_color(self, value): - if value is None: - if self._color is not None: - self._element.rPr._remove_color() - return - self._element.get_or_add_rPr().get_or_add_color().themeColor = value - - @property - def type(self): - """ - Read-only. A member of :ref:`MsoColorType`, one of RGB, THEME, or - AUTO, corresponding to the way this color is defined. Its value is - |None| if no color is applied at this level, which causes the - effective color to be inherited from the style hierarchy. - """ - color = self._color - if color is None: - return None - if color.themeColor is not None: - return MSO_COLOR_TYPE.THEME - if color.val == ST_HexColorAuto.AUTO: - return MSO_COLOR_TYPE.AUTO - return MSO_COLOR_TYPE.RGB - - @property - def _color(self): - """ - Return `w:rPr/w:color` or |None| if not present. Helper to factor out - repetitive element access. - """ - rPr = self._element.rPr - if rPr is None: - return None - return rPr.color diff --git a/docx/document.py b/docx/document.py deleted file mode 100644 index aeb3370b..00000000 --- a/docx/document.py +++ /dev/null @@ -1,214 +0,0 @@ -"""|Document| and closely related objects""" -from docx.blkcntnr import BlockItemContainer -from docx.enum.section import WD_SECTION -from docx.enum.text import WD_BREAK -from docx.section import Section, Sections -from docx.shared import ElementProxy, Emu - - -class Document(ElementProxy): - """WordprocessingML (WML) document. - - Not intended to be constructed directly. Use :func:`docx.Document` to open or create - a document. - """ - - __slots__ = ("_part", "__body") - - def __init__(self, element, part): - super(Document, self).__init__(element) - self._part = part - self.__body = None - - def add_heading(self, text="", level=1): - """Return a heading paragraph newly added to the end of the document. - - The heading paragraph will contain *text* and have its paragraph style - determined by *level*. If *level* is 0, the style is set to `Title`. If *level* - is 1 (or omitted), `Heading 1` is used. Otherwise the style is set to `Heading - {level}`. Raises |ValueError| if *level* is outside the range 0-9. - """ - if not 0 <= level <= 9: - raise ValueError("level must be in range 0-9, got %d" % level) - style = "Title" if level == 0 else "Heading %d" % level - return self.add_paragraph(text, style) - - def add_page_break(self): - """Return newly |Paragraph| object containing only a page break.""" - paragraph = self.add_paragraph() - paragraph.add_run().add_break(WD_BREAK.PAGE) - return paragraph - - def add_paragraph(self, text="", style=None): - """ - Return a paragraph newly added to the end of the document, populated - with *text* and having paragraph style *style*. *text* can contain - tab (``\\t``) characters, which are converted to the appropriate XML - form for a tab. *text* can also include newline (``\\n``) or carriage - return (``\\r``) characters, each of which is converted to a line - break. - """ - return self._body.add_paragraph(text, style) - - def add_picture(self, image_path_or_stream, width=None, height=None): - """ - Return a new picture shape added in its own paragraph at the end of - the document. The picture contains the image at - *image_path_or_stream*, scaled based on *width* and *height*. If - neither width nor height is specified, the picture appears at its - native size. If only one is specified, it is used to compute - a scaling factor that is then applied to the unspecified dimension, - preserving the aspect ratio of the image. The native size of the - picture is calculated using the dots-per-inch (dpi) value specified - in the image file, defaulting to 72 dpi if no value is specified, as - is often the case. - """ - run = self.add_paragraph().add_run() - return run.add_picture(image_path_or_stream, width, height) - - def add_float_picture(self, image_path_or_stream, width=None, height=None, pos_x=0, pos_y=0): - """ - Add float picture at fixed position `pos_x` and `pos_y` to the top-left point of page. - """ - run = self.add_paragraph().add_run() - return run.add_float_picture(image_path_or_stream, width, height, pos_x, pos_y) - - def add_section(self, start_type=WD_SECTION.NEW_PAGE): - """ - Return a |Section| object representing a new section added at the end - of the document. The optional *start_type* argument must be a member - of the :ref:`WdSectionStart` enumeration, and defaults to - ``WD_SECTION.NEW_PAGE`` if not provided. - """ - new_sectPr = self._element.body.add_section_break() - new_sectPr.start_type = start_type - return Section(new_sectPr, self._part) - - def add_table(self, rows, cols, style=None): - """ - Add a table having row and column counts of *rows* and *cols* - respectively and table style of *style*. *style* may be a paragraph - style object or a paragraph style name. If *style* is |None|, the - table inherits the default table style of the document. - """ - table = self._body.add_table(rows, cols, self._block_width) - table.style = style - return table - - @property - def core_properties(self): - """ - A |CoreProperties| object providing read/write access to the core - properties of this document. - """ - return self._part.core_properties - - @property - def custom_properties(self): - """ - A |CustomProperties| object providing read/write access to the custom - properties of this document. - """ - return self._part.custom_properties - - @property - def inline_shapes(self): - """ - An |InlineShapes| object providing access to the inline shapes in - this document. An inline shape is a graphical object, such as - a picture, contained in a run of text and behaving like a character - glyph, being flowed like other text in a paragraph. - """ - return self._part.inline_shapes - - @property - def paragraphs(self): - """ - A list of |Paragraph| instances corresponding to the paragraphs in - the document, in document order. Note that paragraphs within revision - marks such as ```` or ```` do not appear in this list. - """ - return self._body.paragraphs - - @property - def part(self): - """ - The |DocumentPart| object of this document. - """ - return self._part - - def save(self, path_or_stream): - """ - Save this document to *path_or_stream*, which can be either a path to - a filesystem location (a string) or a file-like object. - """ - self._part.save(path_or_stream) - - @property - def sections(self): - """|Sections| object providing access to each section in this document.""" - return Sections(self._element, self._part) - - @property - def settings(self): - """ - A |Settings| object providing access to the document-level settings - for this document. - """ - return self._part.settings - - @property - def styles(self): - """ - A |Styles| object providing access to the styles in this document. - """ - return self._part.styles - - @property - def tables(self): - """ - A list of |Table| instances corresponding to the tables in the - document, in document order. Note that only tables appearing at the - top level of the document appear in this list; a table nested inside - a table cell does not appear. A table within revision marks such as - ```` or ```` will also not appear in the list. - """ - return self._body.tables - - @property - def _block_width(self): - """ - Return a |Length| object specifying the width of available "writing" - space between the margins of the last section of this document. - """ - section = self.sections[-1] - return Emu(section.page_width - section.left_margin - section.right_margin) - - @property - def _body(self): - """ - The |_Body| instance containing the content for this document. - """ - if self.__body is None: - self.__body = _Body(self._element.body, self) - return self.__body - - -class _Body(BlockItemContainer): - """ - Proxy for ```` element in this document, having primarily a - container role. - """ - - def __init__(self, body_elm, parent): - super(_Body, self).__init__(body_elm, parent) - self._body = body_elm - - def clear_content(self): - """ - Return this |_Body| instance after clearing it of all content. - Section properties for the main document story, if present, are - preserved. - """ - self._body.clear_content() - return self diff --git a/docx/enum/__init__.py b/docx/enum/__init__.py deleted file mode 100644 index e1bbd47f..00000000 --- a/docx/enum/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# encoding: utf-8 - -""" -Enumerations used in python-docx -""" - -from __future__ import absolute_import, print_function, unicode_literals - - -class Enumeration(object): - @classmethod - def from_xml(cls, xml_val): - return cls._xml_to_idx[xml_val] - - @classmethod - def to_xml(cls, enum_val): - return cls._idx_to_xml[enum_val] diff --git a/docx/enum/base.py b/docx/enum/base.py deleted file mode 100644 index 0bcdbd6d..00000000 --- a/docx/enum/base.py +++ /dev/null @@ -1,371 +0,0 @@ -# encoding: utf-8 - -""" -Base classes and other objects used by enumerations -""" - -from __future__ import absolute_import, print_function - -import sys -import textwrap - -from ..exceptions import InvalidXmlError - - -def alias(*aliases): - """ - Decorating a class with @alias('FOO', 'BAR', ..) allows the class to - be referenced by each of the names provided as arguments. - """ - - def decorator(cls): - # alias must be set in globals from caller's frame - caller = sys._getframe(1) - globals_dict = caller.f_globals - for alias in aliases: - globals_dict[alias] = cls - return cls - - return decorator - - -class _DocsPageFormatter(object): - """Generate an .rst doc page for an enumeration. - - Formats a RestructuredText documention page (string) for the enumeration - class parts passed to the constructor. An immutable one-shot service - object. - """ - - def __init__(self, clsname, clsdict): - self._clsname = clsname - self._clsdict = clsdict - - @property - def page_str(self): - """ - The RestructuredText documentation page for the enumeration. This is - the only API member for the class. - """ - tmpl = ".. _%s:\n\n%s\n\n%s\n\n----\n\n%s" - components = ( - self._ms_name, - self._page_title, - self._intro_text, - self._member_defs, - ) - return tmpl % components - - @property - def _intro_text(self): - """Docstring of the enumeration, formatted for documentation page.""" - try: - cls_docstring = self._clsdict["__doc__"] - except KeyError: - cls_docstring = "" - - if cls_docstring is None: - return "" - - return textwrap.dedent(cls_docstring).strip() - - def _member_def(self, member): - """ - Return an individual member definition formatted as an RST glossary - entry, wrapped to fit within 78 columns. - """ - member_docstring = textwrap.dedent(member.docstring).strip() - member_docstring = textwrap.fill( - member_docstring, - width=78, - initial_indent=" " * 4, - subsequent_indent=" " * 4, - ) - return "%s\n%s\n" % (member.name, member_docstring) - - @property - def _member_defs(self): - """ - A single string containing the aggregated member definitions section - of the documentation page - """ - members = self._clsdict["__members__"] - member_defs = [ - self._member_def(member) for member in members if member.name is not None - ] - return "\n".join(member_defs) - - @property - def _ms_name(self): - """ - The Microsoft API name for this enumeration - """ - return self._clsdict["__ms_name__"] - - @property - def _page_title(self): - """ - The title for the documentation page, formatted as code (surrounded - in double-backtics) and underlined with '=' characters - """ - title_underscore = "=" * (len(self._clsname) + 4) - return "``%s``\n%s" % (self._clsname, title_underscore) - - -class MetaEnumeration(type): - """ - The metaclass for Enumeration and its subclasses. Adds a name for each - named member and compiles state needed by the enumeration class to - respond to other attribute gets - """ - - def __new__(meta, clsname, bases, clsdict): - meta._add_enum_members(clsdict) - meta._collect_valid_settings(clsdict) - meta._generate_docs_page(clsname, clsdict) - return type.__new__(meta, clsname, bases, clsdict) - - @classmethod - def _add_enum_members(meta, clsdict): - """ - Dispatch ``.add_to_enum()`` call to each member so it can do its - thing to properly add itself to the enumeration class. This - delegation allows member sub-classes to add specialized behaviors. - """ - enum_members = clsdict["__members__"] - for member in enum_members: - member.add_to_enum(clsdict) - - @classmethod - def _collect_valid_settings(meta, clsdict): - """ - Return a sequence containing the enumeration values that are valid - assignment values. Return-only values are excluded. - """ - enum_members = clsdict["__members__"] - valid_settings = [] - for member in enum_members: - valid_settings.extend(member.valid_settings) - clsdict["_valid_settings"] = valid_settings - - @classmethod - def _generate_docs_page(meta, clsname, clsdict): - """ - Return the RST documentation page for the enumeration. - """ - clsdict["__docs_rst__"] = _DocsPageFormatter(clsname, clsdict).page_str - - -class EnumerationBase(object): - """ - Base class for all enumerations, used directly for enumerations requiring - only basic behavior. It's __dict__ is used below in the Python 2+3 - compatible metaclass definition. - """ - - __members__ = () - __ms_name__ = "" - - @classmethod - def validate(cls, value): - """ - Raise |ValueError| if *value* is not an assignable value. - """ - if value not in cls._valid_settings: - raise ValueError( - "%s not a member of %s enumeration" % (value, cls.__name__) - ) - - -Enumeration = MetaEnumeration("Enumeration", (object,), dict(EnumerationBase.__dict__)) - - -class XmlEnumeration(Enumeration): - """ - Provides ``to_xml()`` and ``from_xml()`` methods in addition to base - enumeration features - """ - - __members__ = () - __ms_name__ = "" - - @classmethod - def from_xml(cls, xml_val): - """ - Return the enumeration member corresponding to the XML value - *xml_val*. - """ - if xml_val not in cls._xml_to_member: - raise InvalidXmlError( - "attribute value '%s' not valid for this type" % xml_val - ) - return cls._xml_to_member[xml_val] - - @classmethod - def to_xml(cls, enum_val): - """ - Return the XML value of the enumeration value *enum_val*. - """ - if enum_val not in cls._member_to_xml: - raise ValueError( - "value '%s' not in enumeration %s" % (enum_val, cls.__name__) - ) - return cls._member_to_xml[enum_val] - - -class EnumMember(object): - """ - Used in the enumeration class definition to define a member value and its - mappings - """ - - def __init__(self, name, value, docstring): - self._name = name - if isinstance(value, int): - value = EnumValue(name, value, docstring) - self._value = value - self._docstring = docstring - - def add_to_enum(self, clsdict): - """ - Add a name to *clsdict* for this member. - """ - self.register_name(clsdict) - - @property - def docstring(self): - """ - The description of this member - """ - return self._docstring - - @property - def name(self): - """ - The distinguishing name of this member within the enumeration class, - e.g. 'MIDDLE' for MSO_VERTICAL_ANCHOR.MIDDLE, if this is a named - member. Otherwise the primitive value such as |None|, |True| or - |False|. - """ - return self._name - - def register_name(self, clsdict): - """ - Add a member name to the class dict *clsdict* containing the value of - this member object. Where the name of this object is None, do - nothing; this allows out-of-band values to be defined without adding - a name to the class dict. - """ - if self.name is None: - return - clsdict[self.name] = self.value - - @property - def valid_settings(self): - """ - A sequence containing the values valid for assignment for this - member. May be zero, one, or more in number. - """ - return (self._value,) - - @property - def value(self): - """ - The enumeration value for this member, often an instance of - EnumValue, but may be a primitive value such as |None|. - """ - return self._value - - -class EnumValue(int): - """ - A named enumeration value, providing __str__ and __doc__ string values - for its symbolic name and description, respectively. Subclasses int, so - behaves as a regular int unless the strings are asked for. - """ - - def __new__(cls, member_name, int_value, docstring): - return super(EnumValue, cls).__new__(cls, int_value) - - def __init__(self, member_name, int_value, docstring): - super(EnumValue, self).__init__() - self._member_name = member_name - self._docstring = docstring - - @property - def __doc__(self): - """ - The description of this enumeration member - """ - return self._docstring.strip() - - def __str__(self): - """ - The symbolic name and string value of this member, e.g. 'MIDDLE (3)' - """ - return "%s (%d)" % (self._member_name, int(self)) - - -class ReturnValueOnlyEnumMember(EnumMember): - """ - Used to define a member of an enumeration that is only valid as a query - result and is not valid as a setting, e.g. MSO_VERTICAL_ANCHOR.MIXED (-2) - """ - - @property - def valid_settings(self): - """ - No settings are valid for a return-only value. - """ - return () - - -class XmlMappedEnumMember(EnumMember): - """ - Used to define a member whose value maps to an XML attribute value. - """ - - def __init__(self, name, value, xml_value, docstring): - super(XmlMappedEnumMember, self).__init__(name, value, docstring) - self._xml_value = xml_value - - def add_to_enum(self, clsdict): - """ - Compile XML mappings in addition to base add behavior. - """ - super(XmlMappedEnumMember, self).add_to_enum(clsdict) - self.register_xml_mapping(clsdict) - - def register_xml_mapping(self, clsdict): - """ - Add XML mappings to the enumeration class state for this member. - """ - member_to_xml = self._get_or_add_member_to_xml(clsdict) - member_to_xml[self.value] = self.xml_value - xml_to_member = self._get_or_add_xml_to_member(clsdict) - xml_to_member[self.xml_value] = self.value - - @property - def xml_value(self): - """ - The XML attribute value that corresponds to this enumeration value - """ - return self._xml_value - - @staticmethod - def _get_or_add_member_to_xml(clsdict): - """ - Add the enum -> xml value mapping to the enumeration class state - """ - if "_member_to_xml" not in clsdict: - clsdict["_member_to_xml"] = dict() - return clsdict["_member_to_xml"] - - @staticmethod - def _get_or_add_xml_to_member(clsdict): - """ - Add the xml -> enum value mapping to the enumeration class state - """ - if "_xml_to_member" not in clsdict: - clsdict["_xml_to_member"] = dict() - return clsdict["_xml_to_member"] diff --git a/docx/enum/dml.py b/docx/enum/dml.py deleted file mode 100644 index 133d824d..00000000 --- a/docx/enum/dml.py +++ /dev/null @@ -1,113 +0,0 @@ -# encoding: utf-8 - -""" -Enumerations used by DrawingML objects -""" - -from __future__ import absolute_import - -from .base import alias, Enumeration, EnumMember, XmlEnumeration, XmlMappedEnumMember - - -class MSO_COLOR_TYPE(Enumeration): - """ - Specifies the color specification scheme - - Example:: - - from docx.enum.dml import MSO_COLOR_TYPE - - assert font.color.type == MSO_COLOR_TYPE.SCHEME - """ - - __ms_name__ = "MsoColorType" - - __url__ = ( - "http://msdn.microsoft.com/en-us/library/office/ff864912(v=office.15" ").aspx" - ) - - __members__ = ( - EnumMember("RGB", 1, "Color is specified by an |RGBColor| value."), - EnumMember("THEME", 2, "Color is one of the preset theme colors."), - EnumMember( - "AUTO", 101, "Color is determined automatically by the " "application." - ), - ) - - -@alias("MSO_THEME_COLOR") -class MSO_THEME_COLOR_INDEX(XmlEnumeration): - """ - Indicates the Office theme color, one of those shown in the color gallery - on the formatting ribbon. - - Alias: ``MSO_THEME_COLOR`` - - Example:: - - from docx.enum.dml import MSO_THEME_COLOR - - font.color.theme_color = MSO_THEME_COLOR.ACCENT_1 - """ - - __ms_name__ = "MsoThemeColorIndex" - - __url__ = ( - "http://msdn.microsoft.com/en-us/library/office/ff860782(v=office.15" ").aspx" - ) - - __members__ = ( - EnumMember("NOT_THEME_COLOR", 0, "Indicates the color is not a theme color."), - XmlMappedEnumMember( - "ACCENT_1", 5, "accent1", "Specifies the Accent 1 theme color." - ), - XmlMappedEnumMember( - "ACCENT_2", 6, "accent2", "Specifies the Accent 2 theme color." - ), - XmlMappedEnumMember( - "ACCENT_3", 7, "accent3", "Specifies the Accent 3 theme color." - ), - XmlMappedEnumMember( - "ACCENT_4", 8, "accent4", "Specifies the Accent 4 theme color." - ), - XmlMappedEnumMember( - "ACCENT_5", 9, "accent5", "Specifies the Accent 5 theme color." - ), - XmlMappedEnumMember( - "ACCENT_6", 10, "accent6", "Specifies the Accent 6 theme color." - ), - XmlMappedEnumMember( - "BACKGROUND_1", - 14, - "background1", - "Specifies the Background 1 " "theme color.", - ), - XmlMappedEnumMember( - "BACKGROUND_2", - 16, - "background2", - "Specifies the Background 2 " "theme color.", - ), - XmlMappedEnumMember("DARK_1", 1, "dark1", "Specifies the Dark 1 theme color."), - XmlMappedEnumMember("DARK_2", 3, "dark2", "Specifies the Dark 2 theme color."), - XmlMappedEnumMember( - "FOLLOWED_HYPERLINK", - 12, - "followedHyperlink", - "Specifies the " "theme color for a clicked hyperlink.", - ), - XmlMappedEnumMember( - "HYPERLINK", - 11, - "hyperlink", - "Specifies the theme color for a " "hyperlink.", - ), - XmlMappedEnumMember( - "LIGHT_1", 2, "light1", "Specifies the Light 1 theme color." - ), - XmlMappedEnumMember( - "LIGHT_2", 4, "light2", "Specifies the Light 2 theme color." - ), - XmlMappedEnumMember("TEXT_1", 13, "text1", "Specifies the Text 1 theme color."), - XmlMappedEnumMember("TEXT_2", 15, "text2", "Specifies the Text 2 theme color."), - ) diff --git a/docx/enum/section.py b/docx/enum/section.py deleted file mode 100644 index 814e4cfb..00000000 --- a/docx/enum/section.py +++ /dev/null @@ -1,91 +0,0 @@ -# encoding: utf-8 - -""" -Enumerations related to the main document in WordprocessingML files -""" - -from __future__ import absolute_import, print_function, unicode_literals - -from .base import alias, XmlEnumeration, XmlMappedEnumMember - - -@alias("WD_HEADER_FOOTER") -class WD_HEADER_FOOTER_INDEX(XmlEnumeration): - """ - alias: **WD_HEADER_FOOTER** - - Specifies one of the three possible header/footer definitions for a section. - - For internal use only; not part of the python-docx API. - """ - - __ms_name__ = "WdHeaderFooterIndex" - - __url__ = "https://docs.microsoft.com/en-us/office/vba/api/word.wdheaderfooterindex" - - __members__ = ( - XmlMappedEnumMember( - "PRIMARY", 1, "default", "Header for odd pages or all if no even header." - ), - XmlMappedEnumMember( - "FIRST_PAGE", 2, "first", "Header for first page of section." - ), - XmlMappedEnumMember( - "EVEN_PAGE", 3, "even", "Header for even pages of recto/verso section." - ), - ) - - -@alias("WD_ORIENT") -class WD_ORIENTATION(XmlEnumeration): - """ - alias: **WD_ORIENT** - - Specifies the page layout orientation. - - Example:: - - from docx.enum.section import WD_ORIENT - - section = document.sections[-1] - section.orientation = WD_ORIENT.LANDSCAPE - """ - - __ms_name__ = "WdOrientation" - - __url__ = "http://msdn.microsoft.com/en-us/library/office/ff837902.aspx" - - __members__ = ( - XmlMappedEnumMember("PORTRAIT", 0, "portrait", "Portrait orientation."), - XmlMappedEnumMember("LANDSCAPE", 1, "landscape", "Landscape orientation."), - ) - - -@alias("WD_SECTION") -class WD_SECTION_START(XmlEnumeration): - """ - alias: **WD_SECTION** - - Specifies the start type of a section break. - - Example:: - - from docx.enum.section import WD_SECTION - - section = document.sections[0] - section.start_type = WD_SECTION.NEW_PAGE - """ - - __ms_name__ = "WdSectionStart" - - __url__ = "http://msdn.microsoft.com/en-us/library/office/ff840975.aspx" - - __members__ = ( - XmlMappedEnumMember("CONTINUOUS", 0, "continuous", "Continuous section break."), - XmlMappedEnumMember("NEW_COLUMN", 1, "nextColumn", "New column section break."), - XmlMappedEnumMember("NEW_PAGE", 2, "nextPage", "New page section break."), - XmlMappedEnumMember("EVEN_PAGE", 3, "evenPage", "Even pages section break."), - XmlMappedEnumMember( - "ODD_PAGE", 4, "oddPage", "Section begins on next odd page." - ), - ) diff --git a/docx/enum/shape.py b/docx/enum/shape.py deleted file mode 100644 index b785ab9c..00000000 --- a/docx/enum/shape.py +++ /dev/null @@ -1,23 +0,0 @@ -# encoding: utf-8 - -""" -Enumerations related to DrawingML shapes in WordprocessingML files -""" - -from __future__ import absolute_import, print_function, unicode_literals - - -class WD_INLINE_SHAPE_TYPE(object): - """ - Corresponds to WdInlineShapeType enumeration - http://msdn.microsoft.com/en-us/library/office/ff192587.aspx - """ - - CHART = 12 - LINKED_PICTURE = 4 - PICTURE = 3 - SMART_ART = 15 - NOT_IMPLEMENTED = -6 - - -WD_INLINE_SHAPE = WD_INLINE_SHAPE_TYPE diff --git a/docx/enum/style.py b/docx/enum/style.py deleted file mode 100644 index 1915429c..00000000 --- a/docx/enum/style.py +++ /dev/null @@ -1,196 +0,0 @@ -# encoding: utf-8 - -""" -Enumerations related to styles -""" - -from __future__ import absolute_import, print_function, unicode_literals - -from .base import alias, EnumMember, XmlEnumeration, XmlMappedEnumMember - - -@alias("WD_STYLE") -class WD_BUILTIN_STYLE(XmlEnumeration): - """ - alias: **WD_STYLE** - - Specifies a built-in Microsoft Word style. - - Example:: - - from docx import Document - from docx.enum.style import WD_STYLE - - document = Document() - styles = document.styles - style = styles[WD_STYLE.BODY_TEXT] - """ - - __ms_name__ = "WdBuiltinStyle" - - __url__ = "http://msdn.microsoft.com/en-us/library/office/ff835210.aspx" - - __members__ = ( - EnumMember("BLOCK_QUOTATION", -85, "Block Text."), - EnumMember("BODY_TEXT", -67, "Body Text."), - EnumMember("BODY_TEXT_2", -81, "Body Text 2."), - EnumMember("BODY_TEXT_3", -82, "Body Text 3."), - EnumMember("BODY_TEXT_FIRST_INDENT", -78, "Body Text First Indent."), - EnumMember("BODY_TEXT_FIRST_INDENT_2", -79, "Body Text First Indent 2."), - EnumMember("BODY_TEXT_INDENT", -68, "Body Text Indent."), - EnumMember("BODY_TEXT_INDENT_2", -83, "Body Text Indent 2."), - EnumMember("BODY_TEXT_INDENT_3", -84, "Body Text Indent 3."), - EnumMember("BOOK_TITLE", -265, "Book Title."), - EnumMember("CAPTION", -35, "Caption."), - EnumMember("CLOSING", -64, "Closing."), - EnumMember("COMMENT_REFERENCE", -40, "Comment Reference."), - EnumMember("COMMENT_TEXT", -31, "Comment Text."), - EnumMember("DATE", -77, "Date."), - EnumMember("DEFAULT_PARAGRAPH_FONT", -66, "Default Paragraph Font."), - EnumMember("EMPHASIS", -89, "Emphasis."), - EnumMember("ENDNOTE_REFERENCE", -43, "Endnote Reference."), - EnumMember("ENDNOTE_TEXT", -44, "Endnote Text."), - EnumMember("ENVELOPE_ADDRESS", -37, "Envelope Address."), - EnumMember("ENVELOPE_RETURN", -38, "Envelope Return."), - EnumMember("FOOTER", -33, "Footer."), - EnumMember("FOOTNOTE_REFERENCE", -39, "Footnote Reference."), - EnumMember("FOOTNOTE_TEXT", -30, "Footnote Text."), - EnumMember("HEADER", -32, "Header."), - EnumMember("HEADING_1", -2, "Heading 1."), - EnumMember("HEADING_2", -3, "Heading 2."), - EnumMember("HEADING_3", -4, "Heading 3."), - EnumMember("HEADING_4", -5, "Heading 4."), - EnumMember("HEADING_5", -6, "Heading 5."), - EnumMember("HEADING_6", -7, "Heading 6."), - EnumMember("HEADING_7", -8, "Heading 7."), - EnumMember("HEADING_8", -9, "Heading 8."), - EnumMember("HEADING_9", -10, "Heading 9."), - EnumMember("HTML_ACRONYM", -96, "HTML Acronym."), - EnumMember("HTML_ADDRESS", -97, "HTML Address."), - EnumMember("HTML_CITE", -98, "HTML Cite."), - EnumMember("HTML_CODE", -99, "HTML Code."), - EnumMember("HTML_DFN", -100, "HTML Definition."), - EnumMember("HTML_KBD", -101, "HTML Keyboard."), - EnumMember("HTML_NORMAL", -95, "Normal (Web)."), - EnumMember("HTML_PRE", -102, "HTML Preformatted."), - EnumMember("HTML_SAMP", -103, "HTML Sample."), - EnumMember("HTML_TT", -104, "HTML Typewriter."), - EnumMember("HTML_VAR", -105, "HTML Variable."), - EnumMember("HYPERLINK", -86, "Hyperlink."), - EnumMember("HYPERLINK_FOLLOWED", -87, "Followed Hyperlink."), - EnumMember("INDEX_1", -11, "Index 1."), - EnumMember("INDEX_2", -12, "Index 2."), - EnumMember("INDEX_3", -13, "Index 3."), - EnumMember("INDEX_4", -14, "Index 4."), - EnumMember("INDEX_5", -15, "Index 5."), - EnumMember("INDEX_6", -16, "Index 6."), - EnumMember("INDEX_7", -17, "Index 7."), - EnumMember("INDEX_8", -18, "Index 8."), - EnumMember("INDEX_9", -19, "Index 9."), - EnumMember("INDEX_HEADING", -34, "Index Heading"), - EnumMember("INTENSE_EMPHASIS", -262, "Intense Emphasis."), - EnumMember("INTENSE_QUOTE", -182, "Intense Quote."), - EnumMember("INTENSE_REFERENCE", -264, "Intense Reference."), - EnumMember("LINE_NUMBER", -41, "Line Number."), - EnumMember("LIST", -48, "List."), - EnumMember("LIST_2", -51, "List 2."), - EnumMember("LIST_3", -52, "List 3."), - EnumMember("LIST_4", -53, "List 4."), - EnumMember("LIST_5", -54, "List 5."), - EnumMember("LIST_BULLET", -49, "List Bullet."), - EnumMember("LIST_BULLET_2", -55, "List Bullet 2."), - EnumMember("LIST_BULLET_3", -56, "List Bullet 3."), - EnumMember("LIST_BULLET_4", -57, "List Bullet 4."), - EnumMember("LIST_BULLET_5", -58, "List Bullet 5."), - EnumMember("LIST_CONTINUE", -69, "List Continue."), - EnumMember("LIST_CONTINUE_2", -70, "List Continue 2."), - EnumMember("LIST_CONTINUE_3", -71, "List Continue 3."), - EnumMember("LIST_CONTINUE_4", -72, "List Continue 4."), - EnumMember("LIST_CONTINUE_5", -73, "List Continue 5."), - EnumMember("LIST_NUMBER", -50, "List Number."), - EnumMember("LIST_NUMBER_2", -59, "List Number 2."), - EnumMember("LIST_NUMBER_3", -60, "List Number 3."), - EnumMember("LIST_NUMBER_4", -61, "List Number 4."), - EnumMember("LIST_NUMBER_5", -62, "List Number 5."), - EnumMember("LIST_PARAGRAPH", -180, "List Paragraph."), - EnumMember("MACRO_TEXT", -46, "Macro Text."), - EnumMember("MESSAGE_HEADER", -74, "Message Header."), - EnumMember("NAV_PANE", -90, "Document Map."), - EnumMember("NORMAL", -1, "Normal."), - EnumMember("NORMAL_INDENT", -29, "Normal Indent."), - EnumMember("NORMAL_OBJECT", -158, "Normal (applied to an object)."), - EnumMember("NORMAL_TABLE", -106, "Normal (applied within a table)."), - EnumMember("NOTE_HEADING", -80, "Note Heading."), - EnumMember("PAGE_NUMBER", -42, "Page Number."), - EnumMember("PLAIN_TEXT", -91, "Plain Text."), - EnumMember("QUOTE", -181, "Quote."), - EnumMember("SALUTATION", -76, "Salutation."), - EnumMember("SIGNATURE", -65, "Signature."), - EnumMember("STRONG", -88, "Strong."), - EnumMember("SUBTITLE", -75, "Subtitle."), - EnumMember("SUBTLE_EMPHASIS", -261, "Subtle Emphasis."), - EnumMember("SUBTLE_REFERENCE", -263, "Subtle Reference."), - EnumMember("TABLE_COLORFUL_GRID", -172, "Colorful Grid."), - EnumMember("TABLE_COLORFUL_LIST", -171, "Colorful List."), - EnumMember("TABLE_COLORFUL_SHADING", -170, "Colorful Shading."), - EnumMember("TABLE_DARK_LIST", -169, "Dark List."), - EnumMember("TABLE_LIGHT_GRID", -161, "Light Grid."), - EnumMember("TABLE_LIGHT_GRID_ACCENT_1", -175, "Light Grid Accent 1."), - EnumMember("TABLE_LIGHT_LIST", -160, "Light List."), - EnumMember("TABLE_LIGHT_LIST_ACCENT_1", -174, "Light List Accent 1."), - EnumMember("TABLE_LIGHT_SHADING", -159, "Light Shading."), - EnumMember("TABLE_LIGHT_SHADING_ACCENT_1", -173, "Light Shading Accent 1."), - EnumMember("TABLE_MEDIUM_GRID_1", -166, "Medium Grid 1."), - EnumMember("TABLE_MEDIUM_GRID_2", -167, "Medium Grid 2."), - EnumMember("TABLE_MEDIUM_GRID_3", -168, "Medium Grid 3."), - EnumMember("TABLE_MEDIUM_LIST_1", -164, "Medium List 1."), - EnumMember("TABLE_MEDIUM_LIST_1_ACCENT_1", -178, "Medium List 1 Accent 1."), - EnumMember("TABLE_MEDIUM_LIST_2", -165, "Medium List 2."), - EnumMember("TABLE_MEDIUM_SHADING_1", -162, "Medium Shading 1."), - EnumMember( - "TABLE_MEDIUM_SHADING_1_ACCENT_1", -176, "Medium Shading 1 Accent 1." - ), - EnumMember("TABLE_MEDIUM_SHADING_2", -163, "Medium Shading 2."), - EnumMember( - "TABLE_MEDIUM_SHADING_2_ACCENT_1", -177, "Medium Shading 2 Accent 1." - ), - EnumMember("TABLE_OF_AUTHORITIES", -45, "Table of Authorities."), - EnumMember("TABLE_OF_FIGURES", -36, "Table of Figures."), - EnumMember("TITLE", -63, "Title."), - EnumMember("TOAHEADING", -47, "TOA Heading."), - EnumMember("TOC_1", -20, "TOC 1."), - EnumMember("TOC_2", -21, "TOC 2."), - EnumMember("TOC_3", -22, "TOC 3."), - EnumMember("TOC_4", -23, "TOC 4."), - EnumMember("TOC_5", -24, "TOC 5."), - EnumMember("TOC_6", -25, "TOC 6."), - EnumMember("TOC_7", -26, "TOC 7."), - EnumMember("TOC_8", -27, "TOC 8."), - EnumMember("TOC_9", -28, "TOC 9."), - ) - - -class WD_STYLE_TYPE(XmlEnumeration): - """ - Specifies one of the four style types: paragraph, character, list, or - table. - - Example:: - - from docx import Document - from docx.enum.style import WD_STYLE_TYPE - - styles = Document().styles - assert styles[0].type == WD_STYLE_TYPE.PARAGRAPH - """ - - __ms_name__ = "WdStyleType" - - __url__ = "http://msdn.microsoft.com/en-us/library/office/ff196870.aspx" - - __members__ = ( - XmlMappedEnumMember("CHARACTER", 2, "character", "Character style."), - XmlMappedEnumMember("LIST", 4, "numbering", "List style."), - XmlMappedEnumMember("PARAGRAPH", 1, "paragraph", "Paragraph style."), - XmlMappedEnumMember("TABLE", 3, "table", "Table style."), - ) diff --git a/docx/enum/table.py b/docx/enum/table.py deleted file mode 100644 index f66fdccd..00000000 --- a/docx/enum/table.py +++ /dev/null @@ -1,147 +0,0 @@ -# encoding: utf-8 - -""" -Enumerations related to tables in WordprocessingML files -""" - -from __future__ import absolute_import, division, print_function, unicode_literals - -from .base import alias, Enumeration, EnumMember, XmlEnumeration, XmlMappedEnumMember - - -@alias("WD_ALIGN_VERTICAL") -class WD_CELL_VERTICAL_ALIGNMENT(XmlEnumeration): - """ - alias: **WD_ALIGN_VERTICAL** - - Specifies the vertical alignment of text in one or more cells of a table. - - Example:: - - from docx.enum.table import WD_ALIGN_VERTICAL - - table = document.add_table(3, 3) - table.cell(0, 0).vertical_alignment = WD_ALIGN_VERTICAL.BOTTOM - """ - - __ms_name__ = "WdCellVerticalAlignment" - - __url__ = "https://msdn.microsoft.com/en-us/library/office/ff193345.aspx" - - __members__ = ( - XmlMappedEnumMember( - "TOP", 0, "top", "Text is aligned to the top border of the cell." - ), - XmlMappedEnumMember( - "CENTER", 1, "center", "Text is aligned to the center of the cel" "l." - ), - XmlMappedEnumMember( - "BOTTOM", - 3, - "bottom", - "Text is aligned to the bottom border of " "the cell.", - ), - XmlMappedEnumMember( - "BOTH", - 101, - "both", - "This is an option in the OpenXml spec, but" - " not in Word itself. It's not clear what Word behavior this se" - "tting produces. If you find out please let us know and we'll u" - "pdate this documentation. Otherwise, probably best to avoid thi" - "s option.", - ), - ) - - -@alias("WD_ROW_HEIGHT") -class WD_ROW_HEIGHT_RULE(XmlEnumeration): - """ - alias: **WD_ROW_HEIGHT** - - Specifies the rule for determining the height of a table row - - Example:: - - from docx.enum.table import WD_ROW_HEIGHT_RULE - - table = document.add_table(3, 3) - table.rows[0].height_rule = WD_ROW_HEIGHT_RULE.EXACTLY - """ - - __ms_name__ = "WdRowHeightRule" - - __url__ = "https://msdn.microsoft.com/en-us/library/office/ff193620.aspx" - - __members__ = ( - XmlMappedEnumMember( - "AUTO", - 0, - "auto", - "The row height is adjusted to accommodate th" - "e tallest value in the row.", - ), - XmlMappedEnumMember( - "AT_LEAST", - 1, - "atLeast", - "The row height is at least a minimum " "specified value.", - ), - XmlMappedEnumMember("EXACTLY", 2, "exact", "The row height is an exact value."), - ) - - -class WD_TABLE_ALIGNMENT(XmlEnumeration): - """ - Specifies table justification type. - - Example:: - - from docx.enum.table import WD_TABLE_ALIGNMENT - - table = document.add_table(3, 3) - table.alignment = WD_TABLE_ALIGNMENT.CENTER - """ - - __ms_name__ = "WdRowAlignment" - - __url__ = " http://office.microsoft.com/en-us/word-help/HV080607259.aspx" - - __members__ = ( - XmlMappedEnumMember("LEFT", 0, "left", "Left-aligned"), - XmlMappedEnumMember("CENTER", 1, "center", "Center-aligned."), - XmlMappedEnumMember("RIGHT", 2, "right", "Right-aligned."), - ) - - -class WD_TABLE_DIRECTION(Enumeration): - """ - Specifies the direction in which an application orders cells in the - specified table or row. - - Example:: - - from docx.enum.table import WD_TABLE_DIRECTION - - table = document.add_table(3, 3) - table.direction = WD_TABLE_DIRECTION.RTL - """ - - __ms_name__ = "WdTableDirection" - - __url__ = " http://msdn.microsoft.com/en-us/library/ff835141.aspx" - - __members__ = ( - EnumMember( - "LTR", - 0, - "The table or row is arranged with the first column " - "in the leftmost position.", - ), - EnumMember( - "RTL", - 1, - "The table or row is arranged with the first column " - "in the rightmost position.", - ), - ) diff --git a/docx/enum/text.py b/docx/enum/text.py deleted file mode 100644 index 1de05326..00000000 --- a/docx/enum/text.py +++ /dev/null @@ -1,279 +0,0 @@ -# encoding: utf-8 - -""" -Enumerations related to text in WordprocessingML files -""" - -from __future__ import absolute_import, print_function, unicode_literals - -from .base import alias, EnumMember, XmlEnumeration, XmlMappedEnumMember - - -@alias("WD_ALIGN_PARAGRAPH") -class WD_PARAGRAPH_ALIGNMENT(XmlEnumeration): - """ - alias: **WD_ALIGN_PARAGRAPH** - - Specifies paragraph justification type. - - Example:: - - from docx.enum.text import WD_ALIGN_PARAGRAPH - - paragraph = document.add_paragraph() - paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER - """ - - __ms_name__ = "WdParagraphAlignment" - - __url__ = "http://msdn.microsoft.com/en-us/library/office/ff835817.aspx" - - __members__ = ( - XmlMappedEnumMember("LEFT", 0, "left", "Left-aligned"), - XmlMappedEnumMember("CENTER", 1, "center", "Center-aligned."), - XmlMappedEnumMember("RIGHT", 2, "right", "Right-aligned."), - XmlMappedEnumMember("JUSTIFY", 3, "both", "Fully justified."), - XmlMappedEnumMember( - "DISTRIBUTE", - 4, - "distribute", - "Paragraph characters are distrib" - "uted to fill the entire width of the paragraph.", - ), - XmlMappedEnumMember( - "JUSTIFY_MED", - 5, - "mediumKashida", - "Justified with a medium char" "acter compression ratio.", - ), - XmlMappedEnumMember( - "JUSTIFY_HI", - 7, - "highKashida", - "Justified with a high character" " compression ratio.", - ), - XmlMappedEnumMember( - "JUSTIFY_LOW", - 8, - "lowKashida", - "Justified with a low character " "compression ratio.", - ), - XmlMappedEnumMember( - "THAI_JUSTIFY", - 9, - "thaiDistribute", - "Justified according to Tha" "i formatting layout.", - ), - ) - - -class WD_BREAK_TYPE(object): - """ - Corresponds to WdBreakType enumeration - http://msdn.microsoft.com/en-us/library/office/ff195905.aspx - """ - - COLUMN = 8 - LINE = 6 - LINE_CLEAR_LEFT = 9 - LINE_CLEAR_RIGHT = 10 - LINE_CLEAR_ALL = 11 # added for consistency, not in MS version - PAGE = 7 - SECTION_CONTINUOUS = 3 - SECTION_EVEN_PAGE = 4 - SECTION_NEXT_PAGE = 2 - SECTION_ODD_PAGE = 5 - TEXT_WRAPPING = 11 - - -WD_BREAK = WD_BREAK_TYPE - - -@alias("WD_COLOR") -class WD_COLOR_INDEX(XmlEnumeration): - """ - Specifies a standard preset color to apply. Used for font highlighting and - perhaps other applications. - """ - - __ms_name__ = "WdColorIndex" - - __url__ = "https://msdn.microsoft.com/EN-US/library/office/ff195343.aspx" - - __members__ = ( - XmlMappedEnumMember( - None, None, None, "Color is inherited from the style hierarchy." - ), - XmlMappedEnumMember( - "AUTO", 0, "default", "Automatic color. Default; usually black." - ), - XmlMappedEnumMember("BLACK", 1, "black", "Black color."), - XmlMappedEnumMember("BLUE", 2, "blue", "Blue color"), - XmlMappedEnumMember("BRIGHT_GREEN", 4, "green", "Bright green color."), - XmlMappedEnumMember("DARK_BLUE", 9, "darkBlue", "Dark blue color."), - XmlMappedEnumMember("DARK_RED", 13, "darkRed", "Dark red color."), - XmlMappedEnumMember("DARK_YELLOW", 14, "darkYellow", "Dark yellow color."), - XmlMappedEnumMember("GRAY_25", 16, "lightGray", "25% shade of gray color."), - XmlMappedEnumMember("GRAY_50", 15, "darkGray", "50% shade of gray color."), - XmlMappedEnumMember("GREEN", 11, "darkGreen", "Green color."), - XmlMappedEnumMember("PINK", 5, "magenta", "Pink color."), - XmlMappedEnumMember("RED", 6, "red", "Red color."), - XmlMappedEnumMember("TEAL", 10, "darkCyan", "Teal color."), - XmlMappedEnumMember("TURQUOISE", 3, "cyan", "Turquoise color."), - XmlMappedEnumMember("VIOLET", 12, "darkMagenta", "Violet color."), - XmlMappedEnumMember("WHITE", 8, "white", "White color."), - XmlMappedEnumMember("YELLOW", 7, "yellow", "Yellow color."), - ) - - -class WD_LINE_SPACING(XmlEnumeration): - """ - Specifies a line spacing format to be applied to a paragraph. - - Example:: - - from docx.enum.text import WD_LINE_SPACING - - paragraph = document.add_paragraph() - paragraph.line_spacing_rule = WD_LINE_SPACING.EXACTLY - """ - - __ms_name__ = "WdLineSpacing" - - __url__ = "http://msdn.microsoft.com/en-us/library/office/ff844910.aspx" - - __members__ = ( - EnumMember("ONE_POINT_FIVE", 1, "Space-and-a-half line spacing."), - XmlMappedEnumMember( - "AT_LEAST", - 3, - "atLeast", - "Line spacing is always at least the s" - "pecified amount. The amount is specified separately.", - ), - EnumMember("DOUBLE", 2, "Double spaced."), - XmlMappedEnumMember( - "EXACTLY", - 4, - "exact", - "Line spacing is exactly the specified am" - "ount. The amount is specified separately.", - ), - XmlMappedEnumMember( - "MULTIPLE", - 5, - "auto", - "Line spacing is specified as a multiple " - "of line heights. Changing the font size will change the line sp" - "acing proportionately.", - ), - EnumMember("SINGLE", 0, "Single spaced (default)."), - ) - - -class WD_TAB_ALIGNMENT(XmlEnumeration): - """ - Specifies the tab stop alignment to apply. - """ - - __ms_name__ = "WdTabAlignment" - - __url__ = "https://msdn.microsoft.com/EN-US/library/office/ff195609.aspx" - - __members__ = ( - XmlMappedEnumMember("LEFT", 0, "left", "Left-aligned."), - XmlMappedEnumMember("CENTER", 1, "center", "Center-aligned."), - XmlMappedEnumMember("RIGHT", 2, "right", "Right-aligned."), - XmlMappedEnumMember("DECIMAL", 3, "decimal", "Decimal-aligned."), - XmlMappedEnumMember("BAR", 4, "bar", "Bar-aligned."), - XmlMappedEnumMember("LIST", 6, "list", "List-aligned. (deprecated)"), - XmlMappedEnumMember("CLEAR", 101, "clear", "Clear an inherited tab stop."), - XmlMappedEnumMember("END", 102, "end", "Right-aligned. (deprecated)"), - XmlMappedEnumMember("NUM", 103, "num", "Left-aligned. (deprecated)"), - XmlMappedEnumMember("START", 104, "start", "Left-aligned. (deprecated)"), - ) - - -class WD_TAB_LEADER(XmlEnumeration): - """ - Specifies the character to use as the leader with formatted tabs. - """ - - __ms_name__ = "WdTabLeader" - - __url__ = "https://msdn.microsoft.com/en-us/library/office/ff845050.aspx" - - __members__ = ( - XmlMappedEnumMember("SPACES", 0, "none", "Spaces. Default."), - XmlMappedEnumMember("DOTS", 1, "dot", "Dots."), - XmlMappedEnumMember("DASHES", 2, "hyphen", "Dashes."), - XmlMappedEnumMember("LINES", 3, "underscore", "Double lines."), - XmlMappedEnumMember("HEAVY", 4, "heavy", "A heavy line."), - XmlMappedEnumMember("MIDDLE_DOT", 5, "middleDot", "A vertically-centered dot."), - ) - - -class WD_UNDERLINE(XmlEnumeration): - """ - Specifies the style of underline applied to a run of characters. - """ - - __ms_name__ = "WdUnderline" - - __url__ = "http://msdn.microsoft.com/en-us/library/office/ff822388.aspx" - - __members__ = ( - XmlMappedEnumMember( - None, None, None, "Inherit underline setting from containing par" "agraph." - ), - XmlMappedEnumMember( - "NONE", - 0, - "none", - "No underline. This setting overrides any inh" - "erited underline value, so can be used to remove underline from" - " a run that inherits underlining from its containing paragraph." - " Note this is not the same as assigning |None| to Run.underline" - ". |None| is a valid assignment value, but causes the run to inh" - "erit its underline value. Assigning ``WD_UNDERLINE.NONE`` cause" - "s underlining to be unconditionally turned off.", - ), - XmlMappedEnumMember( - "SINGLE", - 1, - "single", - "A single line. Note that this setting is" - "write-only in the sense that |True| (rather than ``WD_UNDERLINE" - ".SINGLE``) is returned for a run having this setting.", - ), - XmlMappedEnumMember("WORDS", 2, "words", "Underline individual words only."), - XmlMappedEnumMember("DOUBLE", 3, "double", "A double line."), - XmlMappedEnumMember("DOTTED", 4, "dotted", "Dots."), - XmlMappedEnumMember("THICK", 6, "thick", "A single thick line."), - XmlMappedEnumMember("DASH", 7, "dash", "Dashes."), - XmlMappedEnumMember("DOT_DASH", 9, "dotDash", "Alternating dots and dashes."), - XmlMappedEnumMember( - "DOT_DOT_DASH", 10, "dotDotDash", "An alternating dot-dot-dash p" "attern." - ), - XmlMappedEnumMember("WAVY", 11, "wave", "A single wavy line."), - XmlMappedEnumMember("DOTTED_HEAVY", 20, "dottedHeavy", "Heavy dots."), - XmlMappedEnumMember("DASH_HEAVY", 23, "dashedHeavy", "Heavy dashes."), - XmlMappedEnumMember( - "DOT_DASH_HEAVY", - 25, - "dashDotHeavy", - "Alternating heavy dots an" "d heavy dashes.", - ), - XmlMappedEnumMember( - "DOT_DOT_DASH_HEAVY", - 26, - "dashDotDotHeavy", - "An alternating hea" "vy dot-dot-dash pattern.", - ), - XmlMappedEnumMember("WAVY_HEAVY", 27, "wavyHeavy", "A heavy wavy line."), - XmlMappedEnumMember("DASH_LONG", 39, "dashLong", "Long dashes."), - XmlMappedEnumMember("WAVY_DOUBLE", 43, "wavyDouble", "A double wavy line."), - XmlMappedEnumMember( - "DASH_LONG_HEAVY", 55, "dashLongHeavy", "Long heavy dashes." - ), - ) diff --git a/docx/exceptions.py b/docx/exceptions.py deleted file mode 100644 index 7a8b99c8..00000000 --- a/docx/exceptions.py +++ /dev/null @@ -1,27 +0,0 @@ -# encoding: utf-8 - -""" -Exceptions used with python-docx. - -The base exception class is PythonDocxError. -""" - - -class PythonDocxError(Exception): - """ - Generic error class. - """ - - -class InvalidSpanError(PythonDocxError): - """ - Raised when an invalid merge region is specified in a request to merge - table cells. - """ - - -class InvalidXmlError(PythonDocxError): - """ - Raised when invalid XML is encountered, such as on attempt to access a - missing required child element - """ diff --git a/docx/image/exceptions.py b/docx/image/exceptions.py deleted file mode 100644 index c45fc6d9..00000000 --- a/docx/image/exceptions.py +++ /dev/null @@ -1,23 +0,0 @@ -# encoding: utf-8 - -""" -Exceptions specific to the image sub-package -""" - - -class InvalidImageStreamError(Exception): - """ - The recognized image stream appears to be corrupted - """ - - -class UnexpectedEndOfFileError(Exception): - """ - EOF was unexpectedly encountered while reading an image stream. - """ - - -class UnrecognizedImageError(Exception): - """ - The provided image stream could not be recognized. - """ diff --git a/docx/image/image.py b/docx/image/image.py deleted file mode 100644 index 8fddaabc..00000000 --- a/docx/image/image.py +++ /dev/null @@ -1,265 +0,0 @@ -# encoding: utf-8 - -""" -Provides objects that can characterize image streams as to content type and -size, as a required step in including them in a document. -""" - -from __future__ import absolute_import, division, print_function - -import hashlib -import os - -from ..compat import BytesIO, is_string -from .exceptions import UnrecognizedImageError -from ..shared import Emu, Inches, lazyproperty - - -class Image(object): - """ - Graphical image stream such as JPEG, PNG, or GIF with properties and - methods required by ImagePart. - """ - - def __init__(self, blob, filename, image_header): - super(Image, self).__init__() - self._blob = blob - self._filename = filename - self._image_header = image_header - - @classmethod - def from_blob(cls, blob): - """ - Return a new |Image| subclass instance parsed from the image binary - contained in *blob*. - """ - stream = BytesIO(blob) - return cls._from_stream(stream, blob) - - @classmethod - def from_file(cls, image_descriptor): - """ - Return a new |Image| subclass instance loaded from the image file - identified by *image_descriptor*, a path or file-like object. - """ - if is_string(image_descriptor): - path = image_descriptor - with open(path, "rb") as f: - blob = f.read() - stream = BytesIO(blob) - filename = os.path.basename(path) - else: - stream = image_descriptor - stream.seek(0) - blob = stream.read() - filename = None - return cls._from_stream(stream, blob, filename) - - @property - def blob(self): - """ - The bytes of the image 'file' - """ - return self._blob - - @property - def content_type(self): - """ - MIME content type for this image, e.g. ``'image/jpeg'`` for a JPEG - image - """ - return self._image_header.content_type - - @lazyproperty - def ext(self): - """ - The file extension for the image. If an actual one is available from - a load filename it is used. Otherwise a canonical extension is - assigned based on the content type. Does not contain the leading - period, e.g. 'jpg', not '.jpg'. - """ - return os.path.splitext(self._filename)[1][1:] - - @property - def filename(self): - """ - Original image file name, if loaded from disk, or a generic filename - if loaded from an anonymous stream. - """ - return self._filename - - @property - def px_width(self): - """ - The horizontal pixel dimension of the image - """ - return self._image_header.px_width - - @property - def px_height(self): - """ - The vertical pixel dimension of the image - """ - return self._image_header.px_height - - @property - def horz_dpi(self): - """ - Integer dots per inch for the width of this image. Defaults to 72 - when not present in the file, as is often the case. - """ - return self._image_header.horz_dpi - - @property - def vert_dpi(self): - """ - Integer dots per inch for the height of this image. Defaults to 72 - when not present in the file, as is often the case. - """ - return self._image_header.vert_dpi - - @property - def width(self): - """ - A |Length| value representing the native width of the image, - calculated from the values of `px_width` and `horz_dpi`. - """ - return Inches(self.px_width / self.horz_dpi) - - @property - def height(self): - """ - A |Length| value representing the native height of the image, - calculated from the values of `px_height` and `vert_dpi`. - """ - return Inches(self.px_height / self.vert_dpi) - - def scaled_dimensions(self, width=None, height=None): - """ - Return a (cx, cy) 2-tuple representing the native dimensions of this - image scaled by applying the following rules to *width* and *height*. - If both *width* and *height* are specified, the return value is - (*width*, *height*); no scaling is performed. If only one is - specified, it is used to compute a scaling factor that is then - applied to the unspecified dimension, preserving the aspect ratio of - the image. If both *width* and *height* are |None|, the native - dimensions are returned. The native dimensions are calculated using - the dots-per-inch (dpi) value embedded in the image, defaulting to 72 - dpi if no value is specified, as is often the case. The returned - values are both |Length| objects. - """ - if width is None and height is None: - return self.width, self.height - - if width is None: - scaling_factor = float(height) / float(self.height) - width = round(self.width * scaling_factor) - - if height is None: - scaling_factor = float(width) / float(self.width) - height = round(self.height * scaling_factor) - - return Emu(width), Emu(height) - - @lazyproperty - def sha1(self): - """ - SHA1 hash digest of the image blob - """ - return hashlib.sha1(self._blob).hexdigest() - - @classmethod - def _from_stream(cls, stream, blob, filename=None): - """ - Return an instance of the |Image| subclass corresponding to the - format of the image in *stream*. - """ - image_header = _ImageHeaderFactory(stream) - if filename is None: - filename = "image.%s" % image_header.default_ext - return cls(blob, filename, image_header) - - -def _ImageHeaderFactory(stream): - """ - Return a |BaseImageHeader| subclass instance that knows how to parse the - headers of the image in *stream*. - """ - from docx.image import SIGNATURES - - def read_32(stream): - stream.seek(0) - return stream.read(32) - - header = read_32(stream) - for cls, offset, signature_bytes in SIGNATURES: - end = offset + len(signature_bytes) - found_bytes = header[offset:end] - if found_bytes == signature_bytes: - return cls.from_stream(stream) - raise UnrecognizedImageError - - -class BaseImageHeader(object): - """ - Base class for image header subclasses like |Jpeg| and |Tiff|. - """ - - def __init__(self, px_width, px_height, horz_dpi, vert_dpi): - self._px_width = px_width - self._px_height = px_height - self._horz_dpi = horz_dpi - self._vert_dpi = vert_dpi - - @property - def content_type(self): - """ - Abstract property definition, must be implemented by all subclasses. - """ - msg = ( - "content_type property must be implemented by all subclasses of " - "BaseImageHeader" - ) - raise NotImplementedError(msg) - - @property - def default_ext(self): - """ - Default filename extension for images of this type. An abstract - property definition, must be implemented by all subclasses. - """ - msg = ( - "default_ext property must be implemented by all subclasses of " - "BaseImageHeader" - ) - raise NotImplementedError(msg) - - @property - def px_width(self): - """ - The horizontal pixel dimension of the image - """ - return self._px_width - - @property - def px_height(self): - """ - The vertical pixel dimension of the image - """ - return self._px_height - - @property - def horz_dpi(self): - """ - Integer dots per inch for the width of this image. Defaults to 72 - when not present in the file, as is often the case. - """ - return self._horz_dpi - - @property - def vert_dpi(self): - """ - Integer dots per inch for the height of this image. Defaults to 72 - when not present in the file, as is often the case. - """ - return self._vert_dpi diff --git a/docx/opc/compat.py b/docx/opc/compat.py deleted file mode 100644 index d5f63ac1..00000000 --- a/docx/opc/compat.py +++ /dev/null @@ -1,49 +0,0 @@ -# encoding: utf-8 - -""" -Provides Python 2/3 compatibility objects -""" - -from __future__ import absolute_import, division, print_function, unicode_literals - -import sys - -# =========================================================================== -# Python 3 versions -# =========================================================================== - -if sys.version_info >= (3, 0): - - def cls_method_fn(cls, method_name): - """ - Return the function object associated with the method of *cls* having - *method_name*. - """ - return getattr(cls, method_name) - - def is_string(obj): - """ - Return True if *obj* is a string, False otherwise. - """ - return isinstance(obj, str) - - -# =========================================================================== -# Python 2 versions -# =========================================================================== - -else: - - def cls_method_fn(cls, method_name): - """ - Return the function object associated with the method of *cls* having - *method_name*. - """ - unbound_method = getattr(cls, method_name) - return unbound_method.__func__ - - def is_string(obj): - """ - Return True if *obj* is a string, False otherwise. - """ - return isinstance(obj, basestring) # noqa diff --git a/docx/opc/constants.py b/docx/opc/constants.py deleted file mode 100644 index 87a64998..00000000 --- a/docx/opc/constants.py +++ /dev/null @@ -1,559 +0,0 @@ -# encoding: utf-8 - -""" -Constant values related to the Open Packaging Convention, in particular, -content types and relationship types. -""" - - -class CONTENT_TYPE(object): - """ - Content type URIs (like MIME-types) that specify a part's format - """ - - BMP = "image/bmp" - DML_CHART = "application/vnd.openxmlformats-officedocument.drawingml.chart+xml" - DML_CHARTSHAPES = ( - "application/vnd.openxmlformats-officedocument.drawingml.chartshapes" "+xml" - ) - DML_DIAGRAM_COLORS = ( - "application/vnd.openxmlformats-officedocument.drawingml.diagramColo" "rs+xml" - ) - DML_DIAGRAM_DATA = ( - "application/vnd.openxmlformats-officedocument.drawingml.diagramData" "+xml" - ) - DML_DIAGRAM_LAYOUT = ( - "application/vnd.openxmlformats-officedocument.drawingml.diagramLayo" "ut+xml" - ) - DML_DIAGRAM_STYLE = ( - "application/vnd.openxmlformats-officedocument.drawingml.diagramStyl" "e+xml" - ) - GIF = "image/gif" - JPEG = "image/jpeg" - MS_PHOTO = "image/vnd.ms-photo" - OFC_CUSTOM_PROPERTIES = ( - "application/vnd.openxmlformats-officedocument.custom-properties+xml" - ) - OFC_CUSTOM_XML_PROPERTIES = ( - "application/vnd.openxmlformats-officedocument.customXmlProperties+x" "ml" - ) - OFC_DRAWING = "application/vnd.openxmlformats-officedocument.drawing+xml" - OFC_EXTENDED_PROPERTIES = ( - "application/vnd.openxmlformats-officedocument.extended-properties+x" "ml" - ) - OFC_OLE_OBJECT = "application/vnd.openxmlformats-officedocument.oleObject" - OFC_PACKAGE = "application/vnd.openxmlformats-officedocument.package" - OFC_THEME = "application/vnd.openxmlformats-officedocument.theme+xml" - OFC_THEME_OVERRIDE = ( - "application/vnd.openxmlformats-officedocument.themeOverride+xml" - ) - OFC_VML_DRAWING = "application/vnd.openxmlformats-officedocument.vmlDrawing" - OPC_CORE_PROPERTIES = "application/vnd.openxmlformats-package.core-properties+xml" - OPC_CUSTOM_PROPERTIES = ( - "application/vnd.openxmlformats-officedocument.custom-properties+xml" - ) - OPC_DIGITAL_SIGNATURE_CERTIFICATE = ( - "application/vnd.openxmlformats-package.digital-signature-certificat" "e" - ) - OPC_DIGITAL_SIGNATURE_ORIGIN = ( - "application/vnd.openxmlformats-package.digital-signature-origin" - ) - OPC_DIGITAL_SIGNATURE_XMLSIGNATURE = ( - "application/vnd.openxmlformats-package.digital-signature-xmlsignatu" "re+xml" - ) - OPC_RELATIONSHIPS = "application/vnd.openxmlformats-package.relationships+xml" - PML_COMMENTS = ( - "application/vnd.openxmlformats-officedocument.presentationml.commen" "ts+xml" - ) - PML_COMMENT_AUTHORS = ( - "application/vnd.openxmlformats-officedocument.presentationml.commen" - "tAuthors+xml" - ) - PML_HANDOUT_MASTER = ( - "application/vnd.openxmlformats-officedocument.presentationml.handou" - "tMaster+xml" - ) - PML_NOTES_MASTER = ( - "application/vnd.openxmlformats-officedocument.presentationml.notesM" - "aster+xml" - ) - PML_NOTES_SLIDE = ( - "application/vnd.openxmlformats-officedocument.presentationml.notesS" "lide+xml" - ) - PML_PRESENTATION_MAIN = ( - "application/vnd.openxmlformats-officedocument.presentationml.presen" - "tation.main+xml" - ) - PML_PRES_PROPS = ( - "application/vnd.openxmlformats-officedocument.presentationml.presPr" "ops+xml" - ) - PML_PRINTER_SETTINGS = ( - "application/vnd.openxmlformats-officedocument.presentationml.printe" - "rSettings" - ) - PML_SLIDE = ( - "application/vnd.openxmlformats-officedocument.presentationml.slide+" "xml" - ) - PML_SLIDESHOW_MAIN = ( - "application/vnd.openxmlformats-officedocument.presentationml.slides" - "how.main+xml" - ) - PML_SLIDE_LAYOUT = ( - "application/vnd.openxmlformats-officedocument.presentationml.slideL" - "ayout+xml" - ) - PML_SLIDE_MASTER = ( - "application/vnd.openxmlformats-officedocument.presentationml.slideM" - "aster+xml" - ) - PML_SLIDE_UPDATE_INFO = ( - "application/vnd.openxmlformats-officedocument.presentationml.slideU" - "pdateInfo+xml" - ) - PML_TABLE_STYLES = ( - "application/vnd.openxmlformats-officedocument.presentationml.tableS" - "tyles+xml" - ) - PML_TAGS = ( - "application/vnd.openxmlformats-officedocument.presentationml.tags+x" "ml" - ) - PML_TEMPLATE_MAIN = ( - "application/vnd.openxmlformats-officedocument.presentationml.templa" - "te.main+xml" - ) - PML_VIEW_PROPS = ( - "application/vnd.openxmlformats-officedocument.presentationml.viewPr" "ops+xml" - ) - PNG = "image/png" - SML_CALC_CHAIN = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.calcCha" "in+xml" - ) - SML_CHARTSHEET = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsh" "eet+xml" - ) - SML_COMMENTS = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.comment" "s+xml" - ) - SML_CONNECTIONS = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.connect" "ions+xml" - ) - SML_CUSTOM_PROPERTY = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.customP" "roperty" - ) - SML_DIALOGSHEET = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.dialogs" "heet+xml" - ) - SML_EXTERNAL_LINK = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.externa" - "lLink+xml" - ) - SML_PIVOT_CACHE_DEFINITION = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCa" - "cheDefinition+xml" - ) - SML_PIVOT_CACHE_RECORDS = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCa" - "cheRecords+xml" - ) - SML_PIVOT_TABLE = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTa" "ble+xml" - ) - SML_PRINTER_SETTINGS = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.printer" "Settings" - ) - SML_QUERY_TABLE = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.queryTa" "ble+xml" - ) - SML_REVISION_HEADERS = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.revisio" - "nHeaders+xml" - ) - SML_REVISION_LOG = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.revisio" "nLog+xml" - ) - SML_SHARED_STRINGS = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedS" - "trings+xml" - ) - SML_SHEET = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" - SML_SHEET_MAIN = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.m" "ain+xml" - ) - SML_SHEET_METADATA = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMe" - "tadata+xml" - ) - SML_STYLES = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+" "xml" - ) - SML_TABLE = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.table+x" "ml" - ) - SML_TABLE_SINGLE_CELLS = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.tableSi" - "ngleCells+xml" - ) - SML_TEMPLATE_MAIN = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.templat" - "e.main+xml" - ) - SML_USER_NAMES = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.userNam" "es+xml" - ) - SML_VOLATILE_DEPENDENCIES = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.volatil" - "eDependencies+xml" - ) - SML_WORKSHEET = ( - "application/vnd.openxmlformats-officedocument.spreadsheetml.workshe" "et+xml" - ) - TIFF = "image/tiff" - WML_COMMENTS = ( - "application/vnd.openxmlformats-officedocument.wordprocessingml.comm" "ents+xml" - ) - WML_DOCUMENT = ( - "application/vnd.openxmlformats-officedocument.wordprocessingml.docu" "ment" - ) - WML_DOCUMENT_GLOSSARY = ( - "application/vnd.openxmlformats-officedocument.wordprocessingml.docu" - "ment.glossary+xml" - ) - WML_DOCUMENT_MAIN = ( - "application/vnd.openxmlformats-officedocument.wordprocessingml.docu" - "ment.main+xml" - ) - WML_ENDNOTES = ( - "application/vnd.openxmlformats-officedocument.wordprocessingml.endn" "otes+xml" - ) - WML_FONT_TABLE = ( - "application/vnd.openxmlformats-officedocument.wordprocessingml.font" - "Table+xml" - ) - WML_FOOTER = ( - "application/vnd.openxmlformats-officedocument.wordprocessingml.foot" "er+xml" - ) - WML_FOOTNOTES = ( - "application/vnd.openxmlformats-officedocument.wordprocessingml.foot" - "notes+xml" - ) - WML_HEADER = ( - "application/vnd.openxmlformats-officedocument.wordprocessingml.head" "er+xml" - ) - WML_NUMBERING = ( - "application/vnd.openxmlformats-officedocument.wordprocessingml.numb" - "ering+xml" - ) - WML_PRINTER_SETTINGS = ( - "application/vnd.openxmlformats-officedocument.wordprocessingml.prin" - "terSettings" - ) - WML_SETTINGS = ( - "application/vnd.openxmlformats-officedocument.wordprocessingml.sett" "ings+xml" - ) - WML_STYLES = ( - "application/vnd.openxmlformats-officedocument.wordprocessingml.styl" "es+xml" - ) - WML_WEB_SETTINGS = ( - "application/vnd.openxmlformats-officedocument.wordprocessingml.webS" - "ettings+xml" - ) - XML = "application/xml" - X_EMF = "image/x-emf" - X_FONTDATA = "application/x-fontdata" - X_FONT_TTF = "application/x-font-ttf" - X_WMF = "image/x-wmf" - - -class NAMESPACE(object): - """Constant values for OPC XML namespaces""" - - DML_WORDPROCESSING_DRAWING = ( - "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDraw" "ing" - ) - OFC_RELATIONSHIPS = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - ) - OPC_RELATIONSHIPS = "http://schemas.openxmlformats.org/package/2006/relationships" - OPC_CONTENT_TYPES = "http://schemas.openxmlformats.org/package/2006/content-types" - WML_MAIN = "http://schemas.openxmlformats.org/wordprocessingml/2006/main" - - -class RELATIONSHIP_TARGET_MODE(object): - """Open XML relationship target modes""" - - EXTERNAL = "External" - INTERNAL = "Internal" - - -class RELATIONSHIP_TYPE(object): - AUDIO = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/audio" - ) - A_F_CHUNK = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/aFChunk" - ) - CALC_CHAIN = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/calcChain" - ) - CERTIFICATE = ( - "http://schemas.openxmlformats.org/package/2006/relationships/digita" - "l-signature/certificate" - ) - CHART = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/chart" - ) - CHARTSHEET = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/chartsheet" - ) - CHART_USER_SHAPES = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/chartUserShapes" - ) - COMMENTS = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/comments" - ) - COMMENT_AUTHORS = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/commentAuthors" - ) - CONNECTIONS = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/connections" - ) - CONTROL = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/control" - ) - CORE_PROPERTIES = ( - "http://schemas.openxmlformats.org/package/2006/relationships/metada" - "ta/core-properties" - ) - CUSTOM_PROPERTIES = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/custom-properties" - ) - CUSTOM_PROPERTY = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/customProperty" - ) - CUSTOM_XML = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/customXml" - ) - CUSTOM_XML_PROPS = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/customXmlProps" - ) - DIAGRAM_COLORS = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/diagramColors" - ) - DIAGRAM_DATA = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/diagramData" - ) - DIAGRAM_LAYOUT = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/diagramLayout" - ) - DIAGRAM_QUICK_STYLE = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/diagramQuickStyle" - ) - DIALOGSHEET = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/dialogsheet" - ) - DRAWING = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/drawing" - ) - ENDNOTES = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/endnotes" - ) - EXTENDED_PROPERTIES = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/extended-properties" - ) - EXTERNAL_LINK = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/externalLink" - ) - FONT = "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/font" - FONT_TABLE = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/fontTable" - ) - FOOTER = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/footer" - ) - FOOTNOTES = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/footnotes" - ) - GLOSSARY_DOCUMENT = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/glossaryDocument" - ) - HANDOUT_MASTER = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/handoutMaster" - ) - HEADER = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/header" - ) - HYPERLINK = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/hyperlink" - ) - IMAGE = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/image" - ) - NOTES_MASTER = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/notesMaster" - ) - NOTES_SLIDE = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/notesSlide" - ) - NUMBERING = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/numbering" - ) - OFFICE_DOCUMENT = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/officeDocument" - ) - OLE_OBJECT = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/oleObject" - ) - ORIGIN = ( - "http://schemas.openxmlformats.org/package/2006/relationships/digita" - "l-signature/origin" - ) - PACKAGE = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/package" - ) - PIVOT_CACHE_DEFINITION = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/pivotCacheDefinition" - ) - PIVOT_CACHE_RECORDS = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/spreadsheetml/pivotCacheRecords" - ) - PIVOT_TABLE = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/pivotTable" - ) - PRES_PROPS = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/presProps" - ) - PRINTER_SETTINGS = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/printerSettings" - ) - QUERY_TABLE = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/queryTable" - ) - REVISION_HEADERS = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/revisionHeaders" - ) - REVISION_LOG = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/revisionLog" - ) - SETTINGS = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/settings" - ) - SHARED_STRINGS = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/sharedStrings" - ) - SHEET_METADATA = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/sheetMetadata" - ) - SIGNATURE = ( - "http://schemas.openxmlformats.org/package/2006/relationships/digita" - "l-signature/signature" - ) - SLIDE = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/slide" - ) - SLIDE_LAYOUT = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/slideLayout" - ) - SLIDE_MASTER = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/slideMaster" - ) - SLIDE_UPDATE_INFO = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/slideUpdateInfo" - ) - STYLES = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/styles" - ) - TABLE = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/table" - ) - TABLE_SINGLE_CELLS = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/tableSingleCells" - ) - TABLE_STYLES = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/tableStyles" - ) - TAGS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/tags" - THEME = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/theme" - ) - THEME_OVERRIDE = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/themeOverride" - ) - THUMBNAIL = ( - "http://schemas.openxmlformats.org/package/2006/relationships/metada" - "ta/thumbnail" - ) - USERNAMES = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/usernames" - ) - VIDEO = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/video" - ) - VIEW_PROPS = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/viewProps" - ) - VML_DRAWING = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/vmlDrawing" - ) - VOLATILE_DEPENDENCIES = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/volatileDependencies" - ) - WEB_SETTINGS = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/webSettings" - ) - WORKSHEET_SOURCE = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" - "/worksheetSource" - ) - XML_MAPS = ( - "http://schemas.openxmlformats.org/officeDocument/2006/relationships" "/xmlMaps" - ) diff --git a/docx/opc/exceptions.py b/docx/opc/exceptions.py deleted file mode 100644 index b8e6de43..00000000 --- a/docx/opc/exceptions.py +++ /dev/null @@ -1,19 +0,0 @@ -# encoding: utf-8 - -""" -Exceptions specific to python-opc - -The base exception class is OpcError. -""" - - -class OpcError(Exception): - """ - Base error class for python-opc - """ - - -class PackageNotFoundError(OpcError): - """ - Raised when a package cannot be found at the specified path. - """ diff --git a/docx/opc/packuri.py b/docx/opc/packuri.py deleted file mode 100644 index f20af84f..00000000 --- a/docx/opc/packuri.py +++ /dev/null @@ -1,118 +0,0 @@ -# encoding: utf-8 - -""" -Provides the PackURI value type along with some useful known pack URI strings -such as PACKAGE_URI. -""" - -import posixpath -import re - - -class PackURI(str): - """ - Provides access to pack URI components such as the baseURI and the - filename slice. Behaves as |str| otherwise. - """ - - _filename_re = re.compile("([a-zA-Z]+)([1-9][0-9]*)?") - - def __new__(cls, pack_uri_str): - if not pack_uri_str[0] == "/": - tmpl = "PackURI must begin with slash, got '%s'" - raise ValueError(tmpl % pack_uri_str) - return str.__new__(cls, pack_uri_str) - - @staticmethod - def from_rel_ref(baseURI, relative_ref): - """ - Return a |PackURI| instance containing the absolute pack URI formed by - translating *relative_ref* onto *baseURI*. - """ - joined_uri = posixpath.join(baseURI, relative_ref) - abs_uri = posixpath.abspath(joined_uri) - return PackURI(abs_uri) - - @property - def baseURI(self): - """ - The base URI of this pack URI, the directory portion, roughly - speaking. E.g. ``'/ppt/slides'`` for ``'/ppt/slides/slide1.xml'``. - For the package pseudo-partname '/', baseURI is '/'. - """ - return posixpath.split(self)[0] - - @property - def ext(self): - """ - The extension portion of this pack URI, e.g. ``'xml'`` for - ``'/word/document.xml'``. Note the period is not included. - """ - # raw_ext is either empty string or starts with period, e.g. '.xml' - raw_ext = posixpath.splitext(self)[1] - return raw_ext[1:] if raw_ext.startswith(".") else raw_ext - - @property - def filename(self): - """ - The "filename" portion of this pack URI, e.g. ``'slide1.xml'`` for - ``'/ppt/slides/slide1.xml'``. For the package pseudo-partname '/', - filename is ''. - """ - return posixpath.split(self)[1] - - @property - def idx(self): - """ - Return partname index as integer for tuple partname or None for - singleton partname, e.g. ``21`` for ``'/ppt/slides/slide21.xml'`` and - |None| for ``'/ppt/presentation.xml'``. - """ - filename = self.filename - if not filename: - return None - name_part = posixpath.splitext(filename)[0] # filename w/ext removed - match = self._filename_re.match(name_part) - if match is None: - return None - if match.group(2): - return int(match.group(2)) - return None - - @property - def membername(self): - """ - The pack URI with the leading slash stripped off, the form used as - the Zip file membername for the package item. Returns '' for the - package pseudo-partname '/'. - """ - return self[1:] - - def relative_ref(self, baseURI): - """ - Return string containing relative reference to package item from - *baseURI*. E.g. PackURI('/ppt/slideLayouts/slideLayout1.xml') would - return '../slideLayouts/slideLayout1.xml' for baseURI '/ppt/slides'. - """ - # workaround for posixpath bug in 2.6, doesn't generate correct - # relative path when *start* (second) parameter is root ('/') - if baseURI == "/": - relpath = self[1:] - else: - relpath = posixpath.relpath(self, baseURI) - return relpath - - @property - def rels_uri(self): - """ - The pack URI of the .rels part corresponding to the current pack URI. - Only produces sensible output if the pack URI is a partname or the - package pseudo-partname '/'. - """ - rels_filename = "%s.rels" % self.filename - rels_uri_str = posixpath.join(self.baseURI, "_rels", rels_filename) - return PackURI(rels_uri_str) - - -PACKAGE_URI = PackURI("/") -CONTENT_TYPES_URI = PackURI("/[Content_Types].xml") diff --git a/docx/opc/part.py b/docx/opc/part.py deleted file mode 100644 index dcfca45e..00000000 --- a/docx/opc/part.py +++ /dev/null @@ -1,245 +0,0 @@ -from typing import Callable - -from ..oxml import parse_xml -from .compat import cls_method_fn -from .oxml import serialize_part_xml -from .packuri import PackURI -from .rel import Relationships, _Relationship -from .shared import lazyproperty - - -class Part: - """ - Base class for package parts. Provides common properties and methods, but - intended to be subclassed in client code to implement specific part - behaviors. - """ - - def __init__(self, partname, content_type, blob=None, package=None): - self._partname = partname - self._content_type = content_type - self._blob = blob - self._package = package - - def after_unmarshal(self): - """ - Entry point for post-unmarshaling processing, for example to parse - the part XML. May be overridden by subclasses without forwarding call - to super. - """ - # don't place any code here, just catch call if not overridden by - # subclass - pass - - def before_marshal(self): - """ - Entry point for pre-serialization processing, for example to finalize - part naming if necessary. May be overridden by subclasses without - forwarding call to super. - """ - # don't place any code here, just catch call if not overridden by - # subclass - pass - - @property - def blob(self): - """ - Contents of this package part as a sequence of bytes. May be text or - binary. Intended to be overridden by subclasses. Default behavior is - to return load blob. - """ - return self._blob - - @property - def content_type(self): - """ - Content type of this part. - """ - return self._content_type - - def drop_rel(self, rId): - """ - Remove the relationship identified by *rId* if its reference count - is less than 2. Relationships with a reference count of 0 are - implicit relationships. - """ - if self._rel_ref_count(rId) < 2: - del self.rels[rId] - - def drop_rels(self, cmp: Callable[[_Relationship], bool]) -> list[str]: - rids = [rid for rid, rel in self.rels.items() if cmp(rel)] - for rid in rids: - del self.rels[rid] - return rids - - @classmethod - def load(cls, partname, content_type, blob, package): - return cls(partname, content_type, blob, package) - - def load_rel(self, reltype, target, rId, is_external=False): - """ - Return newly added |_Relationship| instance of *reltype* between this - part and *target* with key *rId*. Target mode is set to - ``RTM.EXTERNAL`` if *is_external* is |True|. Intended for use during - load from a serialized package, where the rId is well-known. Other - methods exist for adding a new relationship to a part when - manipulating a part. - """ - return self.rels.add_relationship(reltype, target, rId, is_external) - - @property - def package(self): - """ - |OpcPackage| instance this part belongs to. - """ - return self._package - - @property - def partname(self): - """ - |PackURI| instance holding partname of this part, e.g. - '/ppt/slides/slide1.xml' - """ - return self._partname - - @partname.setter - def partname(self, partname): - if not isinstance(partname, PackURI): - tmpl = "partname must be instance of PackURI, got '%s'" - raise TypeError(tmpl % type(partname).__name__) - self._partname = partname - - def __eq__(self, other): - return type(self) == type(other) and self.partname == other.partname - - def part_related_by(self, reltype): - """ - Return part to which this part has a relationship of *reltype*. - Raises |KeyError| if no such relationship is found and |ValueError| - if more than one such relationship is found. Provides ability to - resolve implicitly related part, such as Slide -> SlideLayout. - """ - return self.rels.part_with_reltype(reltype) - - def relate_to(self, target, reltype, is_external=False): - """ - Return rId key of relationship of *reltype* to *target*, from an - existing relationship if there is one, otherwise a newly created one. - """ - if is_external: - return self.rels.get_or_add_ext_rel(reltype, target) - rel = self.rels.get_or_add(reltype, target) - return rel.rId - - @property - def related_parts(self): - """ - Dictionary mapping related parts by rId, so child objects can resolve - explicit relationships present in the part XML, e.g. sldIdLst to a - specific |Slide| instance. - """ - return self.rels.related_parts - - @lazyproperty - def rels(self): - """ - |Relationships| instance holding the relationships for this part. - """ - return Relationships(self._partname.baseURI) - - def target_ref(self, rId): - """ - Return URL contained in target ref of relationship identified by - *rId*. - """ - rel = self.rels[rId] - return rel.target_ref - - def _rel_ref_count(self, rId): - """ - Return the count of references in this part's XML to the relationship - identified by *rId*. - """ - rIds = self._element.xpath("//@r:id") - return len([_rId for _rId in rIds if _rId == rId]) - - -class PartFactory(object): - """ - Provides a way for client code to specify a subclass of |Part| to be - constructed by |Unmarshaller| based on its content type and/or a custom - callable. Setting ``PartFactory.part_class_selector`` to a callable - object will cause that object to be called with the parameters - ``content_type, reltype``, once for each part in the package. If the - callable returns an object, it is used as the class for that part. If it - returns |None|, part class selection falls back to the content type map - defined in ``PartFactory.part_type_for``. If no class is returned from - either of these, the class contained in ``PartFactory.default_part_type`` - is used to construct the part, which is by default ``opc.package.Part``. - """ - - part_class_selector = None - part_type_for = {} - default_part_type = Part - - def __new__(cls, partname, content_type, reltype, blob, package): - PartClass = None - if cls.part_class_selector is not None: - part_class_selector = cls_method_fn(cls, "part_class_selector") - PartClass = part_class_selector(content_type, reltype) - if PartClass is None: - PartClass = cls._part_cls_for(content_type) - return PartClass.load(partname, content_type, blob, package) - - @classmethod - def _part_cls_for(cls, content_type): - """ - Return the custom part class registered for *content_type*, or the - default part class if no custom class is registered for - *content_type*. - """ - if content_type in cls.part_type_for: - return cls.part_type_for[content_type] - return cls.default_part_type - - -class XmlPart(Part): - """ - Base class for package parts containing an XML payload, which is most of - them. Provides additional methods to the |Part| base class that take care - of parsing and reserializing the XML payload and managing relationships - to other parts. - """ - - def __init__(self, partname, content_type, element, package): - super(XmlPart, self).__init__(partname, content_type, package=package) - self._element = element - - @property - def blob(self): - return serialize_part_xml(self._element) - - @property - def element(self): - """ - The root XML element of this XML part. - """ - return self._element - - @element.setter - def element(self, e): - self._element = e - - @classmethod - def load(cls, partname, content_type, blob, package): - element = parse_xml(blob) - return cls(partname, content_type, element, package) - - @property - def part(self): - """ - Part of the parent protocol, "children" of the document will not know - the part that contains them so must ask their parent object. That - chain of delegation ends here for child objects. - """ - return self diff --git a/docx/opc/parts/coreprops.py b/docx/opc/parts/coreprops.py deleted file mode 100644 index 7e5b8c17..00000000 --- a/docx/opc/parts/coreprops.py +++ /dev/null @@ -1,51 +0,0 @@ -# encoding: utf-8 - -""" -Core properties part, corresponds to ``/docProps/core.xml`` part in package. -""" - -from __future__ import absolute_import, division, print_function, unicode_literals - -from datetime import datetime - -from ..constants import CONTENT_TYPE as CT -from ..coreprops import CoreProperties -from ...oxml.coreprops import CT_CoreProperties -from ..packuri import PackURI -from ..part import XmlPart - - -class CorePropertiesPart(XmlPart): - """ - Corresponds to part named ``/docProps/core.xml``, containing the core - document properties for this document package. - """ - - @classmethod - def default(cls, package): - """ - Return a new |CorePropertiesPart| object initialized with default - values for its base properties. - """ - core_properties_part = cls._new(package) - core_properties = core_properties_part.core_properties - core_properties.title = "Word Document" - core_properties.last_modified_by = "python-docx" - core_properties.revision = 1 - core_properties.modified = datetime.utcnow() - return core_properties_part - - @property - def core_properties(self): - """ - A |CoreProperties| object providing read/write access to the core - properties contained in this core properties part. - """ - return CoreProperties(self.element) - - @classmethod - def _new(cls, package): - partname = PackURI("/docProps/core.xml") - content_type = CT.OPC_CORE_PROPERTIES - coreProperties = CT_CoreProperties.new() - return CorePropertiesPart(partname, content_type, coreProperties, package) diff --git a/docx/opc/pkgwriter.py b/docx/opc/pkgwriter.py deleted file mode 100644 index 1610cbb0..00000000 --- a/docx/opc/pkgwriter.py +++ /dev/null @@ -1,127 +0,0 @@ -# encoding: utf-8 - -""" -Provides a low-level, write-only API to a serialized Open Packaging -Convention (OPC) package, essentially an implementation of OpcPackage.save() -""" - -from __future__ import absolute_import - -from .constants import CONTENT_TYPE as CT -from .oxml import CT_Types, serialize_part_xml -from .packuri import CONTENT_TYPES_URI, PACKAGE_URI -from .phys_pkg import PhysPkgWriter -from .shared import CaseInsensitiveDict -from .spec import default_content_types - - -class PackageWriter(object): - """ - Writes a zip-format OPC package to *pkg_file*, where *pkg_file* can be - either a path to a zip file (a string) or a file-like object. Its single - API method, :meth:`write`, is static, so this class is not intended to - be instantiated. - """ - - @staticmethod - def write(pkg_file, pkg_rels, parts): - """ - Write a physical package (.pptx file) to *pkg_file* containing - *pkg_rels* and *parts* and a content types stream based on the - content types of the parts. - """ - phys_writer = PhysPkgWriter(pkg_file) - PackageWriter._write_content_types_stream(phys_writer, parts) - PackageWriter._write_pkg_rels(phys_writer, pkg_rels) - PackageWriter._write_parts(phys_writer, parts) - phys_writer.close() - - @staticmethod - def _write_content_types_stream(phys_writer, parts): - """ - Write ``[Content_Types].xml`` part to the physical package with an - appropriate content type lookup target for each part in *parts*. - """ - cti = _ContentTypesItem.from_parts(parts) - phys_writer.write(CONTENT_TYPES_URI, cti.blob) - - @staticmethod - def _write_parts(phys_writer, parts): - """ - Write the blob of each part in *parts* to the package, along with a - rels item for its relationships if and only if it has any. - """ - for part in parts: - phys_writer.write(part.partname, part.blob) - if len(part._rels): - phys_writer.write(part.partname.rels_uri, part._rels.xml) - - @staticmethod - def _write_pkg_rels(phys_writer, pkg_rels): - """ - Write the XML rels item for *pkg_rels* ('/_rels/.rels') to the - package. - """ - phys_writer.write(PACKAGE_URI.rels_uri, pkg_rels.xml) - - -class _ContentTypesItem(object): - """ - Service class that composes a content types item ([Content_Types].xml) - based on a list of parts. Not meant to be instantiated directly, its - single interface method is xml_for(), e.g. - ``_ContentTypesItem.xml_for(parts)``. - """ - - def __init__(self): - self._defaults = CaseInsensitiveDict() - self._overrides = dict() - - @property - def blob(self): - """ - Return XML form of this content types item, suitable for storage as - ``[Content_Types].xml`` in an OPC package. - """ - return serialize_part_xml(self._element) - - @classmethod - def from_parts(cls, parts): - """ - Return content types XML mapping each part in *parts* to the - appropriate content type and suitable for storage as - ``[Content_Types].xml`` in an OPC package. - """ - cti = cls() - cti._defaults["rels"] = CT.OPC_RELATIONSHIPS - cti._defaults["xml"] = CT.XML - for part in parts: - cti._add_content_type(part.partname, part.content_type) - return cti - - def _add_content_type(self, partname, content_type): - """ - Add a content type for the part with *partname* and *content_type*, - using a default or override as appropriate. - """ - ext = partname.ext - if (ext.lower(), content_type) in default_content_types: - self._defaults[ext] = content_type - else: - self._overrides[partname] = content_type - - @property - def _element(self): - """ - Return XML form of this content types item, suitable for storage as - ``[Content_Types].xml`` in an OPC package. Although the sequence of - elements is not strictly significant, as an aid to testing and - readability Default elements are sorted by extension and Override - elements are sorted by partname. - """ - _types_elm = CT_Types.new() - for ext in sorted(self._defaults.keys()): - _types_elm.add_default(ext, self._defaults[ext]) - for partname in sorted(self._overrides.keys()): - _types_elm.add_override(partname, self._overrides[partname]) - return _types_elm diff --git a/docx/opc/rel.py b/docx/opc/rel.py deleted file mode 100644 index ab3c5c13..00000000 --- a/docx/opc/rel.py +++ /dev/null @@ -1,181 +0,0 @@ -""" -Relationship-related objects. -""" -from .oxml import CT_Relationships - - -class Relationships(dict): - """ - Collection object for |_Relationship| instances, having list semantics. - """ - - def __init__(self, baseURI): - super(Relationships, self).__init__() - self._baseURI = baseURI - self._target_parts_by_rId = {} - - def add_relationship(self, reltype, target, rId, is_external=False): - """ - Return a newly added |_Relationship| instance. - """ - rel = _Relationship(rId, reltype, target, self._baseURI, is_external) - self[rId] = rel - if not is_external: - self._target_parts_by_rId[rId] = target - return rel - - def get_or_add(self, reltype, target_part): - """ - Return relationship of *reltype* to *target_part*, newly added if not - already present in collection. - """ - rel = self._get_matching(reltype, target_part) - if rel is None: - rId = self._next_rId - rel = self.add_relationship(reltype, target_part, rId) - return rel - - def get_or_add_ext_rel(self, reltype, target_ref): - """ - Return rId of external relationship of *reltype* to *target_ref*, - newly added if not already present in collection. - """ - rel = self._get_matching(reltype, target_ref, is_external=True) - if rel is None: - rId = self._next_rId - rel = self.add_relationship(reltype, target_ref, rId, is_external=True) - return rel.rId - - def part_with_reltype(self, reltype): - """ - Return target part of rel with matching *reltype*, raising |KeyError| - if not found and |ValueError| if more than one matching relationship - is found. - """ - rel = self._get_rel_of_type(reltype) - return rel.target_part - - def parts_with_reltype(self, reltype): - """ - Return target part of rel with matching *reltype*, raising |KeyError| - if not found and |ValueError| if more than one matching relationship - is found. - """ - rels = self._get_rel_of_type(reltype, multiple=True) - return [rel.target_part for rel in rels] - - @property - def related_parts(self): - """ - dict mapping rIds to target parts for all the internal relationships - in the collection. - """ - return self._target_parts_by_rId - - @property - def xml(self): - """ - Serialize this relationship collection into XML suitable for storage - as a .rels file in an OPC package. - """ - rels_elm = CT_Relationships.new() - for rel in self.values(): - rels_elm.add_rel(rel.rId, rel.reltype, rel.target_ref, rel.is_external) - return rels_elm.xml - - def _get_matching(self, reltype, target, is_external=False): - """ - Return relationship of matching *reltype*, *target*, and - *is_external* from collection, or None if not found. - """ - - def matches(rel, reltype, target, is_external): - if rel.reltype != reltype: - return False - if rel.is_external != is_external: - return False - rel_target = rel.target_ref if rel.is_external else rel.target_part - if rel_target != target: - return False - return True - - for rel in self.values(): - if matches(rel, reltype, target, is_external): - return rel - return None - - def _get_rel_of_type(self, reltype, multiple=False): - """ - Return single relationship of type *reltype* from the collection. - Raises |KeyError| if no matching relationship is found. Raises - |ValueError| if more than one matching relationship is found. - """ - matching = [rel for rel in self.values() if rel.reltype == reltype] - if not matching: - tmpl = "no relationship of type '%s' in collection" - raise KeyError(tmpl % reltype) - if multiple: - return matching - if len(matching) > 1: - tmpl = "multiple relationships of type '%s' in collection" - raise ValueError(tmpl % reltype) - return matching[0] - - @property - def _next_rId(self): - """ - Next available rId in collection, starting from 'rId1' and making use - of any gaps in numbering, e.g. 'rId2' for rIds ['rId1', 'rId3']. - """ - for n in range(1, len(self) + 2): - rId_candidate = "rId%d" % n # like 'rId19' - if rId_candidate not in self: - return rId_candidate - - -class _Relationship(object): - """ - Value object for relationship to part. - """ - - def __init__(self, rId, reltype, target, baseURI, external=False): - super(_Relationship, self).__init__() - self._rId = rId - self._reltype = reltype - self._target = target - self._baseURI = baseURI - self._is_external = bool(external) - - @property - def is_external(self): - return self._is_external - - @property - def reltype(self): - return self._reltype - - @property - def rId(self): - return self._rId - - @property - def target_part(self): - if self._is_external: - raise ValueError( - "target_part property on _Relationship is undef" - "ined when target mode is External" - ) - return self._target - - @property - def target_ref(self): - if self._is_external: - return self._target - else: - return self._target.partname.relative_ref(self._baseURI) - - @target_ref.setter - def target_ref(self, ref: str): - if not self._is_external: - raise ValueError("can not set internal target_ref") - self._target = ref diff --git a/docx/opc/shared.py b/docx/opc/shared.py deleted file mode 100644 index 15eed35d..00000000 --- a/docx/opc/shared.py +++ /dev/null @@ -1,46 +0,0 @@ -# encoding: utf-8 - -""" -Objects shared by opc modules. -""" - -from __future__ import absolute_import, print_function, unicode_literals - - -class CaseInsensitiveDict(dict): - """ - Mapping type that behaves like dict except that it matches without respect - to the case of the key. E.g. cid['A'] == cid['a']. Note this is not - general-purpose, just complete enough to satisfy opc package needs. It - assumes str keys, and that it is created empty; keys passed in constructor - are not accounted for - """ - - def __contains__(self, key): - return super(CaseInsensitiveDict, self).__contains__(key.lower()) - - def __getitem__(self, key): - return super(CaseInsensitiveDict, self).__getitem__(key.lower()) - - def __setitem__(self, key, value): - return super(CaseInsensitiveDict, self).__setitem__(key.lower(), value) - - -def lazyproperty(f): - """ - @lazyprop decorator. Decorated method will be called only on first access - to calculate a cached property value. After that, the cached value is - returned. - """ - cache_attr_name = "_%s" % f.__name__ # like '_foobar' for prop 'foobar' - docstring = f.__doc__ - - def get_prop_value(obj): - try: - return getattr(obj, cache_attr_name) - except AttributeError: - value = f(obj) - setattr(obj, cache_attr_name, value) - return value - - return property(get_prop_value, doc=docstring) diff --git a/docx/oxml/document.py b/docx/oxml/document.py deleted file mode 100644 index 5c3e6f2b..00000000 --- a/docx/oxml/document.py +++ /dev/null @@ -1,69 +0,0 @@ -# encoding: utf-8 - -""" -Custom element classes that correspond to the document part, e.g. -. -""" - -from .xmlchemy import BaseOxmlElement, ZeroOrOne, ZeroOrMore - - -class CT_Document(BaseOxmlElement): - """ - ```` element, the root element of a document.xml file. - """ - - body = ZeroOrOne("w:body") - - @property - def sectPr_lst(self): - """ - Return a list containing a reference to each ```` element - in the document, in the order encountered. - """ - return self.xpath(".//w:sectPr") - - -class CT_Body(BaseOxmlElement): - """ - ````, the container element for the main document story in - ``document.xml``. - """ - - p = ZeroOrMore("w:p", successors=("w:sectPr",)) - tbl = ZeroOrMore("w:tbl", successors=("w:sectPr",)) - sectPr = ZeroOrOne("w:sectPr", successors=()) - - def add_section_break(self): - """Return `w:sectPr` element for new section added at end of document. - - The last `w:sectPr` becomes the second-to-last, with the new `w:sectPr` being an - exact clone of the previous one, except that all header and footer references - are removed (and are therefore now "inherited" from the prior section). - - A copy of the previously-last `w:sectPr` will now appear in a new `w:p` at the - end of the document. The returned `w:sectPr` is the sentinel `w:sectPr` for the - document (and as implemented, *is* the prior sentinel `w:sectPr` with headers - and footers removed). - """ - # ---get the sectPr at file-end, which controls last section (sections[-1])--- - sentinel_sectPr = self.get_or_add_sectPr() - # ---add exact copy to new `w:p` element; that is now second-to last section--- - self.add_p().set_sectPr(sentinel_sectPr.clone()) - # ---remove any header or footer references from "new" last section--- - for hdrftr_ref in sentinel_sectPr.xpath("w:headerReference|w:footerReference"): - sentinel_sectPr.remove(hdrftr_ref) - # ---the sentinel `w:sectPr` now controls the new last section--- - return sentinel_sectPr - - def clear_content(self): - """ - Remove all content child elements from this element. Leave - the element if it is present. - """ - if self.sectPr is not None: - content_elms = self[:-1] - else: - content_elms = self[:] - for content_elm in content_elms: - self.remove(content_elm) diff --git a/docx/oxml/exceptions.py b/docx/oxml/exceptions.py deleted file mode 100644 index 4696f1e9..00000000 --- a/docx/oxml/exceptions.py +++ /dev/null @@ -1,16 +0,0 @@ -# encoding: utf-8 - -""" -Exceptions for oxml sub-package -""" - - -class XmlchemyError(Exception): - """Generic error class.""" - - -class InvalidXmlError(XmlchemyError): - """ - Raised when invalid XML is encountered, such as on attempt to access a - missing required child element - """ diff --git a/docx/oxml/section.py b/docx/oxml/section.py deleted file mode 100644 index e7193677..00000000 --- a/docx/oxml/section.py +++ /dev/null @@ -1,370 +0,0 @@ -# encoding: utf-8 - -"""Section-related custom element classes""" - -from __future__ import absolute_import, division, print_function, unicode_literals - -from copy import deepcopy - -from docx.enum.section import WD_HEADER_FOOTER, WD_ORIENTATION, WD_SECTION_START -from docx.oxml.simpletypes import ST_SignedTwipsMeasure, ST_TwipsMeasure, XsdString -from docx.oxml.xmlchemy import ( - BaseOxmlElement, - OptionalAttribute, - RequiredAttribute, - ZeroOrMore, - ZeroOrOne, -) - - -class CT_HdrFtr(BaseOxmlElement): - """`w:hdr` and `w:ftr`, the root element for header and footer part respectively""" - - p = ZeroOrMore("w:p", successors=()) - tbl = ZeroOrMore("w:tbl", successors=()) - - -class CT_HdrFtrRef(BaseOxmlElement): - """`w:headerReference` and `w:footerReference` elements""" - - type_ = RequiredAttribute("w:type", WD_HEADER_FOOTER) - rId = RequiredAttribute("r:id", XsdString) - - -class CT_PageMar(BaseOxmlElement): - """ - ```` element, defining page margins. - """ - - top = OptionalAttribute("w:top", ST_SignedTwipsMeasure) - right = OptionalAttribute("w:right", ST_TwipsMeasure) - bottom = OptionalAttribute("w:bottom", ST_SignedTwipsMeasure) - left = OptionalAttribute("w:left", ST_TwipsMeasure) - header = OptionalAttribute("w:header", ST_TwipsMeasure) - footer = OptionalAttribute("w:footer", ST_TwipsMeasure) - gutter = OptionalAttribute("w:gutter", ST_TwipsMeasure) - - -class CT_PageSz(BaseOxmlElement): - """ - ```` element, defining page dimensions and orientation. - """ - - w = OptionalAttribute("w:w", ST_TwipsMeasure) - h = OptionalAttribute("w:h", ST_TwipsMeasure) - orient = OptionalAttribute( - "w:orient", WD_ORIENTATION, default=WD_ORIENTATION.PORTRAIT - ) - - -class CT_SectPr(BaseOxmlElement): - """`w:sectPr` element, the container element for section properties""" - - _tag_seq = ( - "w:footnotePr", - "w:endnotePr", - "w:type", - "w:pgSz", - "w:pgMar", - "w:paperSrc", - "w:pgBorders", - "w:lnNumType", - "w:pgNumType", - "w:cols", - "w:formProt", - "w:vAlign", - "w:noEndnote", - "w:titlePg", - "w:textDirection", - "w:bidi", - "w:rtlGutter", - "w:docGrid", - "w:printerSettings", - "w:sectPrChange", - ) - headerReference = ZeroOrMore("w:headerReference", successors=_tag_seq) - footerReference = ZeroOrMore("w:footerReference", successors=_tag_seq) - type = ZeroOrOne("w:type", successors=_tag_seq[3:]) - pgSz = ZeroOrOne("w:pgSz", successors=_tag_seq[4:]) - pgMar = ZeroOrOne("w:pgMar", successors=_tag_seq[5:]) - titlePg = ZeroOrOne("w:titlePg", successors=_tag_seq[14:]) - del _tag_seq - - def add_footerReference(self, type_, rId): - """Return newly added CT_HdrFtrRef element of *type_* with *rId*. - - The element tag is `w:footerReference`. - """ - footerReference = self._add_footerReference() - footerReference.type_ = type_ - footerReference.rId = rId - return footerReference - - def add_headerReference(self, type_, rId): - """Return newly added CT_HdrFtrRef element of *type_* with *rId*. - - The element tag is `w:headerReference`. - """ - headerReference = self._add_headerReference() - headerReference.type_ = type_ - headerReference.rId = rId - return headerReference - - @property - def bottom_margin(self): - """ - The value of the ``w:bottom`` attribute in the ```` child - element, as a |Length| object, or |None| if either the element or the - attribute is not present. - """ - pgMar = self.pgMar - if pgMar is None: - return None - return pgMar.bottom - - @bottom_margin.setter - def bottom_margin(self, value): - pgMar = self.get_or_add_pgMar() - pgMar.bottom = value - - def clone(self): - """ - Return an exact duplicate of this ```` element tree - suitable for use in adding a section break. All rsid* attributes are - removed from the root ```` element. - """ - clone_sectPr = deepcopy(self) - clone_sectPr.attrib.clear() - return clone_sectPr - - @property - def footer(self): - """ - The value of the ``w:footer`` attribute in the ```` child - element, as a |Length| object, or |None| if either the element or the - attribute is not present. - """ - pgMar = self.pgMar - if pgMar is None: - return None - return pgMar.footer - - @footer.setter - def footer(self, value): - pgMar = self.get_or_add_pgMar() - pgMar.footer = value - - def get_footerReference(self, type_): - """Return footerReference element of *type_* or None if not present.""" - path = "./w:footerReference[@w:type='%s']" % WD_HEADER_FOOTER.to_xml(type_) - footerReferences = self.xpath(path) - if not footerReferences: - return None - return footerReferences[0] - - def get_headerReference(self, type_): - """Return headerReference element of *type_* or None if not present.""" - matching_headerReferences = self.xpath( - "./w:headerReference[@w:type='%s']" % WD_HEADER_FOOTER.to_xml(type_) - ) - if len(matching_headerReferences) == 0: - return None - return matching_headerReferences[0] - - @property - def gutter(self): - """ - The value of the ``w:gutter`` attribute in the ```` child - element, as a |Length| object, or |None| if either the element or the - attribute is not present. - """ - pgMar = self.pgMar - if pgMar is None: - return None - return pgMar.gutter - - @gutter.setter - def gutter(self, value): - pgMar = self.get_or_add_pgMar() - pgMar.gutter = value - - @property - def header(self): - """ - The value of the ``w:header`` attribute in the ```` child - element, as a |Length| object, or |None| if either the element or the - attribute is not present. - """ - pgMar = self.pgMar - if pgMar is None: - return None - return pgMar.header - - @header.setter - def header(self, value): - pgMar = self.get_or_add_pgMar() - pgMar.header = value - - @property - def left_margin(self): - """ - The value of the ``w:left`` attribute in the ```` child - element, as a |Length| object, or |None| if either the element or the - attribute is not present. - """ - pgMar = self.pgMar - if pgMar is None: - return None - return pgMar.left - - @left_margin.setter - def left_margin(self, value): - pgMar = self.get_or_add_pgMar() - pgMar.left = value - - @property - def orientation(self): - """ - The member of the ``WD_ORIENTATION`` enumeration corresponding to the - value of the ``orient`` attribute of the ```` child element, - or ``WD_ORIENTATION.PORTRAIT`` if not present. - """ - pgSz = self.pgSz - if pgSz is None: - return WD_ORIENTATION.PORTRAIT - return pgSz.orient - - @orientation.setter - def orientation(self, value): - pgSz = self.get_or_add_pgSz() - pgSz.orient = value - - @property - def page_height(self): - """ - Value in EMU of the ``h`` attribute of the ```` child - element, or |None| if not present. - """ - pgSz = self.pgSz - if pgSz is None: - return None - return pgSz.h - - @page_height.setter - def page_height(self, value): - pgSz = self.get_or_add_pgSz() - pgSz.h = value - - @property - def page_width(self): - """ - Value in EMU of the ``w`` attribute of the ```` child - element, or |None| if not present. - """ - pgSz = self.pgSz - if pgSz is None: - return None - return pgSz.w - - @page_width.setter - def page_width(self, value): - pgSz = self.get_or_add_pgSz() - pgSz.w = value - - @property - def preceding_sectPr(self): - """sectPr immediately preceding this one or None if this is the first.""" - # ---[1] predicate returns list of zero or one value--- - preceding_sectPrs = self.xpath("./preceding::w:sectPr[1]") - return preceding_sectPrs[0] if len(preceding_sectPrs) > 0 else None - - def remove_footerReference(self, type_): - """Return rId of w:footerReference child of *type_* after removing it.""" - footerReference = self.get_footerReference(type_) - rId = footerReference.rId - self.remove(footerReference) - return rId - - def remove_headerReference(self, type_): - """Return rId of w:headerReference child of *type_* after removing it.""" - headerReference = self.get_headerReference(type_) - rId = headerReference.rId - self.remove(headerReference) - return rId - - @property - def right_margin(self): - """ - The value of the ``w:right`` attribute in the ```` child - element, as a |Length| object, or |None| if either the element or the - attribute is not present. - """ - pgMar = self.pgMar - if pgMar is None: - return None - return pgMar.right - - @right_margin.setter - def right_margin(self, value): - pgMar = self.get_or_add_pgMar() - pgMar.right = value - - @property - def start_type(self): - """ - The member of the ``WD_SECTION_START`` enumeration corresponding to - the value of the ``val`` attribute of the ```` child element, - or ``WD_SECTION_START.NEW_PAGE`` if not present. - """ - type = self.type - if type is None or type.val is None: - return WD_SECTION_START.NEW_PAGE - return type.val - - @start_type.setter - def start_type(self, value): - if value is None or value is WD_SECTION_START.NEW_PAGE: - self._remove_type() - return - type = self.get_or_add_type() - type.val = value - - @property - def titlePg_val(self): - """Value of `w:titlePg/@val` or |None| if not present""" - titlePg = self.titlePg - if titlePg is None: - return False - return titlePg.val - - @titlePg_val.setter - def titlePg_val(self, value): - if value in [None, False]: - self._remove_titlePg() - else: - self.get_or_add_titlePg().val = value - - @property - def top_margin(self): - """ - The value of the ``w:top`` attribute in the ```` child - element, as a |Length| object, or |None| if either the element or the - attribute is not present. - """ - pgMar = self.pgMar - if pgMar is None: - return None - return pgMar.top - - @top_margin.setter - def top_margin(self, value): - pgMar = self.get_or_add_pgMar() - pgMar.top = value - - -class CT_SectType(BaseOxmlElement): - """ - ```` element, defining the section start type. - """ - - val = OptionalAttribute("w:val", WD_SECTION_START) diff --git a/docx/oxml/shared.py b/docx/oxml/shared.py deleted file mode 100644 index 4981e920..00000000 --- a/docx/oxml/shared.py +++ /dev/null @@ -1,58 +0,0 @@ -# encoding: utf-8 - -""" -Objects shared by modules in the docx.oxml subpackage. -""" - -from __future__ import absolute_import - -from . import OxmlElement -from .ns import qn -from .simpletypes import ST_DecimalNumber, ST_OnOff, ST_String -from .xmlchemy import BaseOxmlElement, OptionalAttribute, RequiredAttribute - - -class CT_DecimalNumber(BaseOxmlElement): - """ - Used for ````, ````, ```` and several - others, containing a text representation of a decimal number (e.g. 42) in - its ``val`` attribute. - """ - - val = RequiredAttribute("w:val", ST_DecimalNumber) - - @classmethod - def new(cls, nsptagname, val): - """ - Return a new ``CT_DecimalNumber`` element having tagname *nsptagname* - and ``val`` attribute set to *val*. - """ - return OxmlElement(nsptagname, attrs={qn("w:val"): str(val)}) - - -class CT_OnOff(BaseOxmlElement): - """ - Used for ````, ```` elements and others, containing a bool-ish - string in its ``val`` attribute, xsd:boolean plus 'on' and 'off'. - """ - - val = OptionalAttribute("w:val", ST_OnOff, default=True) - - -class CT_String(BaseOxmlElement): - """ - Used for ```` and ```` elements and others, - containing a style name in its ``val`` attribute. - """ - - val = RequiredAttribute("w:val", ST_String) - - @classmethod - def new(cls, nsptagname, val): - """ - Return a new ``CT_String`` element with tagname *nsptagname* and - ``val`` attribute set to *val*. - """ - elm = OxmlElement(nsptagname) - elm.val = val - return elm diff --git a/docx/oxml/table.py b/docx/oxml/table.py deleted file mode 100644 index f9423da6..00000000 --- a/docx/oxml/table.py +++ /dev/null @@ -1,948 +0,0 @@ -# encoding: utf-8 - -"""Custom element classes for tables""" - -from __future__ import absolute_import, division, print_function, unicode_literals - -from . import parse_xml -from ..enum.table import WD_CELL_VERTICAL_ALIGNMENT, WD_ROW_HEIGHT_RULE -from ..exceptions import InvalidSpanError -from .ns import nsdecls, qn -from ..shared import Emu, Twips -from .simpletypes import ( - ST_Merge, - ST_TblLayoutType, - ST_TblWidth, - ST_TwipsMeasure, - XsdInt, -) -from .xmlchemy import ( - BaseOxmlElement, - OneAndOnlyOne, - OneOrMore, - OptionalAttribute, - RequiredAttribute, - ZeroOrOne, - ZeroOrMore, -) - - -class CT_Height(BaseOxmlElement): - """ - Used for ```` to specify a row height and row height rule. - """ - - val = OptionalAttribute("w:val", ST_TwipsMeasure) - hRule = OptionalAttribute("w:hRule", WD_ROW_HEIGHT_RULE) - - -class CT_Row(BaseOxmlElement): - """ - ```` element - """ - - tblPrEx = ZeroOrOne("w:tblPrEx") # custom inserter below - trPr = ZeroOrOne("w:trPr") # custom inserter below - tc = ZeroOrMore("w:tc") - - def tc_at_grid_col(self, idx): - """ - The ```` element appearing at grid column *idx*. Raises - |ValueError| if no ``w:tc`` element begins at that grid column. - """ - grid_col = 0 - for tc in self.tc_lst: - if grid_col == idx: - return tc - grid_col += tc.grid_span - if grid_col > idx: - raise ValueError("no cell on grid column %d" % idx) - raise ValueError("index out of bounds") - - @property - def tr_idx(self): - """ - The index of this ```` element within its parent ```` - element. - """ - return self.getparent().tr_lst.index(self) - - @property - def trHeight_hRule(self): - """ - Return the value of `w:trPr/w:trHeight@w:hRule`, or |None| if not - present. - """ - trPr = self.trPr - if trPr is None: - return None - return trPr.trHeight_hRule - - @trHeight_hRule.setter - def trHeight_hRule(self, value): - trPr = self.get_or_add_trPr() - trPr.trHeight_hRule = value - - @property - def trHeight_val(self): - """ - Return the value of `w:trPr/w:trHeight@w:val`, or |None| if not - present. - """ - trPr = self.trPr - if trPr is None: - return None - return trPr.trHeight_val - - @trHeight_val.setter - def trHeight_val(self, value): - trPr = self.get_or_add_trPr() - trPr.trHeight_val = value - - def _insert_tblPrEx(self, tblPrEx): - self.insert(0, tblPrEx) - - def _insert_trPr(self, trPr): - tblPrEx = self.tblPrEx - if tblPrEx is not None: - tblPrEx.addnext(trPr) - else: - self.insert(0, trPr) - - def _new_tc(self): - return CT_Tc.new() - - -class CT_Tbl(BaseOxmlElement): - """ - ```` element - """ - - tblPr = OneAndOnlyOne("w:tblPr") - tblGrid = OneAndOnlyOne("w:tblGrid") - tr = ZeroOrMore("w:tr") - - @property - def bidiVisual_val(self): - """ - Value of `w:tblPr/w:bidiVisual/@w:val` or |None| if not present. - Controls whether table cells are displayed right-to-left or - left-to-right. - """ - bidiVisual = self.tblPr.bidiVisual - if bidiVisual is None: - return None - return bidiVisual.val - - @bidiVisual_val.setter - def bidiVisual_val(self, value): - tblPr = self.tblPr - if value is None: - tblPr._remove_bidiVisual() - else: - tblPr.get_or_add_bidiVisual().val = value - - @property - def col_count(self): - """ - The number of grid columns in this table. - """ - return len(self.tblGrid.gridCol_lst) - - def iter_tcs(self): - """ - Generate each of the `w:tc` elements in this table, left to right and - top to bottom. Each cell in the first row is generated, followed by - each cell in the second row, etc. - """ - for tr in self.tr_lst: - for tc in tr.tc_lst: - yield tc - - @classmethod - def new_tbl(cls, rows, cols, width): - """ - Return a new `w:tbl` element having *rows* rows and *cols* columns - with *width* distributed evenly between the columns. - """ - return parse_xml(cls._tbl_xml(rows, cols, width)) - - @property - def tblStyle_val(self): - """ - Value of `w:tblPr/w:tblStyle/@w:val` (a table style id) or |None| if - not present. - """ - tblStyle = self.tblPr.tblStyle - if tblStyle is None: - return None - return tblStyle.val - - @tblStyle_val.setter - def tblStyle_val(self, styleId): - """ - Set the value of `w:tblPr/w:tblStyle/@w:val` (a table style id) to - *styleId*. If *styleId* is None, remove the `w:tblStyle` element. - """ - tblPr = self.tblPr - tblPr._remove_tblStyle() - if styleId is None: - return - tblPr._add_tblStyle().val = styleId - - @classmethod - def _tbl_xml(cls, rows, cols, width): - col_width = Emu(width / cols) if cols > 0 else Emu(0) - return ( - "\n" - " \n" - ' \n' - ' \n' - " \n" - "%s" # tblGrid - "%s" # trs - "\n" - ) % ( - nsdecls("w"), - cls._tblGrid_xml(cols, col_width), - cls._trs_xml(rows, cols, col_width), - ) - - @classmethod - def _tblGrid_xml(cls, col_count, col_width): - xml = " \n" - for i in range(col_count): - xml += ' \n' % col_width.twips - xml += " \n" - return xml - - @classmethod - def _trs_xml(cls, row_count, col_count, col_width): - xml = "" - for i in range(row_count): - xml += (" \n" "%s" " \n") % cls._tcs_xml( - col_count, col_width - ) - return xml - - @classmethod - def _tcs_xml(cls, col_count, col_width): - xml = "" - for i in range(col_count): - xml += ( - " \n" - " \n" - ' \n' - " \n" - " \n" - " \n" - ) % col_width.twips - return xml - - -class CT_TblGrid(BaseOxmlElement): - """ - ```` element, child of ````, holds ```` - elements that define column count, width, etc. - """ - - gridCol = ZeroOrMore("w:gridCol", successors=("w:tblGridChange",)) - - -class CT_TblGridCol(BaseOxmlElement): - """ - ```` element, child of ````, defines a table - column. - """ - - w = OptionalAttribute("w:w", ST_TwipsMeasure) - - @property - def gridCol_idx(self): - """ - The index of this ```` element within its parent - ```` element. - """ - return self.getparent().gridCol_lst.index(self) - - -class CT_TblLayoutType(BaseOxmlElement): - """ - ```` element, specifying whether column widths are fixed or - can be automatically adjusted based on content. - """ - - type = OptionalAttribute("w:type", ST_TblLayoutType) - - -class CT_TblPr(BaseOxmlElement): - """ - ```` element, child of ````, holds child elements that - define table properties such as style and borders. - """ - - _tag_seq = ( - "w:tblStyle", - "w:tblpPr", - "w:tblOverlap", - "w:bidiVisual", - "w:tblStyleRowBandSize", - "w:tblStyleColBandSize", - "w:tblW", - "w:jc", - "w:tblCellSpacing", - "w:tblInd", - "w:tblBorders", - "w:shd", - "w:tblLayout", - "w:tblCellMar", - "w:tblLook", - "w:tblCaption", - "w:tblDescription", - "w:tblPrChange", - ) - tblStyle = ZeroOrOne("w:tblStyle", successors=_tag_seq[1:]) - bidiVisual = ZeroOrOne("w:bidiVisual", successors=_tag_seq[4:]) - jc = ZeroOrOne("w:jc", successors=_tag_seq[8:]) - tblLayout = ZeroOrOne("w:tblLayout", successors=_tag_seq[13:]) - del _tag_seq - - @property - def alignment(self): - """ - Member of :ref:`WdRowAlignment` enumeration or |None|, based on the - contents of the `w:val` attribute of `./w:jc`. |None| if no `w:jc` - element is present. - """ - jc = self.jc - if jc is None: - return None - return jc.val - - @alignment.setter - def alignment(self, value): - self._remove_jc() - if value is None: - return - jc = self.get_or_add_jc() - jc.val = value - - @property - def autofit(self): - """ - Return |False| if there is a ```` child with ``w:type`` - attribute set to ``'fixed'``. Otherwise return |True|. - """ - tblLayout = self.tblLayout - if tblLayout is None: - return True - return False if tblLayout.type == "fixed" else True - - @autofit.setter - def autofit(self, value): - tblLayout = self.get_or_add_tblLayout() - tblLayout.type = "autofit" if value else "fixed" - - @property - def style(self): - """ - Return the value of the ``val`` attribute of the ```` - child or |None| if not present. - """ - tblStyle = self.tblStyle - if tblStyle is None: - return None - return tblStyle.val - - @style.setter - def style(self, value): - self._remove_tblStyle() - if value is None: - return - self._add_tblStyle(val=value) - - -class CT_TblWidth(BaseOxmlElement): - """ - Used for ```` and ```` elements and many others, to - specify a table-related width. - """ - - # the type for `w` attr is actually ST_MeasurementOrPercent, but using - # XsdInt for now because only dxa (twips) values are being used. It's not - # entirely clear what the semantics are for other values like -01.4mm - w = RequiredAttribute("w:w", XsdInt) - type = RequiredAttribute("w:type", ST_TblWidth) - - @property - def width(self): - """ - Return the EMU length value represented by the combined ``w:w`` and - ``w:type`` attributes. - """ - if self.type != "dxa": - return None - return Twips(self.w) - - @width.setter - def width(self, value): - self.type = "dxa" - self.w = Emu(value).twips - - -class CT_Tc(BaseOxmlElement): - """`w:tc` table cell element""" - - tcPr = ZeroOrOne("w:tcPr") # bunches of successors, overriding insert - p = OneOrMore("w:p") - tbl = OneOrMore("w:tbl") - - @property - def bottom(self): - """ - The row index that marks the bottom extent of the vertical span of - this cell. This is one greater than the index of the bottom-most row - of the span, similar to how a slice of the cell's rows would be - specified. - """ - if self.vMerge is not None: - tc_below = self._tc_below - if tc_below is not None and tc_below.vMerge == ST_Merge.CONTINUE: - return tc_below.bottom - return self._tr_idx + 1 - - def clear_content(self): - """ - Remove all content child elements, preserving the ```` - element if present. Note that this leaves the ```` element in - an invalid state because it doesn't contain at least one block-level - element. It's up to the caller to add a ````child element as the - last content element. - """ - new_children = [] - tcPr = self.tcPr - if tcPr is not None: - new_children.append(tcPr) - self[:] = new_children - - @property - def grid_span(self): - """ - The integer number of columns this cell spans. Determined by - ./w:tcPr/w:gridSpan/@val, it defaults to 1. - """ - tcPr = self.tcPr - if tcPr is None: - return 1 - return tcPr.grid_span - - @grid_span.setter - def grid_span(self, value): - tcPr = self.get_or_add_tcPr() - tcPr.grid_span = value - - def iter_block_items(self): - """ - Generate a reference to each of the block-level content elements in - this cell, in the order they appear. - """ - block_item_tags = (qn("w:p"), qn("w:tbl"), qn("w:sdt")) - for child in self: - if child.tag in block_item_tags: - yield child - - @property - def left(self): - """ - The grid column index at which this ```` element appears. - """ - return self._grid_col - - def merge(self, other_tc): - """ - Return the top-left ```` element of a new span formed by - merging the rectangular region defined by using this tc element and - *other_tc* as diagonal corners. - """ - top, left, height, width = self._span_dimensions(other_tc) - top_tc = self._tbl.tr_lst[top].tc_at_grid_col(left) - top_tc._grow_to(width, height) - return top_tc - - @classmethod - def new(cls): - """ - Return a new ```` element, containing an empty paragraph as the - required EG_BlockLevelElt. - """ - return parse_xml("\n" " \n" "" % nsdecls("w")) - - @property - def right(self): - """ - The grid column index that marks the right-side extent of the - horizontal span of this cell. This is one greater than the index of - the right-most column of the span, similar to how a slice of the - cell's columns would be specified. - """ - return self._grid_col + self.grid_span - - @property - def top(self): - """ - The top-most row index in the vertical span of this cell. - """ - if self.vMerge is None or self.vMerge == ST_Merge.RESTART: - return self._tr_idx - return self._tc_above.top - - @property - def vMerge(self): - """ - The value of the ./w:tcPr/w:vMerge/@val attribute, or |None| if the - w:vMerge element is not present. - """ - tcPr = self.tcPr - if tcPr is None: - return None - return tcPr.vMerge_val - - @vMerge.setter - def vMerge(self, value): - tcPr = self.get_or_add_tcPr() - tcPr.vMerge_val = value - - @property - def width(self): - """ - Return the EMU length value represented in the ``./w:tcPr/w:tcW`` - child element or |None| if not present. - """ - tcPr = self.tcPr - if tcPr is None: - return None - return tcPr.width - - @width.setter - def width(self, value): - tcPr = self.get_or_add_tcPr() - tcPr.width = value - - def _add_width_of(self, other_tc): - """ - Add the width of *other_tc* to this cell. Does nothing if either this - tc or *other_tc* does not have a specified width. - """ - if self.width and other_tc.width: - self.width += other_tc.width - - @property - def _grid_col(self): - """ - The grid column at which this cell begins. - """ - tr = self._tr - idx = tr.tc_lst.index(self) - preceding_tcs = tr.tc_lst[:idx] - return sum(tc.grid_span for tc in preceding_tcs) - - def _grow_to(self, width, height, top_tc=None): - """ - Grow this cell to *width* grid columns and *height* rows by expanding - horizontal spans and creating continuation cells to form vertical - spans. - """ - - def vMerge_val(top_tc): - if top_tc is not self: - return ST_Merge.CONTINUE - if height == 1: - return None - return ST_Merge.RESTART - - top_tc = self if top_tc is None else top_tc - self._span_to_width(width, top_tc, vMerge_val(top_tc)) - if height > 1: - self._tc_below._grow_to(width, height - 1, top_tc) - - def _insert_tcPr(self, tcPr): - """ - ``tcPr`` has a bunch of successors, but it comes first if it appears, - so just overriding and using insert(0, ...) rather than spelling out - successors. - """ - self.insert(0, tcPr) - return tcPr - - @property - def _is_empty(self): - """ - True if this cell contains only a single empty ```` element. - """ - block_items = list(self.iter_block_items()) - if len(block_items) > 1: - return False - p = block_items[0] # cell must include at least one element - if len(p.r_lst) == 0: - return True - return False - - def _move_content_to(self, other_tc): - """ - Append the content of this cell to *other_tc*, leaving this cell with - a single empty ```` element. - """ - if other_tc is self: - return - if self._is_empty: - return - other_tc._remove_trailing_empty_p() - # appending moves each element from self to other_tc - for block_element in self.iter_block_items(): - other_tc.append(block_element) - # add back the required minimum single empty element - self.append(self._new_p()) - - def _new_tbl(self): - return CT_Tbl.new() - - @property - def _next_tc(self): - """ - The `w:tc` element immediately following this one in this row, or - |None| if this is the last `w:tc` element in the row. - """ - following_tcs = self.xpath("./following-sibling::w:tc") - return following_tcs[0] if following_tcs else None - - def _remove(self): - """ - Remove this `w:tc` element from the XML tree. - """ - self.getparent().remove(self) - - def _remove_trailing_empty_p(self): - """ - Remove the last content element from this cell if it is an empty - ```` element. - """ - block_items = list(self.iter_block_items()) - last_content_elm = block_items[-1] - if last_content_elm.tag != qn("w:p"): - return - p = last_content_elm - if len(p.r_lst) > 0: - return - self.remove(p) - - def _span_dimensions(self, other_tc): - """ - Return a (top, left, height, width) 4-tuple specifying the extents of - the merged cell formed by using this tc and *other_tc* as opposite - corner extents. - """ - - def raise_on_inverted_L(a, b): - if a.top == b.top and a.bottom != b.bottom: - raise InvalidSpanError("requested span not rectangular") - if a.left == b.left and a.right != b.right: - raise InvalidSpanError("requested span not rectangular") - - def raise_on_tee_shaped(a, b): - top_most, other = (a, b) if a.top < b.top else (b, a) - if top_most.top < other.top and top_most.bottom > other.bottom: - raise InvalidSpanError("requested span not rectangular") - - left_most, other = (a, b) if a.left < b.left else (b, a) - if left_most.left < other.left and left_most.right > other.right: - raise InvalidSpanError("requested span not rectangular") - - raise_on_inverted_L(self, other_tc) - raise_on_tee_shaped(self, other_tc) - - top = min(self.top, other_tc.top) - left = min(self.left, other_tc.left) - bottom = max(self.bottom, other_tc.bottom) - right = max(self.right, other_tc.right) - - return top, left, bottom - top, right - left - - def _span_to_width(self, grid_width, top_tc, vMerge): - """ - Incorporate and then remove `w:tc` elements to the right of this one - until this cell spans *grid_width*. Raises |ValueError| if - *grid_width* cannot be exactly achieved, such as when a merged cell - would drive the span width greater than *grid_width* or if not enough - grid columns are available to make this cell that wide. All content - from incorporated cells is appended to *top_tc*. The val attribute of - the vMerge element on the single remaining cell is set to *vMerge*. - If *vMerge* is |None|, the vMerge element is removed if present. - """ - self._move_content_to(top_tc) - while self.grid_span < grid_width: - self._swallow_next_tc(grid_width, top_tc) - self.vMerge = vMerge - - def _swallow_next_tc(self, grid_width, top_tc): - """ - Extend the horizontal span of this `w:tc` element to incorporate the - following `w:tc` element in the row and then delete that following - `w:tc` element. Any content in the following `w:tc` element is - appended to the content of *top_tc*. The width of the following - `w:tc` element is added to this one, if present. Raises - |InvalidSpanError| if the width of the resulting cell is greater than - *grid_width* or if there is no next `` element in the row. - """ - - def raise_on_invalid_swallow(next_tc): - if next_tc is None: - raise InvalidSpanError("not enough grid columns") - if self.grid_span + next_tc.grid_span > grid_width: - raise InvalidSpanError("span is not rectangular") - - next_tc = self._next_tc - raise_on_invalid_swallow(next_tc) - next_tc._move_content_to(top_tc) - self._add_width_of(next_tc) - self.grid_span += next_tc.grid_span - next_tc._remove() - - @property - def _tbl(self): - """ - The tbl element this tc element appears in. - """ - return self.xpath("./ancestor::w:tbl[position()=1]")[0] - - @property - def _tc_above(self): - """ - The `w:tc` element immediately above this one in its grid column. - """ - return self._tr_above.tc_at_grid_col(self._grid_col) - - @property - def _tc_below(self): - """ - The tc element immediately below this one in its grid column. - """ - tr_below = self._tr_below - if tr_below is None: - return None - return tr_below.tc_at_grid_col(self._grid_col) - - @property - def _tr(self): - """ - The tr element this tc element appears in. - """ - return self.xpath("./ancestor::w:tr[position()=1]")[0] - - @property - def _tr_above(self): - """ - The tr element prior in sequence to the tr this cell appears in. - Raises |ValueError| if called on a cell in the top-most row. - """ - tr_lst = self._tbl.tr_lst - tr_idx = tr_lst.index(self._tr) - if tr_idx == 0: - raise ValueError("no tr above topmost tr") - return tr_lst[tr_idx - 1] - - @property - def _tr_below(self): - """ - The tr element next in sequence after the tr this cell appears in, or - |None| if this cell appears in the last row. - """ - tr_lst = self._tbl.tr_lst - tr_idx = tr_lst.index(self._tr) - try: - return tr_lst[tr_idx + 1] - except IndexError: - return None - - @property - def _tr_idx(self): - """ - The row index of the tr element this tc element appears in. - """ - return self._tbl.tr_lst.index(self._tr) - - -class CT_TcPr(BaseOxmlElement): - """ - ```` element, defining table cell properties - """ - - _tag_seq = ( - "w:cnfStyle", - "w:tcW", - "w:gridSpan", - "w:hMerge", - "w:vMerge", - "w:tcBorders", - "w:shd", - "w:noWrap", - "w:tcMar", - "w:textDirection", - "w:tcFitText", - "w:vAlign", - "w:hideMark", - "w:headers", - "w:cellIns", - "w:cellDel", - "w:cellMerge", - "w:tcPrChange", - ) - tcW = ZeroOrOne("w:tcW", successors=_tag_seq[2:]) - gridSpan = ZeroOrOne("w:gridSpan", successors=_tag_seq[3:]) - vMerge = ZeroOrOne("w:vMerge", successors=_tag_seq[5:]) - vAlign = ZeroOrOne("w:vAlign", successors=_tag_seq[12:]) - del _tag_seq - - @property - def grid_span(self): - """ - The integer number of columns this cell spans. Determined by - ./w:gridSpan/@val, it defaults to 1. - """ - gridSpan = self.gridSpan - if gridSpan is None: - return 1 - return gridSpan.val - - @grid_span.setter - def grid_span(self, value): - self._remove_gridSpan() - if value > 1: - self.get_or_add_gridSpan().val = value - - @property - def vAlign_val(self): - """Value of `w:val` attribute on `w:vAlign` child. - - Value is |None| if `w:vAlign` child is not present. The `w:val` - attribute on `w:vAlign` is required. - """ - vAlign = self.vAlign - if vAlign is None: - return None - return vAlign.val - - @vAlign_val.setter - def vAlign_val(self, value): - if value is None: - self._remove_vAlign() - return - self.get_or_add_vAlign().val = value - - @property - def vMerge_val(self): - """ - The value of the ./w:vMerge/@val attribute, or |None| if the - w:vMerge element is not present. - """ - vMerge = self.vMerge - if vMerge is None: - return None - return vMerge.val - - @vMerge_val.setter - def vMerge_val(self, value): - self._remove_vMerge() - if value is not None: - self._add_vMerge().val = value - - @property - def width(self): - """ - Return the EMU length value represented in the ```` child - element or |None| if not present or its type is not 'dxa'. - """ - tcW = self.tcW - if tcW is None: - return None - return tcW.width - - @width.setter - def width(self, value): - tcW = self.get_or_add_tcW() - tcW.width = value - - -class CT_TrPr(BaseOxmlElement): - """ - ```` element, defining table row properties - """ - - _tag_seq = ( - "w:cnfStyle", - "w:divId", - "w:gridBefore", - "w:gridAfter", - "w:wBefore", - "w:wAfter", - "w:cantSplit", - "w:trHeight", - "w:tblHeader", - "w:tblCellSpacing", - "w:jc", - "w:hidden", - "w:ins", - "w:del", - "w:trPrChange", - ) - trHeight = ZeroOrOne("w:trHeight", successors=_tag_seq[8:]) - del _tag_seq - - @property - def trHeight_hRule(self): - """ - Return the value of `w:trHeight@w:hRule`, or |None| if not present. - """ - trHeight = self.trHeight - if trHeight is None: - return None - return trHeight.hRule - - @trHeight_hRule.setter - def trHeight_hRule(self, value): - if value is None and self.trHeight is None: - return - trHeight = self.get_or_add_trHeight() - trHeight.hRule = value - - @property - def trHeight_val(self): - """ - Return the value of `w:trHeight@w:val`, or |None| if not present. - """ - trHeight = self.trHeight - if trHeight is None: - return None - return trHeight.val - - @trHeight_val.setter - def trHeight_val(self, value): - if value is None and self.trHeight is None: - return - trHeight = self.get_or_add_trHeight() - trHeight.val = value - - -class CT_VerticalJc(BaseOxmlElement): - """`w:vAlign` element, specifying vertical alignment of cell.""" - - val = RequiredAttribute("w:val", WD_CELL_VERTICAL_ALIGNMENT) - - -class CT_VMerge(BaseOxmlElement): - """ - ```` element, specifying vertical merging behavior of a cell. - """ - - val = OptionalAttribute("w:val", ST_Merge, default=ST_Merge.CONTINUE) diff --git a/docx/oxml/text/font.py b/docx/oxml/text/font.py deleted file mode 100644 index 068d7e1f..00000000 --- a/docx/oxml/text/font.py +++ /dev/null @@ -1,377 +0,0 @@ -# encoding: utf-8 - -""" -Custom element classes related to run properties (font). -""" - -from .. import parse_xml -from ...enum.dml import MSO_THEME_COLOR -from ...enum.text import WD_COLOR, WD_UNDERLINE -from ..ns import nsdecls, qn -from ..simpletypes import ST_HexColor, ST_HpsMeasure, ST_String, ST_VerticalAlignRun -from ..xmlchemy import BaseOxmlElement, OptionalAttribute, RequiredAttribute, ZeroOrOne - - -class CT_Color(BaseOxmlElement): - """ - `w:color` element, specifying the color of a font and perhaps other - objects. - """ - - val = RequiredAttribute("w:val", ST_HexColor) - themeColor = OptionalAttribute("w:themeColor", MSO_THEME_COLOR) - - -class CT_Fonts(BaseOxmlElement): - """ - ```` element, specifying typeface name for the various language - types. - """ - - ascii = OptionalAttribute("w:ascii", ST_String) - hAnsi = OptionalAttribute("w:hAnsi", ST_String) - eastAsia = OptionalAttribute("w:eastAsia", ST_String) - - -class CT_Highlight(BaseOxmlElement): - """ - `w:highlight` element, specifying font highlighting/background color. - """ - - val = RequiredAttribute("w:val", WD_COLOR) - - -class CT_HpsMeasure(BaseOxmlElement): - """ - Used for ```` element and others, specifying font size in - half-points. - """ - - val = RequiredAttribute("w:val", ST_HpsMeasure) - - -class CT_RPr(BaseOxmlElement): - """ - ```` element, containing the properties for a run. - """ - - _tag_seq = ( - "w:rStyle", - "w:rFonts", - "w:b", - "w:bCs", - "w:i", - "w:iCs", - "w:caps", - "w:smallCaps", - "w:strike", - "w:dstrike", - "w:outline", - "w:shadow", - "w:emboss", - "w:imprint", - "w:noProof", - "w:snapToGrid", - "w:vanish", - "w:webHidden", - "w:color", - "w:spacing", - "w:w", - "w:kern", - "w:position", - "w:sz", - "w:szCs", - "w:highlight", - "w:u", - "w:effect", - "w:bdr", - "w:shd", - "w:fitText", - "w:vertAlign", - "w:rtl", - "w:cs", - "w:em", - "w:lang", - "w:eastAsianLayout", - "w:specVanish", - "w:oMath", - ) - rStyle = ZeroOrOne("w:rStyle", successors=_tag_seq[1:]) - rFonts = ZeroOrOne("w:rFonts", successors=_tag_seq[2:]) - b = ZeroOrOne("w:b", successors=_tag_seq[3:]) - bCs = ZeroOrOne("w:bCs", successors=_tag_seq[4:]) - i = ZeroOrOne("w:i", successors=_tag_seq[5:]) - iCs = ZeroOrOne("w:iCs", successors=_tag_seq[6:]) - caps = ZeroOrOne("w:caps", successors=_tag_seq[7:]) - smallCaps = ZeroOrOne("w:smallCaps", successors=_tag_seq[8:]) - strike = ZeroOrOne("w:strike", successors=_tag_seq[9:]) - dstrike = ZeroOrOne("w:dstrike", successors=_tag_seq[10:]) - outline = ZeroOrOne("w:outline", successors=_tag_seq[11:]) - shadow = ZeroOrOne("w:shadow", successors=_tag_seq[12:]) - emboss = ZeroOrOne("w:emboss", successors=_tag_seq[13:]) - imprint = ZeroOrOne("w:imprint", successors=_tag_seq[14:]) - noProof = ZeroOrOne("w:noProof", successors=_tag_seq[15:]) - snapToGrid = ZeroOrOne("w:snapToGrid", successors=_tag_seq[16:]) - vanish = ZeroOrOne("w:vanish", successors=_tag_seq[17:]) - webHidden = ZeroOrOne("w:webHidden", successors=_tag_seq[18:]) - color = ZeroOrOne("w:color", successors=_tag_seq[19:]) - sz = ZeroOrOne("w:sz", successors=_tag_seq[24:]) - highlight = ZeroOrOne("w:highlight", successors=_tag_seq[26:]) - u = ZeroOrOne("w:u", successors=_tag_seq[27:]) - vertAlign = ZeroOrOne("w:vertAlign", successors=_tag_seq[32:]) - rtl = ZeroOrOne("w:rtl", successors=_tag_seq[33:]) - cs = ZeroOrOne("w:cs", successors=_tag_seq[34:]) - specVanish = ZeroOrOne("w:specVanish", successors=_tag_seq[38:]) - oMath = ZeroOrOne("w:oMath", successors=_tag_seq[39:]) - del _tag_seq - - def _new_color(self): - """ - Override metaclass method to set `w:color/@val` to RGB black on - create. - """ - return parse_xml('' % nsdecls("w")) - - @property - def highlight_val(self): - """ - Value of `w:highlight/@val` attribute, specifying a font's highlight - color, or `None` if the text is not highlighted. - """ - highlight = self.highlight - if highlight is None: - return None - return highlight.val - - @highlight_val.setter - def highlight_val(self, value): - if value is None: - self._remove_highlight() - return - highlight = self.get_or_add_highlight() - highlight.val = value - - @property - def rFonts_ascii(self): - """ - The value of `w:rFonts/@w:ascii` or |None| if not present. Represents - the assigned typeface name. The rFonts element also specifies other - special-case typeface names; this method handles the case where just - the common name is required. - """ - rFonts = self.rFonts - if rFonts is None: - return None - return rFonts.ascii - - @rFonts_ascii.setter - def rFonts_ascii(self, value): - if value is None: - self._remove_rFonts() - return - rFonts = self.get_or_add_rFonts() - rFonts.ascii = value - - @property - def rFonts_hAnsi(self): - """ - The value of `w:rFonts/@w:hAnsi` or |None| if not present. - """ - rFonts = self.rFonts - if rFonts is None: - return None - return rFonts.hAnsi - - @rFonts_hAnsi.setter - def rFonts_hAnsi(self, value): - if value is None and self.rFonts is None: - return - rFonts = self.get_or_add_rFonts() - rFonts.hAnsi = value - - @property - def rFonts_eastAsia(self): - """ - The value of `w:rFonts/@w:eastAsia` or |None| if not present. Represents - the assigned typeface name. The rFonts element also specifies other - special-case typeface names; this method handles the case where just - the common name is required. - """ - rFonts = self.rFonts - if rFonts is None: - return None - return rFonts.eastAsia - - @rFonts_eastAsia.setter - def rFonts_eastAsia(self, value): - if value is None: - self._remove_rFonts() - return - rFonts = self.get_or_add_rFonts() - rFonts.eastAsia = value - - @property - def style(self): - """ - String contained in child, or None if that element is not - present. - """ - rStyle = self.rStyle - if rStyle is None: - return None - return rStyle.val - - @style.setter - def style(self, style): - """ - Set val attribute of child element to *style*, adding a - new element if necessary. If *style* is |None|, remove the - element if present. - """ - if style is None: - self._remove_rStyle() - elif self.rStyle is None: - self._add_rStyle(val=style) - else: - self.rStyle.val = style - - @property - def subscript(self): - """ - |True| if `w:vertAlign/@w:val` is 'subscript'. |False| if - `w:vertAlign/@w:val` contains any other value. |None| if - `w:vertAlign` is not present. - """ - vertAlign = self.vertAlign - if vertAlign is None: - return None - if vertAlign.val == ST_VerticalAlignRun.SUBSCRIPT: - return True - return False - - @subscript.setter - def subscript(self, value): - if value is None: - self._remove_vertAlign() - elif bool(value) is True: - self.get_or_add_vertAlign().val = ST_VerticalAlignRun.SUBSCRIPT - elif self.vertAlign is None: - return - elif self.vertAlign.val == ST_VerticalAlignRun.SUBSCRIPT: - self._remove_vertAlign() - - @property - def superscript(self): - """ - |True| if `w:vertAlign/@w:val` is 'superscript'. |False| if - `w:vertAlign/@w:val` contains any other value. |None| if - `w:vertAlign` is not present. - """ - vertAlign = self.vertAlign - if vertAlign is None: - return None - if vertAlign.val == ST_VerticalAlignRun.SUPERSCRIPT: - return True - return False - - @superscript.setter - def superscript(self, value): - if value is None: - self._remove_vertAlign() - elif bool(value) is True: - self.get_or_add_vertAlign().val = ST_VerticalAlignRun.SUPERSCRIPT - elif self.vertAlign is None: - return - elif self.vertAlign.val == ST_VerticalAlignRun.SUPERSCRIPT: - self._remove_vertAlign() - - @property - def sz_val(self): - """ - The value of `w:sz/@w:val` or |None| if not present. - """ - sz = self.sz - if sz is None: - return None - return sz.val - - @sz_val.setter - def sz_val(self, value): - if value is None: - self._remove_sz() - return - sz = self.get_or_add_sz() - sz.val = value - - @property - def u_val(self): - """ - Value of `w:u/@val`, or None if not present. - """ - u = self.u - if u is None: - return None - return u.val - - @u_val.setter - def u_val(self, value): - self._remove_u() - if value is not None: - self._add_u().val = value - - def _get_bool_val(self, name): - """ - Return the value of the boolean child element having *name*, e.g. - 'b', 'i', and 'smallCaps'. - """ - element = getattr(self, name) - if element is None: - return None - return element.val - - def _set_bool_val(self, name, value): - if value is None: - getattr(self, "_remove_%s" % name)() - return - element = getattr(self, "get_or_add_%s" % name)() - element.val = value - - -class CT_Underline(BaseOxmlElement): - """ - ```` element, specifying the underlining style for a run. - """ - - @property - def val(self): - """ - The underline type corresponding to the ``w:val`` attribute value. - """ - val = self.get(qn("w:val")) - underline = WD_UNDERLINE.from_xml(val) - if underline == WD_UNDERLINE.SINGLE: - return True - if underline == WD_UNDERLINE.NONE: - return False - return underline - - @val.setter - def val(self, value): - # works fine without these two mappings, but only because True == 1 - # and False == 0, which happen to match the mapping for WD_UNDERLINE - # .SINGLE and .NONE respectively. - if value is True: - value = WD_UNDERLINE.SINGLE - elif value is False: - value = WD_UNDERLINE.NONE - - val = WD_UNDERLINE.to_xml(value) - self.set(qn("w:val"), val) - - -class CT_VerticalAlignRun(BaseOxmlElement): - """ - ```` element, specifying subscript or superscript. - """ - - val = RequiredAttribute("w:val", ST_VerticalAlignRun) diff --git a/docx/oxml/text/paragraph.py b/docx/oxml/text/paragraph.py deleted file mode 100644 index 8386420f..00000000 --- a/docx/oxml/text/paragraph.py +++ /dev/null @@ -1,79 +0,0 @@ -# encoding: utf-8 - -""" -Custom element classes related to paragraphs (CT_P). -""" - -from ..ns import qn -from ..xmlchemy import BaseOxmlElement, OxmlElement, ZeroOrMore, ZeroOrOne - - -class CT_P(BaseOxmlElement): - """ - ```` element, containing the properties and text for a paragraph. - """ - - pPr = ZeroOrOne("w:pPr") - r = ZeroOrMore("w:r") - - def _insert_pPr(self, pPr): - self.insert(0, pPr) - return pPr - - def add_p_before(self): - """ - Return a new ```` element inserted directly prior to this one. - """ - new_p = OxmlElement("w:p") - self.addprevious(new_p) - return new_p - - @property - def alignment(self): - """ - The value of the ```` grandchild element or |None| if not - present. - """ - pPr = self.pPr - if pPr is None: - return None - return pPr.jc_val - - @alignment.setter - def alignment(self, value): - pPr = self.get_or_add_pPr() - pPr.jc_val = value - - def clear_content(self): - """ - Remove all child elements, except the ```` element if present. - """ - for child in self[:]: - if child.tag == qn("w:pPr"): - continue - self.remove(child) - - def set_sectPr(self, sectPr): - """ - Unconditionally replace or add *sectPr* as a grandchild in the - correct sequence. - """ - pPr = self.get_or_add_pPr() - pPr._remove_sectPr() - pPr._insert_sectPr(sectPr) - - @property - def style(self): - """ - String contained in w:val attribute of ./w:pPr/w:pStyle grandchild, - or |None| if not present. - """ - pPr = self.pPr - if pPr is None: - return None - return pPr.style - - @style.setter - def style(self, style): - pPr = self.get_or_add_pPr() - pPr.style = style diff --git a/docx/oxml/text/run.py b/docx/oxml/text/run.py deleted file mode 100644 index a2667c6b..00000000 --- a/docx/oxml/text/run.py +++ /dev/null @@ -1,164 +0,0 @@ -""" -Custom element classes related to text runs (CT_R). -""" -from ..ns import qn -from ..simpletypes import ST_BrClear, ST_BrType -from ..xmlchemy import BaseOxmlElement, OptionalAttribute, ZeroOrMore, ZeroOrOne - - -class CT_Br(BaseOxmlElement): - """ - ```` element, indicating a line, page, or column break in a run. - """ - - type = OptionalAttribute("w:type", ST_BrType) - clear = OptionalAttribute("w:clear", ST_BrClear) - - -class CT_R(BaseOxmlElement): - """ - ```` element, containing the properties and text for a run. - """ - - rPr = ZeroOrOne("w:rPr") - t = ZeroOrMore("w:t") - br = ZeroOrMore("w:br") - cr = ZeroOrMore("w:cr") - tab = ZeroOrMore("w:tab") - drawing = ZeroOrMore("w:drawing") - - def _insert_rPr(self, rPr): - self.insert(0, rPr) - return rPr - - def add_t(self, text): - """ - Return a newly added ```` element containing *text*. - """ - t = self._add_t(text=text) - if len(text.strip()) < len(text): - t.set(qn("xml:space"), "preserve") - return t - - def add_drawing(self, inline_or_anchor): - """ - Return a newly appended ``CT_Drawing`` (````) child - element having *inline_or_anchor* as its child. - """ - drawing = self._add_drawing() - drawing.append(inline_or_anchor) - return drawing - - def clear_content(self): - """ - Remove all child elements except the ```` element if present. - """ - content_child_elms = self[1:] if self.rPr is not None else self[:] - for child in content_child_elms: - self.remove(child) - - @property - def style(self): - """ - String contained in w:val attribute of grandchild, or - |None| if that element is not present. - """ - rPr = self.rPr - if rPr is None: - return None - return rPr.style - - @style.setter - def style(self, style): - """ - Set the character style of this element to *style*. If *style* - is None, remove the style element. - """ - rPr = self.get_or_add_rPr() - rPr.style = style - - @property - def texts(self): - """ - A string representing the textual content of this run, with content - child elements like ```` translated to their Python - equivalent. - """ - text = "" - for child in self: - if child.tag == qn("w:t"): - t_text = child.text - text += t_text if t_text is not None else "" - elif child.tag == qn("w:tab"): - text += "\t" - elif child.tag in (qn("w:br"), qn("w:cr")): - text += "\n" - return text - - @texts.setter - def texts(self, text): - self.clear_content() - _RunContentAppender.append_to_run_from_text(self, text) - - -class CT_Text(BaseOxmlElement): - """ - ```` element, containing a sequence of characters within a run. - """ - - -class _RunContentAppender(object): - """ - Service object that knows how to translate a Python string into run - content elements appended to a specified ```` element. Contiguous - sequences of regular characters are appended in a single ```` - element. Each tab character ('\t') causes a ```` element to be - appended. Likewise a newline or carriage return character ('\n', '\r') - causes a ```` element to be appended. - """ - - def __init__(self, r): - self._r = r - self._bfr = [] - - @classmethod - def append_to_run_from_text(cls, r, text): - """ - Create a "one-shot" ``_RunContentAppender`` instance and use it to - append the run content elements corresponding to *text* to the - ```` element *r*. - """ - appender = cls(r) - appender.add_text(text) - - def add_text(self, text): - """ - Append the run content elements corresponding to *text* to the - ```` element of this instance. - """ - for char in text: - self.add_char(char) - self.flush() - - def add_char(self, char): - """ - Process the next character of input through the translation finite - state maching (FSM). There are two possible states, buffer pending - and not pending, but those are hidden behind the ``.flush()`` method - which must be called at the end of text to ensure any pending - ```` element is written. - """ - if char == "\t": - self.flush() - self._r.add_tab() - elif char in "\r\n": - self.flush() - self._r.add_br() - else: - self._bfr.append(char) - - def flush(self): - text = "".join(self._bfr) - if text: - self._r.add_t(text) - del self._bfr[:] diff --git a/docx/parts/document.py b/docx/parts/document.py deleted file mode 100644 index cef39b95..00000000 --- a/docx/parts/document.py +++ /dev/null @@ -1,181 +0,0 @@ -""" - |DocumentPart| and closely related objects -""" -from docx.document import Document -from docx.opc.constants import CONTENT_TYPE as CT -from docx.opc.constants import RELATIONSHIP_TYPE as RT -from docx.parts.customxml import CustomXmlPart -from docx.parts.hdrftr import FooterPart, HeaderPart -from docx.parts.numbering import NumberingPart -from docx.parts.settings import SettingsPart -from docx.parts.story import BaseStoryPart -from docx.parts.styles import StylesPart -from docx.shape import InlineShapes -from docx.shared import lazyproperty - - -class DocumentPart(BaseStoryPart): - """Main document part of a WordprocessingML (WML) package, aka a .docx file. - - Acts as broker to other parts such as image, core properties, and style parts. It - also acts as a convenient delegate when a mid-document object needs a service - involving a remote ancestor. The `Parented.part` property inherited by many content - objects provides access to this part object for that purpose. - """ - - def add_footer_part(self): - """Return (footer_part, rId) pair for newly-created footer part.""" - footer_part = FooterPart.new(self.package) - rId = self.relate_to(footer_part, RT.FOOTER) - return footer_part, rId - - def add_header_part(self): - """Return (header_part, rId) pair for newly-created header part.""" - header_part = HeaderPart.new(self.package) - rId = self.relate_to(header_part, RT.HEADER) - return header_part, rId - - @property - def core_properties(self): - """ - A |CoreProperties| object providing read/write access to the core - properties of this document. - """ - return self.package.core_properties - - @property - def custom_properties(self): - """ - A |CustomProperties| object providing read/write access to the custom - properties of this document. - """ - return self.package.custom_properties - - @property - def custom_xml_parts(self) -> list[CustomXmlPart]: - """ - A |CustomXmlPart| object providing access to the customXml/*.xml - for this document. - """ - try: - return self.rels.parts_with_reltype(RT.CUSTOM_XML) - except KeyError: - return [] - - def add_custom_xml_part( - self, xml: str, file_name: str = "item1", content_type: str = CT.XML - ) -> CustomXmlPart: - """ - Add a file in /customXml/*file_name*.xml with default content *xml* - """ - part = CustomXmlPart.default(file_name, content_type, xml, self.package) - return self.rels.get_or_add(RT.CUSTOM_XML, part).target_part - - @property - def document(self): - """ - A |Document| object providing access to the content of this document. - """ - return Document(self._element, self) - - def drop_header_part(self, rId): - """Remove related header part identified by *rId*.""" - self.drop_rel(rId) - - def footer_part(self, rId): - """Return |FooterPart| related by *rId*.""" - return self.related_parts[rId] - - def get_style(self, style_id, style_type): - """ - Return the style in this document matching *style_id*. Returns the - default style for *style_type* if *style_id* is |None| or does not - match a defined style of *style_type*. - """ - return self.styles.get_by_id(style_id, style_type) - - def get_style_id(self, style_or_name, style_type): - """ - Return the style_id (|str|) of the style of *style_type* matching - *style_or_name*. Returns |None| if the style resolves to the default - style for *style_type* or if *style_or_name* is itself |None|. Raises - if *style_or_name* is a style of the wrong type or names a style not - present in the document. - """ - return self.styles.get_style_id(style_or_name, style_type) - - def header_part(self, rId): - """Return |HeaderPart| related by *rId*.""" - return self.related_parts[rId] - - @lazyproperty - def inline_shapes(self): - """ - The |InlineShapes| instance containing the inline shapes in the - document. - """ - return InlineShapes(self._element.body, self) - - @lazyproperty - def numbering_part(self): - """ - A |NumberingPart| object providing access to the numbering - definitions for this document. Creates an empty numbering part if one - is not present. - """ - try: - return self.part_related_by(RT.NUMBERING) - except KeyError: - numbering_part = NumberingPart.default(self.package) - self.relate_to(numbering_part, RT.NUMBERING) - return numbering_part - - def save(self, path_or_stream): - """ - Save this document to *path_or_stream*, which can be either a path to - a filesystem location (a string) or a file-like object. - """ - self.package.save(path_or_stream) - - @property - def settings(self): - """ - A |Settings| object providing access to the settings in the settings - part of this document. - """ - return self._settings_part.settings - - @property - def styles(self): - """ - A |Styles| object providing access to the styles in the styles part - of this document. - """ - return self._styles_part.styles - - @property - def _settings_part(self): - """ - A |SettingsPart| object providing access to the document-level - settings for this document. Creates a default settings part if one is - not present. - """ - try: - return self.part_related_by(RT.SETTINGS) - except KeyError: - settings_part = SettingsPart.default(self.package) - self.relate_to(settings_part, RT.SETTINGS) - return settings_part - - @property - def _styles_part(self): - """ - Instance of |StylesPart| for this document. Creates an empty styles - part if one is not present. - """ - try: - return self.part_related_by(RT.STYLES) - except KeyError: - styles_part = StylesPart.default(self.package) - self.relate_to(styles_part, RT.STYLES) - return styles_part diff --git a/docx/parts/image.py b/docx/parts/image.py deleted file mode 100644 index a235b465..00000000 --- a/docx/parts/image.py +++ /dev/null @@ -1,88 +0,0 @@ -# encoding: utf-8 - -""" -The proxy class for an image part, and related objects. -""" - -from __future__ import absolute_import, division, print_function, unicode_literals - -import hashlib - -from docx.image.image import Image -from docx.opc.part import Part -from docx.shared import Emu, Inches - - -class ImagePart(Part): - """ - An image part. Corresponds to the target part of a relationship with type - RELATIONSHIP_TYPE.IMAGE. - """ - - def __init__(self, partname, content_type, blob, image=None): - super(ImagePart, self).__init__(partname, content_type, blob) - self._image = image - - @property - def default_cx(self): - """ - Native width of this image, calculated from its width in pixels and - horizontal dots per inch (dpi). - """ - px_width = self.image.px_width - horz_dpi = self.image.horz_dpi - width_in_inches = px_width / horz_dpi - return Inches(width_in_inches) - - @property - def default_cy(self): - """ - Native height of this image, calculated from its height in pixels and - vertical dots per inch (dpi). - """ - px_height = self.image.px_height - horz_dpi = self.image.horz_dpi - height_in_emu = 914400 * px_height / horz_dpi - return Emu(height_in_emu) - - @property - def filename(self): - """ - Filename from which this image part was originally created. A generic - name, e.g. 'image.png', is substituted if no name is available, for - example when the image was loaded from an unnamed stream. In that - case a default extension is applied based on the detected MIME type - of the image. - """ - if self._image is not None: - return self._image.filename - return "image.%s" % self.partname.ext - - @classmethod - def from_image(cls, image, partname): - """ - Return an |ImagePart| instance newly created from *image* and - assigned *partname*. - """ - return ImagePart(partname, image.content_type, image.blob, image) - - @property - def image(self): - if self._image is None: - self._image = Image.from_blob(self.blob) - return self._image - - @classmethod - def load(cls, partname, content_type, blob, package): - """ - Called by ``docx.opc.package.PartFactory`` to load an image part from - a package being opened by ``Document(...)`` call. - """ - return cls(partname, content_type, blob) - - @property - def sha1(self): - """ - SHA1 hash digest of the blob of this image part. - """ - return hashlib.sha1(self._blob).hexdigest() diff --git a/docx/parts/settings.py b/docx/parts/settings.py deleted file mode 100644 index e0f751b3..00000000 --- a/docx/parts/settings.py +++ /dev/null @@ -1,52 +0,0 @@ -# encoding: utf-8 - -""" -|SettingsPart| and closely related objects -""" - -from __future__ import absolute_import, division, print_function, unicode_literals - -import os - -from ..opc.constants import CONTENT_TYPE as CT -from ..opc.packuri import PackURI -from ..opc.part import XmlPart -from ..oxml import parse_xml -from ..settings import Settings - - -class SettingsPart(XmlPart): - """ - Document-level settings part of a WordprocessingML (WML) package. - """ - - @classmethod - def default(cls, package): - """ - Return a newly created settings part, containing a default - `w:settings` element tree. - """ - partname = PackURI("/word/settings.xml") - content_type = CT.WML_SETTINGS - element = parse_xml(cls._default_settings_xml()) - return cls(partname, content_type, element, package) - - @property - def settings(self): - """ - A |Settings| proxy object for the `w:settings` element in this part, - containing the document-level settings for this document. - """ - return Settings(self.element) - - @classmethod - def _default_settings_xml(cls): - """ - Return a bytestream containing XML for a default settings part. - """ - path = os.path.join( - os.path.split(__file__)[0], "..", "templates", "default-settings.xml" - ) - with open(path, "rb") as f: - xml_bytes = f.read() - return xml_bytes diff --git a/docx/parts/story.py b/docx/parts/story.py deleted file mode 100644 index b23d2d36..00000000 --- a/docx/parts/story.py +++ /dev/null @@ -1,84 +0,0 @@ -"""|BaseStoryPart| and related objects""" -from docx.opc.constants import RELATIONSHIP_TYPE as RT -from docx.opc.part import XmlPart -from docx.oxml.shape import CT_Anchor, CT_Inline -from docx.shared import lazyproperty - - -class BaseStoryPart(XmlPart): - """Base class for story parts. - - A story part is one that can contain textual content, such as the document-part and - header or footer parts. These all share content behaviors like `.paragraphs`, - `.add_paragraph()`, `.add_table()` etc. - """ - - def get_or_add_image(self, image_descriptor): - """Return (rId, image) pair for image identified by *image_descriptor*. - - *rId* is the str key (often like "rId7") for the relationship between this story - part and the image part, reused if already present, newly created if not. - *image* is an |Image| instance providing access to the properties of the image, - such as dimensions and image type. - """ - image_part = self._package.get_or_add_image_part(image_descriptor) - rId = self.relate_to(image_part, RT.IMAGE) - return rId, image_part.image - - def get_style(self, style_id, style_type): - """Return the style in this document matching *style_id*. - - Returns the default style for *style_type* if *style_id* is |None| or does not - match a defined style of *style_type*. - """ - return self._document_part.get_style(style_id, style_type) - - def get_style_id(self, style_or_name, style_type): - """Return str style_id for *style_or_name* of *style_type*. - - Returns |None| if the style resolves to the default style for *style_type* or if - *style_or_name* is itself |None|. Raises if *style_or_name* is a style of the - wrong type or names a style not present in the document. - """ - return self._document_part.get_style_id(style_or_name, style_type) - - def new_pic_inline(self, image_descriptor, width, height): - """Return a newly-created `w:inline` element. - - The element contains the image specified by *image_descriptor* and is scaled - based on the values of *width* and *height*. - """ - rId, image = self.get_or_add_image(image_descriptor) - cx, cy = image.scaled_dimensions(width, height) - shape_id, filename = self.next_id, image.filename - return CT_Inline.new_pic_inline(shape_id, rId, filename, cx, cy) - - def new_pic_anchor(self, image_descriptor, width, height, pos_x, pos_y): - """Return a newly-created `w:anchor` element. - - The element contains the image specified by *image_descriptor* and is scaled - based on the values of *width* and *height*. - """ - rId, image = self.get_or_add_image(image_descriptor) - cx, cy = image.scaled_dimensions(width, height) - shape_id, filename = self.next_id, image.filename - return CT_Anchor.new_pic_anchor(shape_id, rId, filename, cx, cy, pos_x, pos_y) - - @property - def next_id(self): - """Next available positive integer id value in this story XML document. - - The value is determined by incrementing the maximum existing id value. Gaps in - the existing id sequence are not filled. The id attribute value is unique in the - document, without regard to the element type it appears on. - """ - id_str_lst = self._element.xpath("//@id") - used_ids = [int(id_str) for id_str in id_str_lst if id_str.isdigit()] - if not used_ids: - return 1 - return max(used_ids) + 1 - - @lazyproperty - def _document_part(self): - """|DocumentPart| object for this package.""" - return self.package.main_document_part diff --git a/docx/parts/styles.py b/docx/parts/styles.py deleted file mode 100644 index a16b4188..00000000 --- a/docx/parts/styles.py +++ /dev/null @@ -1,53 +0,0 @@ -# encoding: utf-8 - -""" -Provides StylesPart and related objects -""" - -from __future__ import absolute_import, division, print_function, unicode_literals - -import os - -from ..opc.constants import CONTENT_TYPE as CT -from ..opc.packuri import PackURI -from ..opc.part import XmlPart -from ..oxml import parse_xml -from ..styles.styles import Styles - - -class StylesPart(XmlPart): - """ - Proxy for the styles.xml part containing style definitions for a document - or glossary. - """ - - @classmethod - def default(cls, package): - """ - Return a newly created styles part, containing a default set of - elements. - """ - partname = PackURI("/word/styles.xml") - content_type = CT.WML_STYLES - element = parse_xml(cls._default_styles_xml()) - return cls(partname, content_type, element, package) - - @property - def styles(self): - """ - The |_Styles| instance containing the styles ( element - proxies) for this styles part. - """ - return Styles(self.element) - - @classmethod - def _default_styles_xml(cls): - """ - Return a bytestream containing XML for a default styles part. - """ - path = os.path.join( - os.path.split(__file__)[0], "..", "templates", "default-styles.xml" - ) - with open(path, "rb") as f: - xml_bytes = f.read() - return xml_bytes diff --git a/docx/settings.py b/docx/settings.py deleted file mode 100644 index 502c9d4d..00000000 --- a/docx/settings.py +++ /dev/null @@ -1,28 +0,0 @@ -# encoding: utf-8 - -"""Settings object, providing access to document-level settings""" - -from __future__ import absolute_import, division, print_function, unicode_literals - -from docx.shared import ElementProxy - - -class Settings(ElementProxy): - """Provides access to document-level settings for a document. - - Accessed using the :attr:`.Document.settings` property. - """ - - __slots__ = () - - @property - def odd_and_even_pages_header_footer(self): - """True if this document has distinct odd and even page headers and footers. - - Read/write. - """ - return self._element.evenAndOddHeaders_val - - @odd_and_even_pages_header_footer.setter - def odd_and_even_pages_header_footer(self, value): - self._element.evenAndOddHeaders_val = value diff --git a/docx/shared.py b/docx/shared.py deleted file mode 100644 index ea855a21..00000000 --- a/docx/shared.py +++ /dev/null @@ -1,259 +0,0 @@ -# encoding: utf-8 - -""" -Objects shared by docx modules. -""" - -from __future__ import absolute_import, print_function, unicode_literals - - -class Length(int): - """ - Base class for length constructor classes Inches, Cm, Mm, Px, and Emu. - Behaves as an int count of English Metric Units, 914,400 to the inch, - 36,000 to the mm. Provides convenience unit conversion methods in the form - of read-only properties. Immutable. - """ - - _EMUS_PER_INCH = 914400 - _EMUS_PER_CM = 360000 - _EMUS_PER_MM = 36000 - _EMUS_PER_PT = 12700 - _EMUS_PER_TWIP = 635 - - def __new__(cls, emu): - return int.__new__(cls, emu) - - @property - def cm(self): - """ - The equivalent length expressed in centimeters (float). - """ - return self / float(self._EMUS_PER_CM) - - @property - def emu(self): - """ - The equivalent length expressed in English Metric Units (int). - """ - return self - - @property - def inches(self): - """ - The equivalent length expressed in inches (float). - """ - return self / float(self._EMUS_PER_INCH) - - @property - def mm(self): - """ - The equivalent length expressed in millimeters (float). - """ - return self / float(self._EMUS_PER_MM) - - @property - def pt(self): - """ - Floating point length in points - """ - return self / float(self._EMUS_PER_PT) - - @property - def twips(self): - """ - The equivalent length expressed in twips (int). - """ - return int(round(self / float(self._EMUS_PER_TWIP))) - - -class Inches(Length): - """ - Convenience constructor for length in inches, e.g. - ``width = Inches(0.5)``. - """ - - def __new__(cls, inches): - emu = int(inches * Length._EMUS_PER_INCH) - return Length.__new__(cls, emu) - - -class Cm(Length): - """ - Convenience constructor for length in centimeters, e.g. - ``height = Cm(12)``. - """ - - def __new__(cls, cm): - emu = int(cm * Length._EMUS_PER_CM) - return Length.__new__(cls, emu) - - -class Emu(Length): - """ - Convenience constructor for length in English Metric Units, e.g. - ``width = Emu(457200)``. - """ - - def __new__(cls, emu): - return Length.__new__(cls, int(emu)) - - -class Mm(Length): - """ - Convenience constructor for length in millimeters, e.g. - ``width = Mm(240.5)``. - """ - - def __new__(cls, mm): - emu = int(mm * Length._EMUS_PER_MM) - return Length.__new__(cls, emu) - - -class Pt(Length): - """ - Convenience value class for specifying a length in points - """ - - def __new__(cls, points): - emu = int(points * Length._EMUS_PER_PT) - return Length.__new__(cls, emu) - - -class Twips(Length): - """ - Convenience constructor for length in twips, e.g. ``width = Twips(42)``. - A twip is a twentieth of a point, 635 EMU. - """ - - def __new__(cls, twips): - emu = int(twips * Length._EMUS_PER_TWIP) - return Length.__new__(cls, emu) - - -class RGBColor(tuple): - """ - Immutable value object defining a particular RGB color. - """ - - def __new__(cls, r, g, b): - msg = "RGBColor() takes three integer values 0-255" - for val in (r, g, b): - if not isinstance(val, int) or val < 0 or val > 255: - raise ValueError(msg) - return super(RGBColor, cls).__new__(cls, (r, g, b)) - - def __repr__(self): - return "RGBColor(0x%02x, 0x%02x, 0x%02x)" % self - - def __str__(self): - """ - Return a hex string rgb value, like '3C2F80' - """ - return "%02X%02X%02X" % self - - @classmethod - def from_string(cls, rgb_hex_str): - """ - Return a new instance from an RGB color hex string like ``'3C2F80'``. - """ - r = int(rgb_hex_str[:2], 16) - g = int(rgb_hex_str[2:4], 16) - b = int(rgb_hex_str[4:], 16) - return cls(r, g, b) - - -def lazyproperty(f): - """ - @lazyprop decorator. Decorated method will be called only on first access - to calculate a cached property value. After that, the cached value is - returned. - """ - cache_attr_name = "_%s" % f.__name__ # like '_foobar' for prop 'foobar' - docstring = f.__doc__ - - def get_prop_value(obj): - try: - return getattr(obj, cache_attr_name) - except AttributeError: - value = f(obj) - setattr(obj, cache_attr_name, value) - return value - - return property(get_prop_value, doc=docstring) - - -def write_only_property(f): - """ - @write_only_property decorator. Creates a property (descriptor attribute) - that accepts assignment, but not getattr (use in an expression). - """ - docstring = f.__doc__ - - return property(fset=f, doc=docstring) - - -class ElementProxy(object): - """ - Base class for lxml element proxy classes. An element proxy class is one - whose primary responsibilities are fulfilled by manipulating the - attributes and child elements of an XML element. They are the most common - type of class in python-docx other than custom element (oxml) classes. - """ - - __slots__ = ("_element", "_parent") - - def __init__(self, element, parent=None): - self._element = element - self._parent = parent - - def __eq__(self, other): - """ - Return |True| if this proxy object refers to the same oxml element as - does *other*. ElementProxy objects are value objects and should - maintain no mutable local state. Equality for proxy objects is - defined as referring to the same XML element, whether or not they are - the same proxy object instance. - """ - if not isinstance(other, ElementProxy): - return False - return self._element is other._element - - def __ne__(self, other): - if not isinstance(other, ElementProxy): - return True - return self._element is not other._element - - @property - def element(self): - """ - The lxml element proxied by this object. - """ - return self._element - - @property - def part(self): - """ - The package part containing this object - """ - return self._parent.part - - -class Parented(object): - """ - Provides common services for document elements that occur below a part - but may occasionally require an ancestor object to provide a service, - such as add or drop a relationship. Provides ``self._parent`` attribute - to subclasses. - """ - - def __init__(self, parent): - super(Parented, self).__init__() - self._parent = parent - - @property - def part(self): - """ - The package part containing this object - """ - return self._parent.part diff --git a/docx/styles/__init__.py b/docx/styles/__init__.py deleted file mode 100644 index 61d011d3..00000000 --- a/docx/styles/__init__.py +++ /dev/null @@ -1,48 +0,0 @@ -# encoding: utf-8 - -""" -Sub-package module for docx.styles sub-package. -""" - -from __future__ import absolute_import, division, print_function, unicode_literals - - -class BabelFish(object): - """ - Translates special-case style names from UI name (e.g. Heading 1) to - internal/styles.xml name (e.g. heading 1) and back. - """ - - style_aliases = ( - ("Caption", "caption"), - ("Footer", "footer"), - ("Header", "header"), - ("Heading 1", "heading 1"), - ("Heading 2", "heading 2"), - ("Heading 3", "heading 3"), - ("Heading 4", "heading 4"), - ("Heading 5", "heading 5"), - ("Heading 6", "heading 6"), - ("Heading 7", "heading 7"), - ("Heading 8", "heading 8"), - ("Heading 9", "heading 9"), - ) - - internal_style_names = dict(style_aliases) - ui_style_names = dict((item[1], item[0]) for item in style_aliases) - - @classmethod - def ui2internal(cls, ui_style_name): - """ - Return the internal style name corresponding to *ui_style_name*, such - as 'heading 1' for 'Heading 1'. - """ - return cls.internal_style_names.get(ui_style_name, ui_style_name) - - @classmethod - def internal2ui(cls, internal_style_name): - """ - Return the user interface style name corresponding to - *internal_style_name*, such as 'Heading 1' for 'heading 1'. - """ - return cls.ui_style_names.get(internal_style_name, internal_style_name) diff --git a/docx/styles/latent.py b/docx/styles/latent.py deleted file mode 100644 index 6f723692..00000000 --- a/docx/styles/latent.py +++ /dev/null @@ -1,222 +0,0 @@ -# encoding: utf-8 - -""" -Latent style-related objects. -""" - -from __future__ import absolute_import, division, print_function, unicode_literals - -from . import BabelFish -from ..shared import ElementProxy - - -class LatentStyles(ElementProxy): - """ - Provides access to the default behaviors for latent styles in this - document and to the collection of |_LatentStyle| objects that define - overrides of those defaults for a particular named latent style. - """ - - __slots__ = () - - def __getitem__(self, key): - """ - Enables dictionary-style access to a latent style by name. - """ - style_name = BabelFish.ui2internal(key) - lsdException = self._element.get_by_name(style_name) - if lsdException is None: - raise KeyError("no latent style with name '%s'" % key) - return _LatentStyle(lsdException) - - def __iter__(self): - return (_LatentStyle(ls) for ls in self._element.lsdException_lst) - - def __len__(self): - return len(self._element.lsdException_lst) - - def add_latent_style(self, name): - """ - Return a newly added |_LatentStyle| object to override the inherited - defaults defined in this latent styles object for the built-in style - having *name*. - """ - lsdException = self._element.add_lsdException() - lsdException.name = BabelFish.ui2internal(name) - return _LatentStyle(lsdException) - - @property - def default_priority(self): - """ - Integer between 0 and 99 inclusive specifying the default sort order - for latent styles in style lists and the style gallery. |None| if no - value is assigned, which causes Word to use the default value 99. - """ - return self._element.defUIPriority - - @default_priority.setter - def default_priority(self, value): - self._element.defUIPriority = value - - @property - def default_to_hidden(self): - """ - Boolean specifying whether the default behavior for latent styles is - to be hidden. A hidden style does not appear in the recommended list - or in the style gallery. - """ - return self._element.bool_prop("defSemiHidden") - - @default_to_hidden.setter - def default_to_hidden(self, value): - self._element.set_bool_prop("defSemiHidden", value) - - @property - def default_to_locked(self): - """ - Boolean specifying whether the default behavior for latent styles is - to be locked. A locked style does not appear in the styles panel or - the style gallery and cannot be applied to document content. This - behavior is only active when formatting protection is turned on for - the document (via the Developer menu). - """ - return self._element.bool_prop("defLockedState") - - @default_to_locked.setter - def default_to_locked(self, value): - self._element.set_bool_prop("defLockedState", value) - - @property - def default_to_quick_style(self): - """ - Boolean specifying whether the default behavior for latent styles is - to appear in the style gallery when not hidden. - """ - return self._element.bool_prop("defQFormat") - - @default_to_quick_style.setter - def default_to_quick_style(self, value): - self._element.set_bool_prop("defQFormat", value) - - @property - def default_to_unhide_when_used(self): - """ - Boolean specifying whether the default behavior for latent styles is - to be unhidden when first applied to content. - """ - return self._element.bool_prop("defUnhideWhenUsed") - - @default_to_unhide_when_used.setter - def default_to_unhide_when_used(self, value): - self._element.set_bool_prop("defUnhideWhenUsed", value) - - @property - def load_count(self): - """ - Integer specifying the number of built-in styles to initialize to the - defaults specified in this |LatentStyles| object. |None| if there is - no setting in the XML (very uncommon). The default Word 2011 template - sets this value to 276, accounting for the built-in styles in Word - 2010. - """ - return self._element.count - - @load_count.setter - def load_count(self, value): - self._element.count = value - - -class _LatentStyle(ElementProxy): - """ - Proxy for an `w:lsdException` element, which specifies display behaviors - for a built-in style when no definition for that style is stored yet in - the `styles.xml` part. The values in this element override the defaults - specified in the parent `w:latentStyles` element. - """ - - __slots__ = () - - def delete(self): - """ - Remove this latent style definition such that the defaults defined in - the containing |LatentStyles| object provide the effective value for - each of its attributes. Attempting to access any attributes on this - object after calling this method will raise |AttributeError|. - """ - self._element.delete() - self._element = None - - @property - def hidden(self): - """ - Tri-state value specifying whether this latent style should appear in - the recommended list. |None| indicates the effective value is - inherited from the parent ```` element. - """ - return self._element.on_off_prop("semiHidden") - - @hidden.setter - def hidden(self, value): - self._element.set_on_off_prop("semiHidden", value) - - @property - def locked(self): - """ - Tri-state value specifying whether this latent styles is locked. - A locked style does not appear in the styles panel or the style - gallery and cannot be applied to document content. This behavior is - only active when formatting protection is turned on for the document - (via the Developer menu). - """ - return self._element.on_off_prop("locked") - - @locked.setter - def locked(self, value): - self._element.set_on_off_prop("locked", value) - - @property - def name(self): - """ - The name of the built-in style this exception applies to. - """ - return BabelFish.internal2ui(self._element.name) - - @property - def priority(self): - """ - The integer sort key for this latent style in the Word UI. - """ - return self._element.uiPriority - - @priority.setter - def priority(self, value): - self._element.uiPriority = value - - @property - def quick_style(self): - """ - Tri-state value specifying whether this latent style should appear in - the Word styles gallery when not hidden. |None| indicates the - effective value should be inherited from the default values in its - parent |LatentStyles| object. - """ - return self._element.on_off_prop("qFormat") - - @quick_style.setter - def quick_style(self, value): - self._element.set_on_off_prop("qFormat", value) - - @property - def unhide_when_used(self): - """ - Tri-state value specifying whether this style should have its - :attr:`hidden` attribute set |False| the next time the style is - applied to content. |None| indicates the effective value should be - inherited from the default specified by its parent |LatentStyles| - object. - """ - return self._element.on_off_prop("unhideWhenUsed") - - @unhide_when_used.setter - def unhide_when_used(self, value): - self._element.set_on_off_prop("unhideWhenUsed", value) diff --git a/docx/styles/style.py b/docx/styles/style.py deleted file mode 100644 index ff63a819..00000000 --- a/docx/styles/style.py +++ /dev/null @@ -1,263 +0,0 @@ -# encoding: utf-8 - -""" -Style object hierarchy. -""" - -from __future__ import absolute_import, division, print_function, unicode_literals - -from . import BabelFish -from ..enum.style import WD_STYLE_TYPE -from ..shared import ElementProxy -from ..text.font import Font -from ..text.parfmt import ParagraphFormat - - -def StyleFactory(style_elm): - """ - Return a style object of the appropriate |BaseStyle| subclass, according - to the type of *style_elm*. - """ - style_cls = { - WD_STYLE_TYPE.PARAGRAPH: _ParagraphStyle, - WD_STYLE_TYPE.CHARACTER: _CharacterStyle, - WD_STYLE_TYPE.TABLE: _TableStyle, - WD_STYLE_TYPE.LIST: _NumberingStyle, - }[style_elm.type] - - return style_cls(style_elm) - - -class BaseStyle(ElementProxy): - """ - Base class for the various types of style object, paragraph, character, - table, and numbering. These properties and methods are inherited by all - style objects. - """ - - __slots__ = () - - @property - def builtin(self): - """ - Read-only. |True| if this style is a built-in style. |False| - indicates it is a custom (user-defined) style. Note this value is - based on the presence of a `customStyle` attribute in the XML, not on - specific knowledge of which styles are built into Word. - """ - return not self._element.customStyle - - def delete(self): - """ - Remove this style definition from the document. Note that calling - this method does not remove or change the style applied to any - document content. Content items having the deleted style will be - rendered using the default style, as is any content with a style not - defined in the document. - """ - self._element.delete() - self._element = None - - @property - def hidden(self): - """ - |True| if display of this style in the style gallery and list of - recommended styles is suppressed. |False| otherwise. In order to be - shown in the style gallery, this value must be |False| and - :attr:`.quick_style` must be |True|. - """ - return self._element.semiHidden_val - - @hidden.setter - def hidden(self, value): - self._element.semiHidden_val = value - - @property - def locked(self): - """ - Read/write Boolean. |True| if this style is locked. A locked style - does not appear in the styles panel or the style gallery and cannot - be applied to document content. This behavior is only active when - formatting protection is turned on for the document (via the - Developer menu). - """ - return self._element.locked_val - - @locked.setter - def locked(self, value): - self._element.locked_val = value - - @property - def name(self): - """ - The UI name of this style. - """ - name = self._element.name_val - if name is None: - return None - return BabelFish.internal2ui(name) - - @name.setter - def name(self, value): - self._element.name_val = value - - @property - def priority(self): - """ - The integer sort key governing display sequence of this style in the - Word UI. |None| indicates no setting is defined, causing Word to use - the default value of 0. Style name is used as a secondary sort key to - resolve ordering of styles having the same priority value. - """ - return self._element.uiPriority_val - - @priority.setter - def priority(self, value): - self._element.uiPriority_val = value - - @property - def quick_style(self): - """ - |True| if this style should be displayed in the style gallery when - :attr:`.hidden` is |False|. Read/write Boolean. - """ - return self._element.qFormat_val - - @quick_style.setter - def quick_style(self, value): - self._element.qFormat_val = value - - @property - def style_id(self): - """ - The unique key name (string) for this style. This value is subject to - rewriting by Word and should generally not be changed unless you are - familiar with the internals involved. - """ - return self._element.styleId - - @style_id.setter - def style_id(self, value): - self._element.styleId = value - - @property - def type(self): - """ - Member of :ref:`WdStyleType` corresponding to the type of this style, - e.g. ``WD_STYLE_TYPE.PARAGRAPH``. - """ - type = self._element.type - if type is None: - return WD_STYLE_TYPE.PARAGRAPH - return type - - @property - def unhide_when_used(self): - """ - |True| if an application should make this style visible the next time - it is applied to content. False otherwise. Note that |docx| does not - automatically unhide a style having |True| for this attribute when it - is applied to content. - """ - return self._element.unhideWhenUsed_val - - @unhide_when_used.setter - def unhide_when_used(self, value): - self._element.unhideWhenUsed_val = value - - -class _CharacterStyle(BaseStyle): - """ - A character style. A character style is applied to a |Run| object and - primarily provides character-level formatting via the |Font| object in - its :attr:`.font` property. - """ - - __slots__ = () - - @property - def base_style(self): - """ - Style object this style inherits from or |None| if this style is - not based on another style. - """ - base_style = self._element.base_style - if base_style is None: - return None - return StyleFactory(base_style) - - @base_style.setter - def base_style(self, style): - style_id = style.style_id if style is not None else None - self._element.basedOn_val = style_id - - @property - def font(self): - """ - The |Font| object providing access to the character formatting - properties for this style, such as font name and size. - """ - return Font(self._element) - - -class _ParagraphStyle(_CharacterStyle): - """ - A paragraph style. A paragraph style provides both character formatting - and paragraph formatting such as indentation and line-spacing. - """ - - __slots__ = () - - def __repr__(self): - return "_ParagraphStyle('%s') id: %s" % (self.name, id(self)) - - @property - def next_paragraph_style(self): - """ - |_ParagraphStyle| object representing the style to be applied - automatically to a new paragraph inserted after a paragraph of this - style. Returns self if no next paragraph style is defined. Assigning - |None| or *self* removes the setting such that new paragraphs are - created using this same style. - """ - next_style_elm = self._element.next_style - if next_style_elm is None: - return self - if next_style_elm.type != WD_STYLE_TYPE.PARAGRAPH: - return self - return StyleFactory(next_style_elm) - - @next_paragraph_style.setter - def next_paragraph_style(self, style): - if style is None or style.style_id == self.style_id: - self._element._remove_next() - else: - self._element.get_or_add_next().val = style.style_id - - @property - def paragraph_format(self): - """ - The |ParagraphFormat| object providing access to the paragraph - formatting properties for this style such as indentation. - """ - return ParagraphFormat(self._element) - - -class _TableStyle(_ParagraphStyle): - """ - A table style. A table style provides character and paragraph formatting - for its contents as well as special table formatting properties. - """ - - __slots__ = () - - def __repr__(self): - return "_TableStyle('%s') id: %s" % (self.name, id(self)) - - -class _NumberingStyle(BaseStyle): - """ - A numbering style. Not yet implemented. - """ - - __slots__ = () diff --git a/docx/styles/styles.py b/docx/styles/styles.py deleted file mode 100644 index d09fbd13..00000000 --- a/docx/styles/styles.py +++ /dev/null @@ -1,150 +0,0 @@ -# encoding: utf-8 - -"""Styles object, container for all objects in the styles part""" - -from __future__ import absolute_import, division, print_function, unicode_literals - -from warnings import warn - -from docx.shared import ElementProxy -from docx.styles import BabelFish -from docx.styles.latent import LatentStyles -from docx.styles.style import BaseStyle, StyleFactory - - -class Styles(ElementProxy): - """Provides access to the styles defined in a document. - - Accessed using the :attr:`.Document.styles` property. Supports ``len()``, iteration, - and dictionary-style access by style name. - """ - - __slots__ = () - - def __contains__(self, name): - """ - Enables `in` operator on style name. - """ - internal_name = BabelFish.ui2internal(name) - for style in self._element.style_lst: - if style.name_val == internal_name: - return True - return False - - def __getitem__(self, key): - """ - Enables dictionary-style access by UI name. Lookup by style id is - deprecated, triggers a warning, and will be removed in a near-future - release. - """ - style_elm = self._element.get_by_name(BabelFish.ui2internal(key)) - if style_elm is not None: - return StyleFactory(style_elm) - - style_elm = self._element.get_by_id(key) - if style_elm is not None: - msg = ( - "style lookup by style_id is deprecated. Use style name as " - "key instead." - ) - warn(msg, UserWarning, stacklevel=2) - return StyleFactory(style_elm) - - raise KeyError("no style with name '%s'" % key) - - def __iter__(self): - return (StyleFactory(style) for style in self._element.style_lst) - - def __len__(self): - return len(self._element.style_lst) - - def add_style(self, name, style_type, builtin=False): - """ - Return a newly added style object of *style_type* and identified - by *name*. A builtin style can be defined by passing True for the - optional *builtin* argument. - """ - style_name = BabelFish.ui2internal(name) - if style_name in self: - raise ValueError("document already contains style '%s'" % name) - style = self._element.add_style_of_type(style_name, style_type, builtin) - return StyleFactory(style) - - def default(self, style_type): - """ - Return the default style for *style_type* or |None| if no default is - defined for that type (not common). - """ - style = self._element.default_for(style_type) - if style is None: - return None - return StyleFactory(style) - - def get_by_id(self, style_id, style_type): - """Return the style of *style_type* matching *style_id*. - - Returns the default for *style_type* if *style_id* is not found or is |None|, or - if the style having *style_id* is not of *style_type*. - """ - if style_id is None: - return self.default(style_type) - return self._get_by_id(style_id, style_type) - - def get_style_id(self, style_or_name, style_type): - """ - Return the id of the style corresponding to *style_or_name*, or - |None| if *style_or_name* is |None|. If *style_or_name* is not - a style object, the style is looked up using *style_or_name* as - a style name, raising |ValueError| if no style with that name is - defined. Raises |ValueError| if the target style is not of - *style_type*. - """ - if style_or_name is None: - return None - elif isinstance(style_or_name, BaseStyle): - return self._get_style_id_from_style(style_or_name, style_type) - else: - return self._get_style_id_from_name(style_or_name, style_type) - - @property - def latent_styles(self): - """ - A |LatentStyles| object providing access to the default behaviors for - latent styles and the collection of |_LatentStyle| objects that - define overrides of those defaults for a particular named latent - style. - """ - return LatentStyles(self._element.get_or_add_latentStyles()) - - def _get_by_id(self, style_id, style_type): - """ - Return the style of *style_type* matching *style_id*. Returns the - default for *style_type* if *style_id* is not found or if the style - having *style_id* is not of *style_type*. - """ - style = self._element.get_by_id(style_id) - if style is None or style.type != style_type: - return self.default(style_type) - return StyleFactory(style) - - def _get_style_id_from_name(self, style_name, style_type): - """ - Return the id of the style of *style_type* corresponding to - *style_name*. Returns |None| if that style is the default style for - *style_type*. Raises |ValueError| if the named style is not found in - the document or does not match *style_type*. - """ - return self._get_style_id_from_style(self[style_name], style_type) - - def _get_style_id_from_style(self, style, style_type): - """ - Return the id of *style*, or |None| if it is the default style of - *style_type*. Raises |ValueError| if style is not of *style_type*. - """ - if style.type != style_type: - raise ValueError( - "assigned style is type %s, need type %s" % (style.type, style_type) - ) - if style == self.default(style_type): - return None - return style.style_id diff --git a/docx/table.py b/docx/table.py deleted file mode 100644 index 4afb0ea0..00000000 --- a/docx/table.py +++ /dev/null @@ -1,467 +0,0 @@ -""" -The |Table| object and related proxy classes. -""" -from .blkcntnr import BlockItemContainer -from .enum.style import WD_STYLE_TYPE -from .oxml.simpletypes import ST_Merge -from .shared import Inches, Parented, lazyproperty - - -class Table(Parented): - """ - Proxy class for a WordprocessingML ```` element. - """ - - def __init__(self, tbl, parent): - super(Table, self).__init__(parent) - self._element = self._tbl = tbl - - def add_column(self, width): - """ - Return a |_Column| object of *width*, newly added rightmost to the - table. - """ - tblGrid = self._tbl.tblGrid - gridCol = tblGrid.add_gridCol() - gridCol.w = width - for tr in self._tbl.tr_lst: - tc = tr.add_tc() - tc.width = width - return _Column(gridCol, self) - - def add_row(self): - """ - Return a |_Row| instance, newly added bottom-most to the table. - """ - tbl = self._tbl - tr = tbl.add_tr() - for gridCol in tbl.tblGrid.gridCol_lst: - tc = tr.add_tc() - tc.width = gridCol.w - return _Row(tr, self) - - @property - def alignment(self): - """ - Read/write. A member of :ref:`WdRowAlignment` or None, specifying the - positioning of this table between the page margins. |None| if no - setting is specified, causing the effective value to be inherited - from the style hierarchy. - """ - return self._tblPr.alignment - - @alignment.setter - def alignment(self, value): - self._tblPr.alignment = value - - @property - def autofit(self): - """ - |True| if column widths can be automatically adjusted to improve the - fit of cell contents. |False| if table layout is fixed. Column widths - are adjusted in either case if total column width exceeds page width. - Read/write boolean. - """ - return self._tblPr.autofit - - @autofit.setter - def autofit(self, value): - self._tblPr.autofit = value - - def cell(self, row_idx, col_idx): - """ - Return |_Cell| instance correponding to table cell at *row_idx*, - *col_idx* intersection, where (0, 0) is the top, left-most cell. - """ - cell_idx = col_idx + (row_idx * self._column_count) - return self._cells[cell_idx] - - def column_cells(self, column_idx): - """ - Sequence of cells in the column at *column_idx* in this table. - """ - cells = self._cells - idxs = range(column_idx, len(cells), self._column_count) - return [cells[idx] for idx in idxs] - - @lazyproperty - def columns(self): - """ - |_Columns| instance representing the sequence of columns in this - table. - """ - return _Columns(self._tbl, self) - - def row_cells(self, row_idx): - """ - Sequence of cells in the row at *row_idx* in this table. - """ - column_count = self._column_count - start = row_idx * column_count - end = start + column_count - return self._cells[start:end] - - @lazyproperty - def rows(self): - """ - |_Rows| instance containing the sequence of rows in this table. - """ - return _Rows(self._tbl, self) - - @property - def style(self): - """ - Read/write. A |_TableStyle| object representing the style applied to - this table. The default table style for the document (often `Normal - Table`) is returned if the table has no directly-applied style. - Assigning |None| to this property removes any directly-applied table - style causing it to inherit the default table style of the document. - Note that the style name of a table style differs slightly from that - displayed in the user interface; a hyphen, if it appears, must be - removed. For example, `Light Shading - Accent 1` becomes `Light - Shading Accent 1`. - """ - style_id = self._tbl.tblStyle_val - return self.part.get_style(style_id, WD_STYLE_TYPE.TABLE) - - @style.setter - def style(self, style_or_name): - style_id = self.part.get_style_id(style_or_name, WD_STYLE_TYPE.TABLE) - self._tbl.tblStyle_val = style_id - - @property - def table(self): - """ - Provide child objects with reference to the |Table| object they - belong to, without them having to know their direct parent is - a |Table| object. This is the terminus of a series of `parent._table` - calls from an arbitrary child through its ancestors. - """ - return self - - @property - def table_direction(self): - """ - A member of :ref:`WdTableDirection` indicating the direction in which - the table cells are ordered, e.g. `WD_TABLE_DIRECTION.LTR`. |None| - indicates the value is inherited from the style hierarchy. - """ - return self._element.bidiVisual_val - - @table_direction.setter - def table_direction(self, value): - self._element.bidiVisual_val = value - - @property - def _cells(self): - """ - A sequence of |_Cell| objects, one for each cell of the layout grid. - If the table contains a span, one or more |_Cell| object references - are repeated. - """ - col_count = self._column_count - cells = [] - for tc in self._tbl.iter_tcs(): - for grid_span_idx in range(tc.grid_span): - if tc.vMerge == ST_Merge.CONTINUE: - cells.append(cells[-col_count]) - elif grid_span_idx > 0: - cells.append(cells[-1]) - else: - cells.append(_Cell(tc, self)) - return cells - - @property - def _column_count(self): - """ - The number of grid columns in this table. - """ - return self._tbl.col_count - - @property - def _tblPr(self): - return self._tbl.tblPr - - -class _Cell(BlockItemContainer): - """Table cell""" - - def __init__(self, tc, parent): - super(_Cell, self).__init__(tc, parent) - self._tc = self._element = tc - - def add_paragraph(self, text="", style=None): - """ - Return a paragraph newly added to the end of the content in this - cell. If present, *text* is added to the paragraph in a single run. - If specified, the paragraph style *style* is applied. If *style* is - not specified or is |None|, the result is as though the 'Normal' - style was applied. Note that the formatting of text in a cell can be - influenced by the table style. *text* can contain tab (``\\t``) - characters, which are converted to the appropriate XML form for - a tab. *text* can also include newline (``\\n``) or carriage return - (``\\r``) characters, each of which is converted to a line break. - """ - return super(_Cell, self).add_paragraph(text, style) - - def add_table(self, rows, cols): - """ - Return a table newly added to this cell after any existing cell - content, having *rows* rows and *cols* columns. An empty paragraph is - added after the table because Word requires a paragraph element as - the last element in every cell. - """ - width = self.width if self.width is not None else Inches(1) - table = super(_Cell, self).add_table(rows, cols, width) - self.add_paragraph() - return table - - def merge(self, other_cell): - """ - Return a merged cell created by spanning the rectangular region - having this cell and *other_cell* as diagonal corners. Raises - |InvalidSpanError| if the cells do not define a rectangular region. - """ - tc, tc_2 = self._tc, other_cell._tc - merged_tc = tc.merge(tc_2) - return _Cell(merged_tc, self._parent) - - @property - def paragraphs(self): - """ - List of paragraphs in the cell. A table cell is required to contain - at least one block-level element and end with a paragraph. By - default, a new cell contains a single paragraph. Read-only - """ - return super(_Cell, self).paragraphs - - @property - def tables(self): - """ - List of tables in the cell, in the order they appear. Read-only. - """ - return super(_Cell, self).tables - - @property - def text(self): - """ - The entire contents of this cell as a string of text. Assigning - a string to this property replaces all existing content with a single - paragraph containing the assigned text in a single run. - """ - return "\n".join(p.text for p in self.paragraphs) - - @text.setter - def text(self, text): - """ - Write-only. Set entire contents of cell to the string *text*. Any - existing content or revisions are replaced. - """ - tc = self._tc - tc.clear_content() - p = tc.add_p() - r = p.add_r() - r.texts = text - - @property - def vertical_alignment(self): - """Member of :ref:`WdCellVerticalAlignment` or None. - - A value of |None| indicates vertical alignment for this cell is - inherited. Assigning |None| causes any explicitly defined vertical - alignment to be removed, restoring inheritance. - """ - tcPr = self._element.tcPr - if tcPr is None: - return None - return tcPr.vAlign_val - - @vertical_alignment.setter - def vertical_alignment(self, value): - tcPr = self._element.get_or_add_tcPr() - tcPr.vAlign_val = value - - @property - def width(self): - """ - The width of this cell in EMU, or |None| if no explicit width is set. - """ - return self._tc.width - - @width.setter - def width(self, value): - self._tc.width = value - - -class _Column(Parented): - """ - Table column - """ - - def __init__(self, gridCol, parent): - super(_Column, self).__init__(parent) - self._gridCol = gridCol - - @property - def cells(self): - """ - Sequence of |_Cell| instances corresponding to cells in this column. - """ - return tuple(self.table.column_cells(self._index)) - - @property - def table(self): - """ - Reference to the |Table| object this column belongs to. - """ - return self._parent.table - - @property - def width(self): - """ - The width of this column in EMU, or |None| if no explicit width is - set. - """ - return self._gridCol.w - - @width.setter - def width(self, value): - self._gridCol.w = value - - @property - def _index(self): - """ - Index of this column in its table, starting from zero. - """ - return self._gridCol.gridCol_idx - - -class _Columns(Parented): - """ - Sequence of |_Column| instances corresponding to the columns in a table. - Supports ``len()``, iteration and indexed access. - """ - - def __init__(self, tbl, parent): - super(_Columns, self).__init__(parent) - self._tbl = tbl - - def __getitem__(self, idx): - """ - Provide indexed access, e.g. 'columns[0]' - """ - try: - gridCol = self._gridCol_lst[idx] - except IndexError: - msg = "column index [%d] is out of range" % idx - raise IndexError(msg) - return _Column(gridCol, self) - - def __iter__(self): - for gridCol in self._gridCol_lst: - yield _Column(gridCol, self) - - def __len__(self): - return len(self._gridCol_lst) - - @property - def table(self): - """ - Reference to the |Table| object this column collection belongs to. - """ - return self._parent.table - - @property - def _gridCol_lst(self): - """ - Sequence containing ```` elements for this table, each - representing a table column. - """ - tblGrid = self._tbl.tblGrid - return tblGrid.gridCol_lst - - -class _Row(Parented): - """ - Table row - """ - - def __init__(self, tr, parent): - super(_Row, self).__init__(parent) - self._tr = self._element = tr - - @property - def cells(self): - """ - Sequence of |_Cell| instances corresponding to cells in this row. - """ - return tuple(self.table.row_cells(self._index)) - - @property - def height(self): - """ - Return a |Length| object representing the height of this cell, or - |None| if no explicit height is set. - """ - return self._tr.trHeight_val - - @height.setter - def height(self, value): - self._tr.trHeight_val = value - - @property - def height_rule(self): - """ - Return the height rule of this cell as a member of the - :ref:`WdRowHeightRule` enumeration, or |None| if no explicit - height_rule is set. - """ - return self._tr.trHeight_hRule - - @height_rule.setter - def height_rule(self, value): - self._tr.trHeight_hRule = value - - @property - def table(self): - """ - Reference to the |Table| object this row belongs to. - """ - return self._parent.table - - @property - def _index(self): - """ - Index of this row in its table, starting from zero. - """ - return self._tr.tr_idx - - -class _Rows(Parented): - """ - Sequence of |_Row| objects corresponding to the rows in a table. - Supports ``len()``, iteration, indexed access, and slicing. - """ - - def __init__(self, tbl, parent): - super(_Rows, self).__init__(parent) - self._tbl = tbl - - def __getitem__(self, idx): - """ - Provide indexed access, (e.g. 'rows[0]') - """ - return list(self)[idx] - - def __iter__(self): - return (_Row(tr, self) for tr in self._tbl.tr_lst) - - def __len__(self): - return len(self._tbl.tr_lst) - - @property - def table(self): - """ - Reference to the |Table| object this row collection belongs to. - """ - return self._parent.table diff --git a/docx/text/font.py b/docx/text/font.py deleted file mode 100644 index f9ccbaf2..00000000 --- a/docx/text/font.py +++ /dev/null @@ -1,424 +0,0 @@ -# encoding: utf-8 - -""" -Font-related proxy objects. -""" - -from __future__ import absolute_import, division, print_function, unicode_literals - -from ..dml.color import ColorFormat -from ..shared import ElementProxy - - -class Font(ElementProxy): - """ - Proxy object wrapping the parent of a ```` element and providing - access to character properties such as font name, font size, bold, and - subscript. - """ - - __slots__ = () - - @property - def all_caps(self): - """ - Read/write. Causes text in this font to appear in capital letters. - """ - return self._get_bool_prop("caps") - - @all_caps.setter - def all_caps(self, value): - self._set_bool_prop("caps", value) - - @property - def bold(self): - """ - Read/write. Causes text in this font to appear in bold. - """ - return self._get_bool_prop("b") - - @bold.setter - def bold(self, value): - self._set_bool_prop("b", value) - - @property - def color(self): - """ - A |ColorFormat| object providing a way to get and set the text color - for this font. - """ - return ColorFormat(self._element) - - @property - def complex_script(self): - """ - Read/write tri-state value. When |True|, causes the characters in the - run to be treated as complex script regardless of their Unicode - values. - """ - return self._get_bool_prop("cs") - - @complex_script.setter - def complex_script(self, value): - self._set_bool_prop("cs", value) - - @property - def cs_bold(self): - """ - Read/write tri-state value. When |True|, causes the complex script - characters in the run to be displayed in bold typeface. - """ - return self._get_bool_prop("bCs") - - @cs_bold.setter - def cs_bold(self, value): - self._set_bool_prop("bCs", value) - - @property - def cs_italic(self): - """ - Read/write tri-state value. When |True|, causes the complex script - characters in the run to be displayed in italic typeface. - """ - return self._get_bool_prop("iCs") - - @cs_italic.setter - def cs_italic(self, value): - self._set_bool_prop("iCs", value) - - @property - def double_strike(self): - """ - Read/write tri-state value. When |True|, causes the text in the run - to appear with double strikethrough. - """ - return self._get_bool_prop("dstrike") - - @double_strike.setter - def double_strike(self, value): - self._set_bool_prop("dstrike", value) - - @property - def emboss(self): - """ - Read/write tri-state value. When |True|, causes the text in the run - to appear as if raised off the page in relief. - """ - return self._get_bool_prop("emboss") - - @emboss.setter - def emboss(self, value): - self._set_bool_prop("emboss", value) - - @property - def hidden(self): - """ - Read/write tri-state value. When |True|, causes the text in the run - to be hidden from display, unless applications settings force hidden - text to be shown. - """ - return self._get_bool_prop("vanish") - - @hidden.setter - def hidden(self, value): - self._set_bool_prop("vanish", value) - - @property - def highlight_color(self): - """ - A member of :ref:`WdColorIndex` indicating the color of highlighting - applied, or `None` if no highlighting is applied. - """ - rPr = self._element.rPr - if rPr is None: - return None - return rPr.highlight_val - - @highlight_color.setter - def highlight_color(self, value): - rPr = self._element.get_or_add_rPr() - rPr.highlight_val = value - - @property - def italic(self): - """ - Read/write tri-state value. When |True|, causes the text of the run - to appear in italics. |None| indicates the effective value is - inherited from the style hierarchy. - """ - return self._get_bool_prop("i") - - @italic.setter - def italic(self, value): - self._set_bool_prop("i", value) - - @property - def imprint(self): - """ - Read/write tri-state value. When |True|, causes the text in the run - to appear as if pressed into the page. - """ - return self._get_bool_prop("imprint") - - @imprint.setter - def imprint(self, value): - self._set_bool_prop("imprint", value) - - @property - def math(self): - """ - Read/write tri-state value. When |True|, specifies this run contains - WML that should be handled as though it was Office Open XML Math. - """ - return self._get_bool_prop("oMath") - - @math.setter - def math(self, value): - self._set_bool_prop("oMath", value) - - @property - def name(self): - """ - Get or set the typeface names for this |Font| instance, causing the - text it controls to appear in the named font, if a matching font is - found. |None| indicates the typeface is inherited from the style - hierarchy. `ascii`, `hAnsi`, and `eastAsia` can be set respectively - by specifying them in dictionary format - """ - rPr = self._element.rPr - if rPr is None: - return { - "ascii": None, - "hAnsi": None, - "eastAsia": None, - } - return { - "ascii": rPr.rFonts_ascii, - "hAnsi": rPr.rFonts_hAnsi, - "eastAsia": rPr.rFonts_eastAsia, - } - - @name.setter - def name(self, value): - rPr = self._element.get_or_add_rPr() - if isinstance(value, dict): - rPr.rFonts_ascii = value.get('ascii') - rPr.rFonts_hAnsi = value.get('hAnsi') - rPr.rFonts_eastAsia = value.get('eastAsia') - else: - rPr.rFonts_ascii = value - rPr.rFonts_hAnsi = value - rPr.rFonts_eastAsia = value - - @property - def no_proof(self): - """ - Read/write tri-state value. When |True|, specifies that the contents - of this run should not report any errors when the document is scanned - for spelling and grammar. - """ - return self._get_bool_prop("noProof") - - @no_proof.setter - def no_proof(self, value): - self._set_bool_prop("noProof", value) - - @property - def outline(self): - """ - Read/write tri-state value. When |True| causes the characters in the - run to appear as if they have an outline, by drawing a one pixel wide - border around the inside and outside borders of each character glyph. - """ - return self._get_bool_prop("outline") - - @outline.setter - def outline(self, value): - self._set_bool_prop("outline", value) - - @property - def rtl(self): - """ - Read/write tri-state value. When |True| causes the text in the run - to have right-to-left characteristics. - """ - return self._get_bool_prop("rtl") - - @rtl.setter - def rtl(self, value): - self._set_bool_prop("rtl", value) - - @property - def shadow(self): - """ - Read/write tri-state value. When |True| causes the text in the run - to appear as if each character has a shadow. - """ - return self._get_bool_prop("shadow") - - @shadow.setter - def shadow(self, value): - self._set_bool_prop("shadow", value) - - @property - def size(self): - """ - Read/write |Length| value or |None|, indicating the font height in - English Metric Units (EMU). |None| indicates the font size should be - inherited from the style hierarchy. |Length| is a subclass of |int| - having properties for convenient conversion into points or other - length units. The :class:`docx.shared.Pt` class allows convenient - specification of point values:: - - >> font.size = Pt(24) - >> font.size - 304800 - >> font.size.pt - 24.0 - """ - rPr = self._element.rPr - if rPr is None: - return None - return rPr.sz_val - - @size.setter - def size(self, emu): - rPr = self._element.get_or_add_rPr() - rPr.sz_val = emu - - @property - def small_caps(self): - """ - Read/write tri-state value. When |True| causes the lowercase - characters in the run to appear as capital letters two points smaller - than the font size specified for the run. - """ - return self._get_bool_prop("smallCaps") - - @small_caps.setter - def small_caps(self, value): - self._set_bool_prop("smallCaps", value) - - @property - def snap_to_grid(self): - """ - Read/write tri-state value. When |True| causes the run to use the - document grid characters per line settings defined in the docGrid - element when laying out the characters in this run. - """ - return self._get_bool_prop("snapToGrid") - - @snap_to_grid.setter - def snap_to_grid(self, value): - self._set_bool_prop("snapToGrid", value) - - @property - def spec_vanish(self): - """ - Read/write tri-state value. When |True|, specifies that the given run - shall always behave as if it is hidden, even when hidden text is - being displayed in the current document. The property has a very - narrow, specialized use related to the table of contents. Consult the - spec (§17.3.2.36) for more details. - """ - return self._get_bool_prop("specVanish") - - @spec_vanish.setter - def spec_vanish(self, value): - self._set_bool_prop("specVanish", value) - - @property - def strike(self): - """ - Read/write tri-state value. When |True| causes the text in the run - to appear with a single horizontal line through the center of the - line. - """ - return self._get_bool_prop("strike") - - @strike.setter - def strike(self, value): - self._set_bool_prop("strike", value) - - @property - def subscript(self): - """ - Boolean indicating whether the characters in this |Font| appear as - subscript. |None| indicates the subscript/subscript value is - inherited from the style hierarchy. - """ - rPr = self._element.rPr - if rPr is None: - return None - return rPr.subscript - - @subscript.setter - def subscript(self, value): - rPr = self._element.get_or_add_rPr() - rPr.subscript = value - - @property - def superscript(self): - """ - Boolean indicating whether the characters in this |Font| appear as - superscript. |None| indicates the subscript/superscript value is - inherited from the style hierarchy. - """ - rPr = self._element.rPr - if rPr is None: - return None - return rPr.superscript - - @superscript.setter - def superscript(self, value): - rPr = self._element.get_or_add_rPr() - rPr.superscript = value - - @property - def underline(self): - """ - The underline style for this |Font|, one of |None|, |True|, |False|, - or a value from :ref:`WdUnderline`. |None| indicates the font - inherits its underline value from the style hierarchy. |False| - indicates no underline. |True| indicates single underline. The values - from :ref:`WdUnderline` are used to specify other outline styles such - as double, wavy, and dotted. - """ - rPr = self._element.rPr - if rPr is None: - return None - return rPr.u_val - - @underline.setter - def underline(self, value): - rPr = self._element.get_or_add_rPr() - rPr.u_val = value - - @property - def web_hidden(self): - """ - Read/write tri-state value. When |True|, specifies that the contents - of this run shall be hidden when the document is displayed in web - page view. - """ - return self._get_bool_prop("webHidden") - - @web_hidden.setter - def web_hidden(self, value): - self._set_bool_prop("webHidden", value) - - def _get_bool_prop(self, name): - """ - Return the value of boolean child of `w:rPr` having *name*. - """ - rPr = self._element.rPr - if rPr is None: - return None - return rPr._get_bool_val(name) - - def _set_bool_prop(self, name, value): - """ - Assign *value* to the boolean child *name* of `w:rPr`. - """ - rPr = self._element.get_or_add_rPr() - rPr._set_bool_val(name, value) diff --git a/docx/text/paragraph.py b/docx/text/paragraph.py deleted file mode 100644 index d349e537..00000000 --- a/docx/text/paragraph.py +++ /dev/null @@ -1,142 +0,0 @@ -# encoding: utf-8 - -""" -Paragraph-related proxy types. -""" - -from __future__ import absolute_import, division, print_function, unicode_literals - -from ..enum.style import WD_STYLE_TYPE -from .parfmt import ParagraphFormat -from .run import Run -from ..shared import Parented - - -class Paragraph(Parented): - """ - Proxy object wrapping ```` element. - """ - - def __init__(self, p, parent): - super(Paragraph, self).__init__(parent) - self._p = self._element = p - - def add_run(self, text=None, style=None): - """ - Append a run to this paragraph containing *text* and having character - style identified by style ID *style*. *text* can contain tab - (``\\t``) characters, which are converted to the appropriate XML form - for a tab. *text* can also include newline (``\\n``) or carriage - return (``\\r``) characters, each of which is converted to a line - break. - """ - r = self._p.add_r() - run = Run(r, self) - if text: - run.text = text - if style: - run.style = style - return run - - @property - def alignment(self): - """ - A member of the :ref:`WdParagraphAlignment` enumeration specifying - the justification setting for this paragraph. A value of |None| - indicates the paragraph has no directly-applied alignment value and - will inherit its alignment value from its style hierarchy. Assigning - |None| to this property removes any directly-applied alignment value. - """ - return self._p.alignment - - @alignment.setter - def alignment(self, value): - self._p.alignment = value - - def clear(self): - """ - Return this same paragraph after removing all its content. - Paragraph-level formatting, such as style, is preserved. - """ - self._p.clear_content() - return self - - def insert_paragraph_before(self, text=None, style=None): - """ - Return a newly created paragraph, inserted directly before this - paragraph. If *text* is supplied, the new paragraph contains that - text in a single run. If *style* is provided, that style is assigned - to the new paragraph. - """ - paragraph = self._insert_paragraph_before() - if text: - paragraph.add_run(text) - if style is not None: - paragraph.style = style - return paragraph - - @property - def paragraph_format(self): - """ - The |ParagraphFormat| object providing access to the formatting - properties for this paragraph, such as line spacing and indentation. - """ - return ParagraphFormat(self._element) - - @property - def runs(self): - """ - Sequence of |Run| instances corresponding to the elements in - this paragraph. - """ - return [Run(r, self) for r in self._p.r_lst] - - @property - def style(self): - """ - Read/Write. |_ParagraphStyle| object representing the style assigned - to this paragraph. If no explicit style is assigned to this - paragraph, its value is the default paragraph style for the document. - A paragraph style name can be assigned in lieu of a paragraph style - object. Assigning |None| removes any applied style, making its - effective value the default paragraph style for the document. - """ - style_id = self._p.style - return self.part.get_style(style_id, WD_STYLE_TYPE.PARAGRAPH) - - @style.setter - def style(self, style_or_name): - style_id = self.part.get_style_id(style_or_name, WD_STYLE_TYPE.PARAGRAPH) - self._p.style = style_id - - @property - def text(self): - """ - String formed by concatenating the text of each run in the paragraph. - Tabs and line breaks in the XML are mapped to ``\\t`` and ``\\n`` - characters respectively. - - Assigning text to this property causes all existing paragraph content - to be replaced with a single run containing the assigned text. - A ``\\t`` character in the text is mapped to a ```` element - and each ``\\n`` or ``\\r`` character is mapped to a line break. - Paragraph-level formatting, such as style, is preserved. All - run-level formatting, such as bold or italic, is removed. - """ - text = "" - for run in self.runs: - text += run.text - return text - - @text.setter - def text(self, text): - self.clear() - self.add_run(text) - - def _insert_paragraph_before(self): - """ - Return a newly created paragraph, inserted directly before this - paragraph. - """ - p = self._p.add_p_before() - return Paragraph(p, self._parent) diff --git a/docx/text/run.py b/docx/text/run.py deleted file mode 100644 index 10b58bd9..00000000 --- a/docx/text/run.py +++ /dev/null @@ -1,192 +0,0 @@ -""" -Run-related proxy objects for python-docx, Run in particular. -""" -from ..enum.style import WD_STYLE_TYPE -from ..enum.text import WD_BREAK -from ..shape import InlineShape -from ..shared import Parented -from .font import Font - - -class Run(Parented): - """ - Proxy object wrapping ```` element. Several of the properties on Run - take a tri-state value, |True|, |False|, or |None|. |True| and |False| - correspond to on and off respectively. |None| indicates the property is - not specified directly on the run and its effective value is taken from - the style hierarchy. - """ - - def __init__(self, r, parent): - super(Run, self).__init__(parent) - self._r = self._element = self.element = r - - def add_break(self, break_type=WD_BREAK.LINE): - """ - Add a break element of *break_type* to this run. *break_type* can - take the values `WD_BREAK.LINE`, `WD_BREAK.PAGE`, and - `WD_BREAK.COLUMN` where `WD_BREAK` is imported from `docx.enum.text`. - *break_type* defaults to `WD_BREAK.LINE`. - """ - type_, clear = { - WD_BREAK.LINE: (None, None), - WD_BREAK.PAGE: ("page", None), - WD_BREAK.COLUMN: ("column", None), - WD_BREAK.LINE_CLEAR_LEFT: ("textWrapping", "left"), - WD_BREAK.LINE_CLEAR_RIGHT: ("textWrapping", "right"), - WD_BREAK.LINE_CLEAR_ALL: ("textWrapping", "all"), - }[break_type] - br = self._r.add_br() - if type_ is not None: - br.type = type_ - if clear is not None: - br.clear = clear - - def add_picture(self, image_path_or_stream, width=None, height=None): - """ - Return an |InlineShape| instance containing the image identified by - *image_path_or_stream*, added to the end of this run. - *image_path_or_stream* can be a path (a string) or a file-like object - containing a binary image. If neither width nor height is specified, - the picture appears at its native size. If only one is specified, it - is used to compute a scaling factor that is then applied to the - unspecified dimension, preserving the aspect ratio of the image. The - native size of the picture is calculated using the dots-per-inch - (dpi) value specified in the image file, defaulting to 72 dpi if no - value is specified, as is often the case. - """ - inline = self.part.new_pic_inline(image_path_or_stream, width, height) - self._r.add_drawing(inline) - return InlineShape(inline) - - def add_float_picture(self, image_path_or_stream, width=None, height=None, pos_x=0, pos_y=0): - """Add float picture at fixed position `pos_x` and `pos_y` to the top-left point of page.""" - anchor = self.part.new_pic_anchor(image_path_or_stream, width, height, pos_x, pos_y) - self._r.add_drawing(anchor) - return anchor - - def add_tab(self): - """ - Add a ```` element at the end of the run, which Word - interprets as a tab character. - """ - self._r._add_tab() - - def add_text(self, text): - """ - Returns a newly appended |_Text| object (corresponding to a new - ```` child element) to the run, containing *text*. Compare with - the possibly more friendly approach of assigning text to the - :attr:`Run.text` property. - """ - t = self._r.add_t(text) - return _Text(t) - - @property - def bold(self): - """ - Read/write. Causes the text of the run to appear in bold. - """ - return self.font.bold - - @bold.setter - def bold(self, value): - self.font.bold = value - - def clear(self): - """ - Return reference to this run after removing all its content. All run - formatting is preserved. - """ - self._r.clear_content() - return self - - @property - def font(self): - """ - The |Font| object providing access to the character formatting - properties for this run, such as font name and size. - """ - return Font(self._element) - - @property - def italic(self): - """ - Read/write tri-state value. When |True|, causes the text of the run - to appear in italics. - """ - return self.font.italic - - @italic.setter - def italic(self, value): - self.font.italic = value - - @property - def style(self): - """ - Read/write. A |_CharacterStyle| object representing the character - style applied to this run. The default character style for the - document (often `Default Character Font`) is returned if the run has - no directly-applied character style. Setting this property to |None| - removes any directly-applied character style. - """ - style_id = self._r.style - return self.part.get_style(style_id, WD_STYLE_TYPE.CHARACTER) - - @style.setter - def style(self, style_or_name): - style_id = self.part.get_style_id(style_or_name, WD_STYLE_TYPE.CHARACTER) - self._r.style = style_id - - @property - def text(self): - """ - String formed by concatenating the text equivalent of each run - content child element into a Python string. Each ```` element - adds the text characters it contains. A ```` element adds - a ``\\t`` character. A ```` or ```` element each add - a ``\\n`` character. Note that a ```` element can indicate - a page break or column break as well as a line break. All ```` - elements translate to a single ``\\n`` character regardless of their - type. All other content child elements, such as ````, are - ignored. - - Assigning text to this property has the reverse effect, translating - each ``\\t`` character to a ```` element and each ``\\n`` or - ``\\r`` character to a ```` element. Any existing run content - is replaced. Run formatting is preserved. - """ - return self._r.texts - - @text.setter - def text(self, text): - self._r.texts = text - - @property - def underline(self): - """ - The underline style for this |Run|, one of |None|, |True|, |False|, - or a value from :ref:`WdUnderline`. A value of |None| indicates the - run has no directly-applied underline value and so will inherit the - underline value of its containing paragraph. Assigning |None| to this - property removes any directly-applied underline value. A value of - |False| indicates a directly-applied setting of no underline, - overriding any inherited value. A value of |True| indicates single - underline. The values from :ref:`WdUnderline` are used to specify - other outline styles such as double, wavy, and dotted. - """ - return self.font.underline - - @underline.setter - def underline(self, value): - self.font.underline = value - - -class _Text(object): - """ - Proxy object wrapping ```` element. - """ - - def __init__(self, t_elm): - super(_Text, self).__init__() - self._t = t_elm diff --git a/docx/text/tabstops.py b/docx/text/tabstops.py deleted file mode 100644 index 6915285c..00000000 --- a/docx/text/tabstops.py +++ /dev/null @@ -1,142 +0,0 @@ -# encoding: utf-8 - -""" -Tabstop-related proxy types. -""" - -from __future__ import absolute_import, division, print_function, unicode_literals - -from ..shared import ElementProxy -from docx.enum.text import WD_TAB_ALIGNMENT, WD_TAB_LEADER - - -class TabStops(ElementProxy): - """ - A sequence of |TabStop| objects providing access to the tab stops of - a paragraph or paragraph style. Supports iteration, indexed access, del, - and len(). It is accesed using the :attr:`~.ParagraphFormat.tab_stops` - property of ParagraphFormat; it is not intended to be constructed - directly. - """ - - __slots__ = "_pPr" - - def __init__(self, element): - super(TabStops, self).__init__(element, None) - self._pPr = element - - def __delitem__(self, idx): - """ - Remove the tab at offset *idx* in this sequence. - """ - tabs = self._pPr.tabs - try: - tabs.remove(tabs[idx]) - except (AttributeError, IndexError): - raise IndexError("tab index out of range") - - if len(tabs) == 0: - self._pPr.remove(tabs) - - def __getitem__(self, idx): - """ - Enables list-style access by index. - """ - tabs = self._pPr.tabs - if tabs is None: - raise IndexError("TabStops object is empty") - tab = tabs.tab_lst[idx] - return TabStop(tab) - - def __iter__(self): - """ - Generate a TabStop object for each of the w:tab elements, in XML - document order. - """ - tabs = self._pPr.tabs - if tabs is not None: - for tab in tabs.tab_lst: - yield TabStop(tab) - - def __len__(self): - tabs = self._pPr.tabs - if tabs is None: - return 0 - return len(tabs.tab_lst) - - def add_tab_stop( - self, position, alignment=WD_TAB_ALIGNMENT.LEFT, leader=WD_TAB_LEADER.SPACES - ): - """ - Add a new tab stop at *position*, a |Length| object specifying the - location of the tab stop relative to the paragraph edge. A negative - *position* value is valid and appears in hanging indentation. Tab - alignment defaults to left, but may be specified by passing a member - of the :ref:`WdTabAlignment` enumeration as *alignment*. An optional - leader character can be specified by passing a member of the - :ref:`WdTabLeader` enumeration as *leader*. - """ - tabs = self._pPr.get_or_add_tabs() - tab = tabs.insert_tab_in_order(position, alignment, leader) - return TabStop(tab) - - def clear_all(self): - """ - Remove all custom tab stops. - """ - self._pPr._remove_tabs() - - -class TabStop(ElementProxy): - """ - An individual tab stop applying to a paragraph or style. Accessed using - list semantics on its containing |TabStops| object. - """ - - __slots__ = "_tab" - - def __init__(self, element): - super(TabStop, self).__init__(element, None) - self._tab = element - - @property - def alignment(self): - """ - A member of :ref:`WdTabAlignment` specifying the alignment setting - for this tab stop. Read/write. - """ - return self._tab.val - - @alignment.setter - def alignment(self, value): - self._tab.val = value - - @property - def leader(self): - """ - A member of :ref:`WdTabLeader` specifying a repeating character used - as a "leader", filling in the space spanned by this tab. Assigning - |None| produces the same result as assigning `WD_TAB_LEADER.SPACES`. - Read/write. - """ - return self._tab.leader - - @leader.setter - def leader(self, value): - self._tab.leader = value - - @property - def position(self): - """ - A |Length| object representing the distance of this tab stop from the - inside edge of the paragraph. May be positive or negative. - Read/write. - """ - return self._tab.pos - - @position.setter - def position(self, value): - tab = self._tab - tabs = tab.getparent() - self._tab = tabs.insert_tab_in_order(value, tab.val, tab.leader) - tabs.remove(tab) diff --git a/features/blk-iter-inner-content.feature b/features/blk-iter-inner-content.feature new file mode 100644 index 00000000..047efb9e --- /dev/null +++ b/features/blk-iter-inner-content.feature @@ -0,0 +1,24 @@ +Feature: Iterate paragraphs and tables in document-order + In order to access paragraphs and tables in the same order they appear in the document + As a developer using python-docx + I need the ability to iterate the inner-content of a block-item-container + + + Scenario: Document.iter_inner_content() + Given a Document object with paragraphs and tables + Then document.iter_inner_content() produces the block-items in document order + + + Scenario: Header.iter_inner_content() + Given a Header object with paragraphs and tables + Then header.iter_inner_content() produces the block-items in document order + + + Scenario: Footer.iter_inner_content() + Given a Footer object with paragraphs and tables + Then footer.iter_inner_content() produces the block-items in document order + + + Scenario: _Cell.iter_inner_content() + Given a _Cell object with paragraphs and tables + Then cell.iter_inner_content() produces the block-items in document order diff --git a/features/cmt-mutations.feature b/features/cmt-mutations.feature new file mode 100644 index 00000000..1ef9ad2d --- /dev/null +++ b/features/cmt-mutations.feature @@ -0,0 +1,59 @@ +Feature: Comment mutations + In order to add and modify the content of a comment + As a developer using python-docx + I need mutation methods on Comment objects + + + Scenario: Comments.add_comment() + Given a Comments object with 0 comments + When I assign comment = comments.add_comment() + Then comment.comment_id == 0 + And len(comment.paragraphs) == 1 + And comment.paragraphs[0].style.name == "CommentText" + And len(comments) == 1 + And comments.get(0) == comment + + + Scenario: Comments.add_comment() specifying author and initials + Given a Comments object with 0 comments + When I assign comment = comments.add_comment(author="John Doe", initials="JD") + Then comment.author == "John Doe" + And comment.initials == "JD" + + + Scenario: Comment.add_paragraph() specifying text and style + Given a default Comment object + When I assign paragraph = comment.add_paragraph(text, style) + Then len(comment.paragraphs) == 2 + And paragraph.text == text + And paragraph.style == style + And comment.paragraphs[-1] == paragraph + + + Scenario: Comment.add_paragraph() not specifying text or style + Given a default Comment object + When I assign paragraph = comment.add_paragraph() + Then len(comment.paragraphs) == 2 + And paragraph.text == "" + And paragraph.style == "CommentText" + And comment.paragraphs[-1] == paragraph + + + Scenario: Add image to comment + Given a default Comment object + When I assign paragraph = comment.add_paragraph() + And I assign run = paragraph.add_run() + And I call run.add_picture() + Then run.iter_inner_content() yields a single Picture drawing + + + Scenario: update Comment.author + Given a Comment object + When I assign "Jane Smith" to comment.author + Then comment.author == "Jane Smith" + + + Scenario: update Comment.initials + Given a Comment object + When I assign "JS" to comment.initials + Then comment.initials == "JS" diff --git a/features/cmt-props.feature b/features/cmt-props.feature new file mode 100644 index 00000000..e4e62082 --- /dev/null +++ b/features/cmt-props.feature @@ -0,0 +1,35 @@ +Feature: Get comment properties + In order to characterize comments by their metadata + As a developer using python-docx + I need methods to access comment metadata properties + + + Scenario: Comment.id + Given a Comment object + Then comment.comment_id is the comment identifier + + + Scenario: Comment.author + Given a Comment object + Then comment.author is the author of the comment + + + Scenario: Comment.initials + Given a Comment object + Then comment.initials is the initials of the comment author + + + Scenario: Comment.timestamp + Given a Comment object + Then comment.timestamp is the date and time the comment was authored + + + Scenario: Comment.paragraphs[0].text + Given a Comment object + When I assign para_text = comment.paragraphs[0].text + Then para_text is the text of the first paragraph in the comment + + + Scenario: Retrieve embedded image from a comment + Given a Comment object containing an embedded image + Then I can extract the image from the comment diff --git a/features/doc-add-comment.feature b/features/doc-add-comment.feature new file mode 100644 index 00000000..36f46244 --- /dev/null +++ b/features/doc-add-comment.feature @@ -0,0 +1,13 @@ +Feature: Add a comment to a document + In order add a comment to a document + As a developer using python-docx + I need a way to add a comment specifying both its content and its reference + + + Scenario: Document.add_comment(runs, text, author, initials) + Given a document having a comments part + When I assign comment = document.add_comment(runs, "A comment", "John Doe", "JD") + Then comment is a Comment object + And comment.text == "A comment" + And comment.author == "John Doe" + And comment.initials == "JD" diff --git a/features/doc-comments.feature b/features/doc-comments.feature new file mode 100644 index 00000000..944146e5 --- /dev/null +++ b/features/doc-comments.feature @@ -0,0 +1,36 @@ +Feature: Document.comments + In order to operate on comments added to a document + As a developer using python-docx + I need access to the comments collection for the document + And I need methods allowing access to the comments in the collection + + + Scenario Outline: Access document comments + Given a document having comments part + Then document.comments is a Comments object + + Examples: having a comments part or not + | a-or-no | + | a | + | no | + + + Scenario Outline: Comments.__len__() + Given a Comments object with comments + Then len(comments) == + + Examples: len(comments) values + | count | + | 0 | + | 4 | + + + Scenario: Comments.__iter__() + Given a Comments object with 4 comments + Then iterating comments yields 4 Comment objects + + + Scenario: Comments.get() + Given a Comments object with 4 comments + When I call comments.get(2) + Then the result is a Comment object with id 2 diff --git a/features/environment.py b/features/environment.py index f180da73..dfd2028a 100644 --- a/features/environment.py +++ b/features/environment.py @@ -1,9 +1,4 @@ -# encoding: utf-8 - -""" -Used by behave to set testing environment before and after running acceptance -tests. -""" +"""Set testing environment before and after behave acceptance test runs.""" import os diff --git a/features/hlk-props.feature b/features/hlk-props.feature new file mode 100644 index 00000000..a315318e --- /dev/null +++ b/features/hlk-props.feature @@ -0,0 +1,54 @@ +Feature: Access hyperlink properties + In order to access the URL and other details for a hyperlink + As a developer using python-docx + I need properties on Hyperlink + + + Scenario: Hyperlink.address has the URL of the hyperlink + Given a hyperlink + Then hyperlink.address is the URL of the hyperlink + + + Scenario Outline: Hyperlink.contains_page_break reports presence of page-break + Given a hyperlink having rendered page breaks + Then hyperlink.contains_page_break is + + Examples: Hyperlink.contains_page_break cases + | zero-or-more | value | + | no | False | + | one | True | + + + Scenario: Hyperlink.fragment has the URI fragment of the hyperlink + Given a hyperlink having a URI fragment + Then hyperlink.fragment is the URI fragment of the hyperlink + + + Scenario Outline: Hyperlink.runs contains Run for each run in hyperlink + Given a hyperlink having runs + Then hyperlink.runs has length + And hyperlink.runs contains only Run instances + + Examples: Hyperlink.runs cases + | zero-or-more | value | + | one | 1 | + | two | 2 | + + + Scenario: Hyperlink.text has the visible text of the hyperlink + Given a hyperlink + Then hyperlink.text is the visible text of the hyperlink + + + Scenario Outline: Hyperlink.url is the full URL of an internet hyperlink + Given a hyperlink having address
    and fragment + Then hyperlink.url is + + Examples: Hyperlink.url cases + | address | fragment | url | + | '' | linkedBookmark | '' | + | https://foo.com | '' | https://foo.com | + | https://foo.com?q=bar | '' | https://foo.com?q=bar | + | http://foo.com/ | intro | http://foo.com/#intro | + | https://foo.com?q=bar#baz | '' | https://foo.com?q=bar#baz | + | court-exif.jpg | '' | court-exif.jpg | diff --git a/features/par-access-inner-content.feature b/features/par-access-inner-content.feature new file mode 100644 index 00000000..047168fc --- /dev/null +++ b/features/par-access-inner-content.feature @@ -0,0 +1,49 @@ +Feature: Access paragraph inner-content including hyperlinks + In order to extract paragraph content with high-fidelity + As a developer using python-docx + I need to access differentiated paragraph content in document order + + + Scenario Outline: Paragraph.contains_page_break reports presence of page-break + Given a paragraph having rendered page breaks + Then paragraph.contains_page_break is + + Examples: Paragraph.contains_page_break cases + | zero-or-more | value | + | no | False | + | one | True | + | two | True | + + + Scenario Outline: Paragraph.hyperlinks contains Hyperlink for each link in paragraph + Given a paragraph having hyperlinks + Then paragraph.hyperlinks has length + And paragraph.hyperlinks contains only Hyperlink instances + + Examples: Paragraph.hyperlinks cases + | zero-or-more | value | + | no | 0 | + | one | 1 | + | three | 3 | + + + Scenario: Paragraph.iter_inner_content() generates the paragraph's runs and hyperlinks + Given a paragraph having three hyperlinks + Then paragraph.iter_inner_content() generates the paragraph runs and hyperlinks + + + Scenario Outline: Paragraph.rendered_page_breaks contains paragraph RenderedPageBreaks + Given a paragraph having rendered page breaks + Then paragraph.rendered_page_breaks has length + And paragraph.rendered_page_breaks contains only RenderedPageBreak instances + + Examples: Paragraph.rendered_page_breaks cases + | zero-or-more | value | + | no | 0 | + | one | 1 | + | two | 2 | + + + Scenario: Paragraph.text contains both run-text and hyperlink-text + Given a paragraph having three hyperlinks + Then paragraph.text contains the text of both the runs and the hyperlinks diff --git a/features/pbk-split-para.feature b/features/pbk-split-para.feature new file mode 100644 index 00000000..8ce048a4 --- /dev/null +++ b/features/pbk-split-para.feature @@ -0,0 +1,24 @@ +Feature: Split paragraph on rendered page-breaks + In order to extract document content with high page-attribution fidelity + As a developer using python-docx + I need to a way to split a paragraph on its first rendered page break + + + Scenario: RenderedPageBreak.preceding_paragraph_fragment is the content before break + Given a rendered_page_break in a paragraph + Then rendered_page_break.preceding_paragraph_fragment is the content before break + + + Scenario: RenderedPageBreak.preceding_paragraph_fragment includes the hyperlink + Given a rendered_page_break in a hyperlink + Then rendered_page_break.preceding_paragraph_fragment includes the hyperlink + + + Scenario: RenderedPageBreak.following_paragraph_fragment is the content after break + Given a rendered_page_break in a paragraph + Then rendered_page_break.following_paragraph_fragment is the content after break + + + Scenario: RenderedPageBreak.following_paragraph_fragment excludes the hyperlink + Given a rendered_page_break in a hyperlink + Then rendered_page_break.following_paragraph_fragment excludes the hyperlink diff --git a/features/run-access-content.feature b/features/run-access-content.feature deleted file mode 100644 index ad30f6fe..00000000 --- a/features/run-access-content.feature +++ /dev/null @@ -1,9 +0,0 @@ -Feature: Access run content - In order to discover or locate existing inline content - As a developer using python-docx - I need ways to access the run content - - - Scenario: Get run content as Python text - Given a run having mixed text content - Then the text of the run represents the textual run content diff --git a/features/run-access-inner-content.feature b/features/run-access-inner-content.feature new file mode 100644 index 00000000..a9bbb170 --- /dev/null +++ b/features/run-access-inner-content.feature @@ -0,0 +1,25 @@ +Feature: Access run inner-content including rendered page-breaks + In order to extract run content with high-fidelity + As a developer using python-docx + I need to access differentiated run content in document order + + + Scenario Outline: Run.contains_page_break reports presence of page-break + Given a run having rendered page breaks + Then run.contains_page_break is + + Examples: Run.contains_page_break cases + | zero-or-more | value | + | no | False | + | one | True | + | two | True | + + + Scenario: Run.iter_inner_content() generates the run's text and rendered page-breaks + Given a run having two rendered page breaks + Then run.iter_inner_content() generates the run text and rendered page-breaks + + + Scenario: Run.text contains the text content of the run + Given a run having mixed text content + Then run.text contains the text content of the run diff --git a/features/run-add-content.feature b/features/run-add-content.feature index d4257925..078dccd3 100644 --- a/features/run-add-content.feature +++ b/features/run-add-content.feature @@ -11,4 +11,4 @@ Feature: Add content to a run Scenario: Assign mixed text to text property Given a run When I assign mixed text to the text property - Then the text of the run represents the textual run content + Then run.text contains the text content of the run diff --git a/features/sct-section.feature b/features/sct-section.feature index d0028740..7017d77a 100644 --- a/features/sct-section.feature +++ b/features/sct-section.feature @@ -57,6 +57,11 @@ Feature: Access and change section properties Then section.header is a _Header object + Scenario: Section.iter_inner_content() + Given a Section object of a multi-section document as section + Then section.iter_inner_content() produces the paragraphs and tables in section + + Scenario Outline: Get section start type Given a section having start type Then the reported section start type is diff --git a/features/steps/api.py b/features/steps/api.py index 1c66c4c8..16038ffe 100644 --- a/features/steps/api.py +++ b/features/steps/api.py @@ -1,18 +1,12 @@ -# encoding: utf-8 - -""" -Step implementations for basic API features -""" +"""Step implementations for basic API features.""" from behave import given, then, when import docx - from docx import Document from helpers import test_docx - # given ==================================================== diff --git a/features/steps/block.py b/features/steps/block.py index 686da2c9..e3d5c615 100644 --- a/features/steps/block.py +++ b/features/steps/block.py @@ -1,27 +1,43 @@ -# encoding: utf-8 - -""" -Step implementations for block content containers -""" +"""Step implementations for block content containers.""" from behave import given, then, when +from behave.runner import Context from docx import Document from docx.table import Table from helpers import test_docx - # given =================================================== +@given("a _Cell object with paragraphs and tables") +def given_a_cell_with_paragraphs_and_tables(context: Context): + context.cell = Document(test_docx("blk-paras-and-tables")).tables[1].rows[0].cells[0] + + +@given("a Document object with paragraphs and tables") +def given_a_document_with_paragraphs_and_tables(context: Context): + context.document = Document(test_docx("blk-paras-and-tables")) + + @given("a document containing a table") -def given_a_document_containing_a_table(context): +def given_a_document_containing_a_table(context: Context): context.document = Document(test_docx("blk-containing-table")) +@given("a Footer object with paragraphs and tables") +def given_a_footer_with_paragraphs_and_tables(context: Context): + context.footer = Document(test_docx("blk-paras-and-tables")).sections[0].footer + + +@given("a Header object with paragraphs and tables") +def given_a_header_with_paragraphs_and_tables(context: Context): + context.header = Document(test_docx("blk-paras-and-tables")).sections[0].header + + @given("a paragraph") -def given_a_paragraph(context): +def given_a_paragraph(context: Context): context.document = Document() context.paragraph = context.document.add_paragraph() @@ -30,13 +46,13 @@ def given_a_paragraph(context): @when("I add a paragraph") -def when_add_paragraph(context): +def when_add_paragraph(context: Context): document = context.document context.p = document.add_paragraph() @when("I add a table") -def when_add_table(context): +def when_add_table(context: Context): rows, cols = 2, 2 context.document.add_table(rows, cols) @@ -44,13 +60,41 @@ def when_add_table(context): # then ===================================================== +@then("cell.iter_inner_content() produces the block-items in document order") +def then_cell_iter_inner_content_produces_the_block_items(context: Context): + actual = [type(item).__name__ for item in context.cell.iter_inner_content()] + expected = ["Paragraph", "Table", "Paragraph"] + assert actual == expected, f"expected: {expected}, got: {actual}" + + +@then("document.iter_inner_content() produces the block-items in document order") +def then_document_iter_inner_content_produces_the_block_items(context: Context): + actual = [type(item).__name__ for item in context.document.iter_inner_content()] + expected = ["Table", "Paragraph", "Table", "Paragraph", "Table", "Paragraph"] + assert actual == expected, f"expected: {expected}, got: {actual}" + + +@then("footer.iter_inner_content() produces the block-items in document order") +def then_footer_iter_inner_content_produces_the_block_items(context: Context): + actual = [type(item).__name__ for item in context.footer.iter_inner_content()] + expected = ["Paragraph", "Table", "Paragraph"] + assert actual == expected, f"expected: {expected}, got: {actual}" + + +@then("header.iter_inner_content() produces the block-items in document order") +def then_header_iter_inner_content_produces_the_block_items(context: Context): + actual = [type(item).__name__ for item in context.header.iter_inner_content()] + expected = ["Table", "Paragraph"] + assert actual == expected, f"expected: {expected}, got: {actual}" + + @then("I can access the table") -def then_can_access_table(context): +def then_can_access_table(context: Context): table = context.document.tables[-1] assert isinstance(table, Table) @then("the new table appears in the document") -def then_new_table_appears_in_document(context): +def then_new_table_appears_in_document(context: Context): table = context.document.tables[-1] assert isinstance(table, Table) diff --git a/features/steps/cell.py b/features/steps/cell.py deleted file mode 100644 index 4ec633ae..00000000 --- a/features/steps/cell.py +++ /dev/null @@ -1,57 +0,0 @@ -# encoding: utf-8 - -""" -Step implementations for table cell-related features -""" - -from __future__ import absolute_import, print_function, unicode_literals - -from behave import given, then, when - -from docx import Document - -from helpers import test_docx - - -# given =================================================== - - -@given("a table cell") -def given_a_table_cell(context): - table = Document(test_docx("tbl-2x2-table")).tables[0] - context.cell = table.cell(0, 0) - - -# when ===================================================== - - -@when("I add a 2 x 2 table into the first cell") -def when_I_add_a_2x2_table_into_the_first_cell(context): - context.table_ = context.cell.add_table(2, 2) - - -@when("I assign a string to the cell text attribute") -def when_assign_string_to_cell_text_attribute(context): - cell = context.cell - text = "foobar" - cell.text = text - context.expected_text = text - - -# then ===================================================== - - -@then("cell.tables[0] is a 2 x 2 table") -def then_cell_tables_0_is_a_2x2_table(context): - cell = context.cell - table = cell.tables[0] - assert len(table.rows) == 2 - assert len(table.columns) == 2 - - -@then("the cell contains the string I assigned") -def then_cell_contains_string_assigned(context): - cell, expected_text = context.cell, context.expected_text - text = cell.paragraphs[0].runs[0].text - msg = "expected '%s', got '%s'" % (expected_text, text) - assert text == expected_text, msg diff --git a/features/steps/comments.py b/features/steps/comments.py new file mode 100644 index 00000000..39680f25 --- /dev/null +++ b/features/steps/comments.py @@ -0,0 +1,284 @@ +"""Step implementations for document comments-related features.""" + +import datetime as dt + +from behave import given, then, when +from behave.runner import Context + +from docx import Document +from docx.comments import Comment, Comments +from docx.drawing import Drawing + +from helpers import test_docx + +# given ==================================================== + + +@given("a Comment object") +def given_a_comment_object(context: Context): + context.comment = Document(test_docx("comments-rich-para")).comments.get(0) + + +@given("a Comment object containing an embedded image") +def given_a_comment_object_containing_an_embedded_image(context: Context): + context.comment = Document(test_docx("comments-rich-para")).comments.get(1) + + +@given("a Comments object with {count} comments") +def given_a_comments_object_with_count_comments(context: Context, count: str): + testfile_name = {"0": "doc-default", "4": "comments-rich-para"}[count] + context.comments = Document(test_docx(testfile_name)).comments + + +@given("a default Comment object") +def given_a_default_comment_object(context: Context): + context.comment = Document(test_docx("comments-rich-para")).comments.add_comment() + + +@given("a document having a comments part") +def given_a_document_having_a_comments_part(context: Context): + context.document = Document(test_docx("comments-rich-para")) + + +@given("a document having no comments part") +def given_a_document_having_no_comments_part(context: Context): + context.document = Document(test_docx("doc-default")) + + +# when ===================================================== + + +@when('I assign "{author}" to comment.author') +def when_I_assign_author_to_comment_author(context: Context, author: str): + context.comment.author = author + + +@when("I assign comment = comments.add_comment()") +def when_I_assign_comment_eq_add_comment(context: Context): + context.comment = context.comments.add_comment() + + +@when('I assign comment = comments.add_comment(author="John Doe", initials="JD")') +def when_I_assign_comment_eq_comments_add_comment_with_author_and_initials(context: Context): + context.comment = context.comments.add_comment(author="John Doe", initials="JD") + + +@when('I assign comment = document.add_comment(runs, "A comment", "John Doe", "JD")') +def when_I_assign_comment_eq_document_add_comment(context: Context): + runs = list(context.document.paragraphs[0].runs) + context.comment = context.document.add_comment( + runs=runs, + text="A comment", + author="John Doe", + initials="JD", + ) + + +@when('I assign "{initials}" to comment.initials') +def when_I_assign_initials(context: Context, initials: str): + context.comment.initials = initials + + +@when("I assign para_text = comment.paragraphs[0].text") +def when_I_assign_para_text(context: Context): + context.para_text = context.comment.paragraphs[0].text + + +@when("I assign paragraph = comment.add_paragraph()") +def when_I_assign_default_add_paragraph(context: Context): + context.paragraph = context.comment.add_paragraph() + + +@when("I assign paragraph = comment.add_paragraph(text, style)") +def when_I_assign_add_paragraph_with_text_and_style(context: Context): + context.para_text = text = "Comment text" + context.para_style = style = "Normal" + context.paragraph = context.comment.add_paragraph(text, style) + + +@when("I assign run = paragraph.add_run()") +def when_I_assign_paragraph_add_run(context: Context): + context.run = context.paragraph.add_run() + + +@when("I call comments.get(2)") +def when_I_call_comments_get_2(context: Context): + context.comment = context.comments.get(2) + + +# then ===================================================== + + +@then("comment is a Comment object") +def then_comment_is_a_Comment_object(context: Context): + assert type(context.comment) is Comment + + +@then('comment.author == "{author}"') +def then_comment_author_eq_author(context: Context, author: str): + actual = context.comment.author + assert actual == author, f"expected author '{author}', got '{actual}'" + + +@then("comment.author is the author of the comment") +def then_comment_author_is_the_author_of_the_comment(context: Context): + actual = context.comment.author + assert actual == "Steve Canny", f"expected author 'Steve Canny', got '{actual}'" + + +@then("comment.comment_id == 0") +def then_comment_id_is_0(context: Context): + assert context.comment.comment_id == 0 + + +@then("comment.comment_id is the comment identifier") +def then_comment_comment_id_is_the_comment_identifier(context: Context): + assert context.comment.comment_id == 0 + + +@then("comment.initials is the initials of the comment author") +def then_comment_initials_is_the_initials_of_the_comment_author(context: Context): + initials = context.comment.initials + assert initials == "SJC", f"expected initials 'SJC', got '{initials}'" + + +@then('comment.initials == "{initials}"') +def then_comment_initials_eq_initials(context: Context, initials: str): + actual = context.comment.initials + assert actual == initials, f"expected initials '{initials}', got '{actual}'" + + +@then("comment.paragraphs[{idx}] == paragraph") +def then_comment_paragraphs_idx_eq_paragraph(context: Context, idx: str): + actual = context.comment.paragraphs[int(idx)]._p + expected = context.paragraph._p + assert actual == expected, "paragraphs do not compare equal" + + +@then('comment.paragraphs[{idx}].style.name == "{style}"') +def then_comment_paragraphs_idx_style_name_eq_style(context: Context, idx: str, style: str): + actual = context.comment.paragraphs[int(idx)]._p.style + expected = style + assert actual == expected, f"expected style name '{expected}', got '{actual}'" + + +@then('comment.text == "{text}"') +def then_comment_text_eq_text(context: Context, text: str): + actual = context.comment.text + expected = text + assert actual == expected, f"expected text '{expected}', got '{actual}'" + + +@then("comment.timestamp is the date and time the comment was authored") +def then_comment_timestamp_is_the_date_and_time_the_comment_was_authored(context: Context): + assert context.comment.timestamp == dt.datetime(2025, 6, 7, 11, 20, 0, tzinfo=dt.timezone.utc) + + +@then("comments.get({id}) == comment") +def then_comments_get_comment_id_eq_comment(context: Context, id: str): + comment_id = int(id) + comment = context.comments.get(comment_id) + + assert type(comment) is Comment, f"expected a Comment object, got {type(comment)}" + assert comment.comment_id == comment_id, ( + f"expected comment_id '{comment_id}', got '{comment.comment_id}'" + ) + + +@then("document.comments is a Comments object") +def then_document_comments_is_a_Comments_object(context: Context): + document = context.document + assert type(document.comments) is Comments + + +@then("I can extract the image from the comment") +def then_I_can_extract_the_image_from_the_comment(context: Context): + paragraph = context.comment.paragraphs[0] + run = paragraph.runs[2] + drawing = next(d for d in run.iter_inner_content() if isinstance(d, Drawing)) + assert drawing.has_picture + + image = drawing.image + + assert image.content_type == "image/jpeg", f"got {image.content_type}" + assert image.filename == "image.jpg", f"got {image.filename}" + assert image.sha1 == "1be010ea47803b00e140b852765cdf84f491da47", f"got {image.sha1}" + + +@then("iterating comments yields {count} Comment objects") +def then_iterating_comments_yields_count_comments(context: Context, count: str): + comment_iter = iter(context.comments) + + comment = next(comment_iter) + assert type(comment) is Comment, f"expected a Comment object, got {type(comment)}" + + remaining = list(comment_iter) + assert len(remaining) == int(count) - 1, "iterating comments did not yield the expected count" + + +@then("len(comment.paragraphs) == {count}") +def then_len_comment_paragraphs_eq_count(context: Context, count: str): + actual = len(context.comment.paragraphs) + expected = int(count) + assert actual == expected, f"expected len(comment.paragraphs) of {expected}, got {actual}" + + +@then("len(comments) == {count}") +def then_len_comments_eq_count(context: Context, count: str): + actual = len(context.comments) + expected = int(count) + assert actual == expected, f"expected len(comments) of {expected}, got {actual}" + + +@then("para_text is the text of the first paragraph in the comment") +def then_para_text_is_the_text_of_the_first_paragraph_in_the_comment(context: Context): + actual = context.para_text + expected = "Text with hyperlink https://google.com embedded." + assert actual == expected, f"expected para_text '{expected}', got '{actual}'" + + +@then("paragraph.style == style") +def then_paragraph_style_eq_known_style(context: Context): + actual = context.paragraph.style.name + expected = context.para_style + assert actual == expected, f"expected paragraph.style '{expected}', got '{actual}'" + + +@then('paragraph.style == "{style}"') +def then_paragraph_style_eq_style(context: Context, style: str): + actual = context.paragraph._p.style + expected = style + assert actual == expected, f"expected paragraph.style '{expected}', got '{actual}'" + + +@then("paragraph.text == text") +def then_paragraph_text_eq_known_text(context: Context): + actual = context.paragraph.text + expected = context.para_text + assert actual == expected, f"expected paragraph.text '{expected}', got '{actual}'" + + +@then('paragraph.text == ""') +def then_paragraph_text_eq_text(context: Context): + actual = context.paragraph.text + expected = "" + assert actual == expected, f"expected paragraph.text '{expected}', got '{actual}'" + + +@then("run.iter_inner_content() yields a single Picture drawing") +def then_run_iter_inner_content_yields_a_single_picture_drawing(context: Context): + inner_content = list(context.run.iter_inner_content()) + + assert len(inner_content) == 1, ( + f"expected a single inner content element, got {len(inner_content)}" + ) + inner_content_item = inner_content[0] + assert isinstance(inner_content_item, Drawing) + assert inner_content_item.has_picture + + +@then("the result is a Comment object with id 2") +def then_the_result_is_a_comment_object_with_id_2(context: Context): + comment = context.comment + assert type(comment) is Comment, f"expected a Comment object, got {type(comment)}" + assert comment.comment_id == 2, f"expected comment_id `2`, got '{comment.comment_id}'" diff --git a/features/steps/coreprops.py b/features/steps/coreprops.py index e13c5f8f..90467fb6 100644 --- a/features/steps/coreprops.py +++ b/features/steps/coreprops.py @@ -1,31 +1,25 @@ -# encoding: utf-8 +"""Gherkin step implementations for core properties-related features.""" -""" -Gherkin step implementations for core properties-related features. -""" - -from __future__ import absolute_import, division, print_function, unicode_literals - -from datetime import datetime, timedelta +import datetime as dt from behave import given, then, when +from behave.runner import Context from docx import Document from docx.opc.coreprops import CoreProperties from helpers import test_docx - # given =================================================== @given("a document having known core properties") -def given_a_document_having_known_core_properties(context): +def given_a_document_having_known_core_properties(context: Context): context.document = Document(test_docx("doc-coreprops")) @given("a document having no core properties part") -def given_a_document_having_no_core_properties_part(context): +def given_a_document_having_no_core_properties_part(context: Context): context.document = Document(test_docx("doc-no-coreprops")) @@ -33,24 +27,24 @@ def given_a_document_having_no_core_properties_part(context): @when("I access the core properties object") -def when_I_access_the_core_properties_object(context): +def when_I_access_the_core_properties_object(context: Context): context.document.core_properties @when("I assign new values to the properties") -def when_I_assign_new_values_to_the_properties(context): +def when_I_assign_new_values_to_the_properties(context: Context): context.propvals = ( ("author", "Creator"), ("category", "Category"), ("comments", "Description"), ("content_status", "Content Status"), - ("created", datetime(2013, 6, 15, 12, 34, 56)), + ("created", dt.datetime(2013, 6, 15, 12, 34, 56, tzinfo=dt.timezone.utc)), ("identifier", "Identifier"), ("keywords", "key; word; keyword"), ("language", "Language"), ("last_modified_by", "Last Modified By"), - ("last_printed", datetime(2013, 6, 15, 12, 34, 56)), - ("modified", datetime(2013, 6, 15, 12, 34, 56)), + ("last_printed", dt.datetime(2013, 6, 15, 12, 34, 56, tzinfo=dt.timezone.utc)), + ("modified", dt.datetime(2013, 6, 15, 12, 34, 56, tzinfo=dt.timezone.utc)), ("revision", 9), ("subject", "Subject"), ("title", "Title"), @@ -65,39 +59,39 @@ def when_I_assign_new_values_to_the_properties(context): @then("a core properties part with default values is added") -def then_a_core_properties_part_with_default_values_is_added(context): +def then_a_core_properties_part_with_default_values_is_added(context: Context): core_properties = context.document.core_properties assert core_properties.title == "Word Document" assert core_properties.last_modified_by == "python-docx" assert core_properties.revision == 1 # core_properties.modified only stores time with seconds resolution, so # comparison needs to be a little loose (within two seconds) - modified_timedelta = datetime.utcnow() - core_properties.modified - max_expected_timedelta = timedelta(seconds=2) + modified_timedelta = dt.datetime.now(dt.timezone.utc) - core_properties.modified + max_expected_timedelta = dt.timedelta(seconds=2) assert modified_timedelta < max_expected_timedelta @then("I can access the core properties object") -def then_I_can_access_the_core_properties_object(context): +def then_I_can_access_the_core_properties_object(context: Context): document = context.document core_properties = document.core_properties assert isinstance(core_properties, CoreProperties) @then("the core property values match the known values") -def then_the_core_property_values_match_the_known_values(context): +def then_the_core_property_values_match_the_known_values(context: Context): known_propvals = ( ("author", "Steve Canny"), ("category", "Category"), ("comments", "Description"), ("content_status", "Content Status"), - ("created", datetime(2014, 12, 13, 22, 2, 0)), + ("created", dt.datetime(2014, 12, 13, 22, 2, 0, tzinfo=dt.timezone.utc)), ("identifier", "Identifier"), ("keywords", "key; word; keyword"), ("language", "Language"), ("last_modified_by", "Steve Canny"), - ("last_printed", datetime(2014, 12, 13, 22, 2, 42)), - ("modified", datetime(2014, 12, 13, 22, 6, 0)), + ("last_printed", dt.datetime(2014, 12, 13, 22, 2, 42, tzinfo=dt.timezone.utc)), + ("modified", dt.datetime(2014, 12, 13, 22, 6, 0, tzinfo=dt.timezone.utc)), ("revision", 2), ("subject", "Subject"), ("title", "Title"), @@ -113,7 +107,7 @@ def then_the_core_property_values_match_the_known_values(context): @then("the core property values match the new values") -def then_the_core_property_values_match_the_new_values(context): +def then_the_core_property_values_match_the_new_values(context: Context): core_properties = context.document.core_properties for name, expected_value in context.propvals: value = getattr(core_properties, name) diff --git a/features/steps/document.py b/features/steps/document.py index 2aae3e19..1c12ac10 100644 --- a/features/steps/document.py +++ b/features/steps/document.py @@ -1,25 +1,18 @@ -# encoding: utf-8 - -""" -Step implementations for document-related features -""" - -from __future__ import absolute_import, print_function, unicode_literals +"""Step implementations for document-related features.""" from behave import given, then, when from docx import Document from docx.enum.section import WD_ORIENT, WD_SECTION +from docx.section import Sections from docx.shape import InlineShapes from docx.shared import Inches -from docx.section import Sections from docx.styles.styles import Styles from docx.table import Table from docx.text.paragraph import Paragraph from helpers import test_docx, test_file - # given =================================================== @@ -133,17 +126,13 @@ def when_add_picture_specifying_width_and_height(context): @when("I add a picture specifying a height of 1.5 inches") def when_add_picture_specifying_height(context): document = context.document - context.picture = document.add_picture( - test_file("monty-truth.png"), height=Inches(1.5) - ) + context.picture = document.add_picture(test_file("monty-truth.png"), height=Inches(1.5)) @when("I add a picture specifying a width of 1.5 inches") def when_add_picture_specifying_width(context): document = context.document - context.picture = document.add_picture( - test_file("monty-truth.png"), width=Inches(1.5) - ) + context.picture = document.add_picture(test_file("monty-truth.png"), width=Inches(1.5)) @when("I add a picture specifying only the image file") diff --git a/features/steps/font.py b/features/steps/font.py index 720b29c5..6f91df8e 100644 --- a/features/steps/font.py +++ b/features/steps/font.py @@ -1,10 +1,4 @@ -# encoding: utf-8 - -""" -Step implementations for font-related features. -""" - -from __future__ import absolute_import, division, print_function, unicode_literals +"""Step implementations for font-related features.""" from behave import given, then, when @@ -16,7 +10,6 @@ from helpers import test_docx - # given =================================================== @@ -195,13 +188,15 @@ def then_font_highlight_color_is_value(context, value): @then("font.name is {value}") def then_font_name_is_value(context, value): font = context.font - fontname = font.name - if isinstance(fontname, dict): - # word started differentiating typefaces for different regions of the world in 2025 - # font.name is a dict of typeface names for different scripts - fontname = font.name['ascii'] # test against ascii name - value = None if value == "None" else value - assert fontname == value, f"expected '{value}', got '{fontname}'" + expected_value = None if value == "None" else value + actual_value = font.name + if isinstance(actual_value, dict): + if expected_value is None: + assert all(v is None for v in actual_value.values()) + else: + assert actual_value["ascii"] == expected_value + else: + assert actual_value == expected_value @then("font.size is {value}") diff --git a/features/steps/hdrftr.py b/features/steps/hdrftr.py index 4f0e3b91..5949f961 100644 --- a/features/steps/hdrftr.py +++ b/features/steps/hdrftr.py @@ -1,8 +1,4 @@ -# encoding: utf-8 - -"""Step implementations for header and footer-related features""" - -from __future__ import absolute_import, division, print_function, unicode_literals +"""Step implementations for header and footer-related features.""" from behave import given, then, when @@ -10,7 +6,6 @@ from helpers import test_docx, test_file - # given ==================================================== diff --git a/features/steps/helpers.py b/features/steps/helpers.py index cd64a786..fc40697b 100644 --- a/features/steps/helpers.py +++ b/features/steps/helpers.py @@ -1,21 +1,17 @@ -# encoding: utf-8 - -""" -Helper methods and variables for acceptance tests. -""" +"""Helper methods and variables for acceptance tests.""" import os -def absjoin(*paths): +def absjoin(*paths: str) -> str: return os.path.abspath(os.path.join(*paths)) -thisdir = os.path.split(__file__)[0] -scratch_dir = absjoin(thisdir, "../_scratch") +thisdir: str = os.path.split(__file__)[0] +scratch_dir: str = absjoin(thisdir, "../_scratch") # scratch output docx file ------------- -saved_docx_path = absjoin(scratch_dir, "test_out.docx") +saved_docx_path: str = absjoin(scratch_dir, "test_out.docx") bool_vals = {"True": True, "False": False} @@ -28,15 +24,11 @@ def absjoin(*paths): } -def test_docx(name): - """ - Return the absolute path to test .docx file with root name *name*. - """ +def test_docx(name: str): + """Return the absolute path to test .docx file with root name `name`.""" return absjoin(thisdir, "test_files", "%s.docx" % name) -def test_file(name): - """ - Return the absolute path to file with *name* in test_files directory - """ +def test_file(name: str): + """Return the absolute path to file with `name` in test_files directory""" return absjoin(thisdir, "test_files", "%s" % name) diff --git a/features/steps/hyperlink.py b/features/steps/hyperlink.py new file mode 100644 index 00000000..14fa9f7b --- /dev/null +++ b/features/steps/hyperlink.py @@ -0,0 +1,116 @@ +"""Step implementations for hyperlink-related features.""" + +from __future__ import annotations + +from typing import Dict, Tuple + +from behave import given, then +from behave.runner import Context + +from docx import Document + +from helpers import test_docx + +# given =================================================== + + +@given("a hyperlink") +def given_a_hyperlink(context: Context): + document = Document(test_docx("par-hyperlinks")) + context.hyperlink = document.paragraphs[1].hyperlinks[0] + + +@given("a hyperlink having a URI fragment") +def given_a_hyperlink_having_a_uri_fragment(context: Context): + document = Document(test_docx("par-hlink-frags")) + context.hyperlink = document.paragraphs[1].hyperlinks[0] + + +@given("a hyperlink having address {address} and fragment {fragment}") +def given_a_hyperlink_having_address_and_fragment(context: Context, address: str, fragment: str): + paragraph_idxs: Dict[Tuple[str, str], int] = { + ("''", "linkedBookmark"): 1, + ("https://foo.com", "''"): 2, + ("https://foo.com?q=bar", "''"): 3, + ("http://foo.com/", "intro"): 4, + ("https://foo.com?q=bar#baz", "''"): 5, + ("court-exif.jpg", "''"): 7, + } + paragraph_idx = paragraph_idxs[(address, fragment)] + document = Document(test_docx("par-hlink-frags")) + paragraph = document.paragraphs[paragraph_idx] + context.hyperlink = paragraph.hyperlinks[0] + + +@given("a hyperlink having {zero_or_more} rendered page breaks") +def given_a_hyperlink_having_rendered_page_breaks(context: Context, zero_or_more: str): + paragraph_idx = { + "no": 1, + "one": 2, + }[zero_or_more] + document = Document(test_docx("par-hyperlinks")) + paragraph = document.paragraphs[paragraph_idx] + context.hyperlink = paragraph.hyperlinks[0] + + +@given("a hyperlink having {one_or_more} runs") +def given_a_hyperlink_having_one_or_more_runs(context: Context, one_or_more: str): + paragraph_idx, hyperlink_idx = { + "one": (1, 0), + "two": (2, 1), + }[one_or_more] + document = Document(test_docx("par-hyperlinks")) + paragraph = document.paragraphs[paragraph_idx] + context.hyperlink = paragraph.hyperlinks[hyperlink_idx] + + +# then ===================================================== + + +@then("hyperlink.address is the URL of the hyperlink") +def then_hyperlink_address_is_the_URL_of_the_hyperlink(context: Context): + actual_value = context.hyperlink.address + expected_value = "http://yahoo.com/" + assert actual_value == expected_value, f"expected: {expected_value}, got: {actual_value}" + + +@then("hyperlink.contains_page_break is {value}") +def then_hyperlink_contains_page_break_is_value(context: Context, value: str): + actual_value = context.hyperlink.contains_page_break + expected_value = {"True": True, "False": False}[value] + assert actual_value == expected_value, f"expected: {expected_value}, got: {actual_value}" + + +@then("hyperlink.fragment is the URI fragment of the hyperlink") +def then_hyperlink_fragment_is_the_URI_fragment_of_the_hyperlink(context: Context): + actual_value = context.hyperlink.fragment + expected_value = "linkedBookmark" + assert actual_value == expected_value, f"expected: {expected_value}, got: {actual_value}" + + +@then("hyperlink.runs contains only Run instances") +def then_hyperlink_runs_contains_only_Run_instances(context: Context): + actual_value = [type(item).__name__ for item in context.hyperlink.runs] + expected_value = ["Run" for _ in context.hyperlink.runs] + assert actual_value == expected_value, f"expected: {expected_value}, got: {actual_value}" + + +@then("hyperlink.runs has length {value}") +def then_hyperlink_runs_has_length(context: Context, value: str): + actual_value = len(context.hyperlink.runs) + expected_value = int(value) + assert actual_value == expected_value, f"expected: {expected_value}, got: {actual_value}" + + +@then("hyperlink.text is the visible text of the hyperlink") +def then_hyperlink_text_is_the_visible_text_of_the_hyperlink(context: Context): + actual_value = context.hyperlink.text + expected_value = "awesome hyperlink" + assert actual_value == expected_value, f"expected: {expected_value}, got: {actual_value}" + + +@then("hyperlink.url is {value}") +def then_hyperlink_url_is_value(context: Context, value: str): + actual_value = context.hyperlink.url + expected_value = "" if value == "''" else value + assert actual_value == expected_value, f"expected: {expected_value}, got: {actual_value}" diff --git a/features/steps/image.py b/features/steps/image.py index 7f80baa5..5ac54169 100644 --- a/features/steps/image.py +++ b/features/steps/image.py @@ -1,10 +1,4 @@ -# encoding: utf-8 - -""" -Step implementations for image characterization features -""" - -from __future__ import absolute_import, print_function, unicode_literals +"""Step implementations for image characterization features.""" from behave import given, then, when @@ -12,7 +6,6 @@ from helpers import test_file - # given =================================================== diff --git a/features/steps/numbering.py b/features/steps/numbering.py index 2a20fd08..be88ceee 100644 --- a/features/steps/numbering.py +++ b/features/steps/numbering.py @@ -1,8 +1,4 @@ -# encoding: utf-8 - -""" -Step implementations for numbering-related features -""" +"""Step implementations for numbering-related features.""" from behave import given, then, when @@ -10,7 +6,6 @@ from helpers import test_docx - # given =================================================== diff --git a/features/steps/pagebreak.py b/features/steps/pagebreak.py new file mode 100644 index 00000000..87042812 --- /dev/null +++ b/features/steps/pagebreak.py @@ -0,0 +1,135 @@ +"""Step implementations for rendered page-break related features.""" + +from __future__ import annotations + +from behave import given, then +from behave.runner import Context + +from docx import Document +from docx.enum.text import WD_PARAGRAPH_ALIGNMENT + +from helpers import test_docx + +# given =================================================== + + +@given("a rendered_page_break in a hyperlink") +def given_a_rendered_page_break_in_a_hyperlink(context: Context): + document = Document(test_docx("par-rendered-page-breaks")) + paragraph = document.paragraphs[2] + context.rendered_page_break = paragraph.rendered_page_breaks[0] + + +@given("a rendered_page_break in a paragraph") +def given_a_rendered_page_break_in_a_paragraph(context: Context): + document = Document(test_docx("par-rendered-page-breaks")) + paragraph = document.paragraphs[1] + context.rendered_page_break = paragraph.rendered_page_breaks[0] + + +# then ===================================================== + + +@then("rendered_page_break.preceding_paragraph_fragment includes the hyperlink") +def then_rendered_page_break_preceding_paragraph_fragment_includes_the_hyperlink( + context: Context, +): + para_frag = context.rendered_page_break.preceding_paragraph_fragment + + actual_value = type(para_frag).__name__ + expected_value = "Paragraph" + assert actual_value == expected_value, f"expected: '{expected_value}', got: '{actual_value}'" + + actual_value = para_frag.text + expected_value = "Page break in>>< 0 assert all(isinstance(s, BaseStyle) for s in styles) @then("I can iterate over the latent styles") def then_I_can_iterate_over_the_latent_styles(context): - latent_styles = [ls for ls in context.latent_styles] + latent_styles = list(context.latent_styles) assert len(latent_styles) == 137 assert all(isinstance(ls, _LatentStyle) for ls in latent_styles) diff --git a/features/steps/table.py b/features/steps/table.py index 83751d1f..38d49ee0 100644 --- a/features/steps/table.py +++ b/features/steps/table.py @@ -1,32 +1,32 @@ -# encoding: utf-8 +# pyright: reportPrivateUsage=false -""" -Step implementations for table-related features -""" - -from __future__ import absolute_import, division, print_function, unicode_literals +"""Step implementations for table-related features.""" from behave import given, then, when +from behave.runner import Context from docx import Document -from docx.enum.table import WD_ALIGN_VERTICAL # noqa -from docx.enum.table import WD_ROW_HEIGHT_RULE, WD_TABLE_ALIGNMENT, WD_TABLE_DIRECTION +from docx.enum.table import ( + WD_ALIGN_VERTICAL, + WD_ROW_HEIGHT_RULE, + WD_TABLE_ALIGNMENT, + WD_TABLE_DIRECTION, +) from docx.shared import Inches -from docx.table import _Column, _Columns, _Row, _Rows +from docx.table import Table, _Cell, _Column, _Columns, _Row, _Rows from helpers import test_docx - # given =================================================== @given("a 2 x 2 table") -def given_a_2x2_table(context): +def given_a_2x2_table(context: Context): context.table_ = Document().add_table(rows=2, cols=2) @given("a 3x3 table having {span_state}") -def given_a_3x3_table_having_span_state(context, span_state): +def given_a_3x3_table_having_span_state(context: Context, span_state: str): table_idx = { "only uniform cells": 0, "a horizontal span": 1, @@ -37,8 +37,15 @@ def given_a_3x3_table_having_span_state(context, span_state): context.table_ = document.tables[table_idx] +@given("a _Cell object spanning {count} layout-grid cells") +def given_a_Cell_object_spanning_count_layout_grid_cells(context: Context, count: str): + document = Document(test_docx("tbl-cell-props")) + table = document.tables[0] + context.cell = _Cell(table._tbl.tr_lst[int(count)].tc_lst[0], table) + + @given("a _Cell object with {state} vertical alignment as cell") -def given_a_Cell_object_with_vertical_alignment_as_cell(context, state): +def given_a_Cell_object_with_vertical_alignment_as_cell(context: Context, state: str): table_idx = { "inherited": 0, "bottom": 1, @@ -51,26 +58,32 @@ def given_a_Cell_object_with_vertical_alignment_as_cell(context, state): @given("a column collection having two columns") -def given_a_column_collection_having_two_columns(context): +def given_a_column_collection_having_two_columns(context: Context): docx_path = test_docx("blk-containing-table") document = Document(docx_path) context.columns = document.tables[0].columns @given("a row collection having two rows") -def given_a_row_collection_having_two_rows(context): +def given_a_row_collection_having_two_rows(context: Context): docx_path = test_docx("blk-containing-table") document = Document(docx_path) context.rows = document.tables[0].rows @given("a table") -def given_a_table(context): +def given_a_table(context: Context): context.table_ = Document().add_table(rows=2, cols=2) +@given("a table cell") +def given_a_table_cell(context: Context): + table = Document(test_docx("tbl-2x2-table")).tables[0] + context.cell = table.cell(0, 0) + + @given("a table cell having a width of {width}") -def given_a_table_cell_having_a_width_of_width(context, width): +def given_a_table_cell_having_a_width_of_width(context: Context, width: str): table_idx = {"no explicit setting": 0, "1 inch": 1, "2 inches": 2}[width] document = Document(test_docx("tbl-props")) table = document.tables[table_idx] @@ -79,7 +92,7 @@ def given_a_table_cell_having_a_width_of_width(context, width): @given("a table column having a width of {width_desc}") -def given_a_table_having_a_width_of_width_desc(context, width_desc): +def given_a_table_having_a_width_of_width_desc(context: Context, width_desc: str): col_idx = { "no explicit setting": 0, "1440": 1, @@ -90,7 +103,7 @@ def given_a_table_having_a_width_of_width_desc(context, width_desc): @given("a table having {alignment} alignment") -def given_a_table_having_alignment_alignment(context, alignment): +def given_a_table_having_alignment_alignment(context: Context, alignment: str): table_idx = { "inherited": 3, "left": 4, @@ -103,7 +116,7 @@ def given_a_table_having_alignment_alignment(context, alignment): @given("a table having an autofit layout of {autofit}") -def given_a_table_having_an_autofit_layout_of_autofit(context, autofit): +def given_a_table_having_an_autofit_layout_of_autofit(context: Context, autofit: str): tbl_idx = { "no explicit setting": 0, "autofit": 1, @@ -114,7 +127,7 @@ def given_a_table_having_an_autofit_layout_of_autofit(context, autofit): @given("a table having {style} style") -def given_a_table_having_style(context, style): +def given_a_table_having_style(context: Context, style: str): table_idx = { "no explicit": 0, "Table Grid": 1, @@ -126,14 +139,14 @@ def given_a_table_having_style(context, style): @given("a table having table direction set {setting}") -def given_a_table_having_table_direction_setting(context, setting): +def given_a_table_having_table_direction_setting(context: Context, setting: str): table_idx = ["to inherit", "right-to-left", "left-to-right"].index(setting) document = Document(test_docx("tbl-on-off-props")) context.table_ = document.tables[table_idx] @given("a table having two columns") -def given_a_table_having_two_columns(context): +def given_a_table_having_two_columns(context: Context): docx_path = test_docx("blk-containing-table") document = Document(docx_path) # context.table is used internally by behave, underscore added @@ -142,14 +155,21 @@ def given_a_table_having_two_columns(context): @given("a table having two rows") -def given_a_table_having_two_rows(context): +def given_a_table_having_two_rows(context: Context): docx_path = test_docx("blk-containing-table") document = Document(docx_path) context.table_ = document.tables[0] +@given("a table row ending with {count} empty grid columns") +def given_a_table_row_ending_with_count_empty_grid_columns(context: Context, count: str): + document = Document(test_docx("tbl-props")) + table = document.tables[8] + context.row = table.rows[int(count)] + + @given("a table row having height of {state}") -def given_a_table_row_having_height_of_state(context, state): +def given_a_table_row_having_height_of_state(context: Context, state: str): table_idx = {"no explicit setting": 0, "2 inches": 2, "3 inches": 3}[state] document = Document(test_docx("tbl-props")) table = document.tables[table_idx] @@ -157,48 +177,66 @@ def given_a_table_row_having_height_of_state(context, state): @given("a table row having height rule {state}") -def given_a_table_row_having_height_rule_state(context, state): - table_idx = {"no explicit setting": 0, "automatic": 1, "at least": 2, "exactly": 3}[ - state - ] +def given_a_table_row_having_height_rule_state(context: Context, state: str): + table_idx = {"no explicit setting": 0, "automatic": 1, "at least": 2, "exactly": 3}[state] document = Document(test_docx("tbl-props")) table = document.tables[table_idx] context.row = table.rows[0] +@given("a table row starting with {count} empty grid columns") +def given_a_table_row_starting_with_count_empty_grid_columns(context: Context, count: str): + document = Document(test_docx("tbl-props")) + table = document.tables[7] + context.row = table.rows[int(count)] + + # when ===================================================== @when("I add a 1.0 inch column to the table") -def when_I_add_a_1_inch_column_to_table(context): +def when_I_add_a_1_inch_column_to_table(context: Context): context.column = context.table_.add_column(Inches(1.0)) +@when("I add a 2 x 2 table into the first cell") +def when_I_add_a_2x2_table_into_the_first_cell(context: Context): + context.table_ = context.cell.add_table(2, 2) + + @when("I add a row to the table") -def when_add_row_to_table(context): +def when_add_row_to_table(context: Context): table = context.table_ context.row = table.add_row() +@when("I assign a string to the cell text attribute") +def when_assign_string_to_cell_text_attribute(context: Context): + cell = context.cell + text = "foobar" + cell.text = text + context.expected_text = text + + @when("I assign {value} to cell.vertical_alignment") -def when_I_assign_value_to_cell_vertical_alignment(context, value): +def when_I_assign_value_to_cell_vertical_alignment(context: Context, value: str): context.cell.vertical_alignment = eval(value) @when("I assign {value} to row.height") -def when_I_assign_value_to_row_height(context, value): +def when_I_assign_value_to_row_height(context: Context, value: str): new_value = None if value == "None" else int(value) context.row.height = new_value @when("I assign {value} to row.height_rule") -def when_I_assign_value_to_row_height_rule(context, value): +def when_I_assign_value_to_row_height_rule(context: Context, value: str): new_value = None if value == "None" else getattr(WD_ROW_HEIGHT_RULE, value) context.row.height_rule = new_value @when("I assign {value_str} to table.alignment") -def when_I_assign_value_to_table_alignment(context, value_str): +def when_I_assign_value_to_table_alignment(context: Context, value_str: str): value = { "None": None, "WD_TABLE_ALIGNMENT.LEFT": WD_TABLE_ALIGNMENT.LEFT, @@ -210,7 +248,7 @@ def when_I_assign_value_to_table_alignment(context, value_str): @when("I assign {value} to table.style") -def when_apply_value_to_table_style(context, value): +def when_apply_value_to_table_style(context: Context, value: str): table, styles = context.table_, context.document.styles if value == "None": new_value = None @@ -222,14 +260,14 @@ def when_apply_value_to_table_style(context, value): @when("I assign {value} to table.table_direction") -def when_assign_value_to_table_table_direction(context, value): +def when_assign_value_to_table_table_direction(context: Context, value: str): new_value = None if value == "None" else getattr(WD_TABLE_DIRECTION, value) context.table_.table_direction = new_value @when("I merge from cell {origin} to cell {other}") -def when_I_merge_from_cell_origin_to_cell_other(context, origin, other): - def cell(table, idx): +def when_I_merge_from_cell_origin_to_cell_other(context: Context, origin: str, other: str): + def cell(table: Table, idx: int): row, col = idx // 3, idx % 3 return table.cell(row, col) @@ -240,19 +278,19 @@ def cell(table, idx): @when("I set the cell width to {width}") -def when_I_set_the_cell_width_to_width(context, width): +def when_I_set_the_cell_width_to_width(context: Context, width: str): new_value = {"1 inch": Inches(1)}[width] context.cell.width = new_value @when("I set the column width to {width_emu}") -def when_I_set_the_column_width_to_width_emu(context, width_emu): +def when_I_set_the_column_width_to_width_emu(context: Context, width_emu: str): new_value = None if width_emu == "None" else int(width_emu) context.column.width = new_value @when("I set the table autofit to {setting}") -def when_I_set_the_table_autofit_to_setting(context, setting): +def when_I_set_the_table_autofit_to_setting(context: Context, setting: str): new_value = {"autofit": True, "fixed": False}[setting] table = context.table_ table.autofit = new_value @@ -261,17 +299,34 @@ def when_I_set_the_table_autofit_to_setting(context, setting): # then ===================================================== +@then("cell.grid_span is {count}") +def then_cell_grid_span_is_count(context: Context, count: str): + expected = int(count) + actual = context.cell.grid_span + assert actual == expected, f"expected {expected}, got {actual}" + + +@then("cell.tables[0] is a 2 x 2 table") +def then_cell_tables_0_is_a_2x2_table(context: Context): + cell = context.cell + table = cell.tables[0] + assert len(table.rows) == 2 + assert len(table.columns) == 2 + + @then("cell.vertical_alignment is {value}") -def then_cell_vertical_alignment_is_value(context, value): - expected_value = eval(value) +def then_cell_vertical_alignment_is_value(context: Context, value: str): + expected_value = { + "None": None, + "WD_ALIGN_VERTICAL.BOTTOM": WD_ALIGN_VERTICAL.BOTTOM, + "WD_ALIGN_VERTICAL.CENTER": WD_ALIGN_VERTICAL.CENTER, + }[value] actual_value = context.cell.vertical_alignment - assert actual_value is expected_value, ( - "cell.vertical_alignment is %s" % actual_value - ) + assert actual_value is expected_value, "cell.vertical_alignment is %s" % actual_value @then("I can access a collection column by index") -def then_can_access_collection_column_by_index(context): +def then_can_access_collection_column_by_index(context: Context): columns = context.columns for idx in range(2): column = columns[idx] @@ -279,7 +334,7 @@ def then_can_access_collection_column_by_index(context): @then("I can access a collection row by index") -def then_can_access_collection_row_by_index(context): +def then_can_access_collection_row_by_index(context: Context): rows = context.rows for idx in range(2): row = rows[idx] @@ -287,21 +342,21 @@ def then_can_access_collection_row_by_index(context): @then("I can access the column collection of the table") -def then_can_access_column_collection_of_table(context): +def then_can_access_column_collection_of_table(context: Context): table = context.table_ columns = table.columns assert isinstance(columns, _Columns) @then("I can access the row collection of the table") -def then_can_access_row_collection_of_table(context): +def then_can_access_row_collection_of_table(context: Context): table = context.table_ rows = table.rows assert isinstance(rows, _Rows) @then("I can iterate over the column collection") -def then_can_iterate_over_column_collection(context): +def then_can_iterate_over_column_collection(context: Context): columns = context.columns actual_count = 0 for column in columns: @@ -311,7 +366,7 @@ def then_can_iterate_over_column_collection(context): @then("I can iterate over the row collection") -def then_can_iterate_over_row_collection(context): +def then_can_iterate_over_row_collection(context: Context): rows = context.rows actual_count = 0 for row in rows: @@ -320,8 +375,22 @@ def then_can_iterate_over_row_collection(context): assert actual_count == 2 +@then("row.grid_cols_after is {value}") +def then_row_grid_cols_after_is_value(context: Context, value: str): + expected = int(value) + actual = context.row.grid_cols_after + assert actual == expected, "expected %s, got %s" % (expected, actual) + + +@then("row.grid_cols_before is {value}") +def then_row_grid_cols_before_is_value(context: Context, value: str): + expected = int(value) + actual = context.row.grid_cols_before + assert actual == expected, "expected %s, got %s" % (expected, actual) + + @then("row.height is {value}") -def then_row_height_is_value(context, value): +def then_row_height_is_value(context: Context, value: str): expected_height = None if value == "None" else int(value) actual_height = context.row.height assert actual_height == expected_height, "expected %s, got %s" % ( @@ -331,7 +400,7 @@ def then_row_height_is_value(context, value): @then("row.height_rule is {value}") -def then_row_height_rule_is_value(context, value): +def then_row_height_rule_is_value(context: Context, value: str): expected_rule = None if value == "None" else getattr(WD_ROW_HEIGHT_RULE, value) actual_rule = context.row.height_rule assert actual_rule == expected_rule, "expected %s, got %s" % ( @@ -341,7 +410,7 @@ def then_row_height_rule_is_value(context, value): @then("table.alignment is {value_str}") -def then_table_alignment_is_value(context, value_str): +def then_table_alignment_is_value(context: Context, value_str: str): value = { "None": None, "WD_TABLE_ALIGNMENT.LEFT": WD_TABLE_ALIGNMENT.LEFT, @@ -353,7 +422,7 @@ def then_table_alignment_is_value(context, value_str): @then("table.cell({row}, {col}).text is {expected_text}") -def then_table_cell_row_col_text_is_text(context, row, col, expected_text): +def then_table_cell_row_col_text_is_text(context: Context, row: str, col: str, expected_text: str): table = context.table_ row_idx, col_idx = int(row), int(col) cell_text = table.cell(row_idx, col_idx).text @@ -361,68 +430,76 @@ def then_table_cell_row_col_text_is_text(context, row, col, expected_text): @then("table.style is styles['{style_name}']") -def then_table_style_is_styles_style_name(context, style_name): +def then_table_style_is_styles_style_name(context: Context, style_name: str): table, styles = context.table_, context.document.styles expected_style = styles[style_name] assert table.style == expected_style, "got '%s'" % table.style @then("table.table_direction is {value}") -def then_table_table_direction_is_value(context, value): +def then_table_table_direction_is_value(context: Context, value: str): expected_value = None if value == "None" else getattr(WD_TABLE_DIRECTION, value) actual_value = context.table_.table_direction assert actual_value == expected_value, "got '%s'" % actual_value +@then("the cell contains the string I assigned") +def then_cell_contains_string_assigned(context: Context): + cell, expected_text = context.cell, context.expected_text + text = cell.paragraphs[0].runs[0].text + msg = "expected '%s', got '%s'" % (expected_text, text) + assert text == expected_text, msg + + @then("the column cells text is {expected_text}") -def then_the_column_cells_text_is_expected_text(context, expected_text): +def then_the_column_cells_text_is_expected_text(context: Context, expected_text: str): table = context.table_ cells_text = " ".join(c.text for col in table.columns for c in col.cells) assert cells_text == expected_text, "got %s" % cells_text @then("the length of the column collection is 2") -def then_len_of_column_collection_is_2(context): +def then_len_of_column_collection_is_2(context: Context): columns = context.table_.columns assert len(columns) == 2 @then("the length of the row collection is 2") -def then_len_of_row_collection_is_2(context): +def then_len_of_row_collection_is_2(context: Context): rows = context.table_.rows assert len(rows) == 2 @then("the new column has 2 cells") -def then_new_column_has_2_cells(context): +def then_new_column_has_2_cells(context: Context): assert len(context.column.cells) == 2 @then("the new column is 1.0 inches wide") -def then_new_column_is_1_inches_wide(context): +def then_new_column_is_1_inches_wide(context: Context): assert context.column.width == Inches(1) @then("the new row has 2 cells") -def then_new_row_has_2_cells(context): +def then_new_row_has_2_cells(context: Context): assert len(context.row.cells) == 2 @then("the reported autofit setting is {autofit}") -def then_the_reported_autofit_setting_is_autofit(context, autofit): +def then_the_reported_autofit_setting_is_autofit(context: Context, autofit: str): expected_value = {"autofit": True, "fixed": False}[autofit] table = context.table_ assert table.autofit is expected_value @then("the reported column width is {width_emu}") -def then_the_reported_column_width_is_width_emu(context, width_emu): +def then_the_reported_column_width_is_width_emu(context: Context, width_emu: str): expected_value = None if width_emu == "None" else int(width_emu) assert context.column.width == expected_value, "got %s" % context.column.width @then("the reported width of the cell is {width}") -def then_the_reported_width_of_the_cell_is_width(context, width): +def then_the_reported_width_of_the_cell_is_width(context: Context, width: str): expected_width = {"None": None, "1 inch": Inches(1)}[width] actual_width = context.cell.width assert actual_width == expected_width, "expected %s, got %s" % ( @@ -432,7 +509,7 @@ def then_the_reported_width_of_the_cell_is_width(context, width): @then("the row cells text is {encoded_text}") -def then_the_row_cells_text_is_expected_text(context, encoded_text): +def then_the_row_cells_text_is_expected_text(context: Context, encoded_text: str): expected_text = encoded_text.replace("\\", "\n") table = context.table_ cells_text = " ".join(c.text for row in table.rows for c in row.cells) @@ -440,32 +517,33 @@ def then_the_row_cells_text_is_expected_text(context, encoded_text): @then("the table has {count} columns") -def then_table_has_count_columns(context, count): +def then_table_has_count_columns(context: Context, count: str): column_count = int(count) columns = context.table_.columns assert len(columns) == column_count @then("the table has {count} rows") -def then_table_has_count_rows(context, count): +def then_table_has_count_rows(context: Context, count: str): row_count = int(count) rows = context.table_.rows assert len(rows) == row_count @then("the width of cell {n_str} is {inches_str} inches") -def then_the_width_of_cell_n_is_x_inches(context, n_str, inches_str): - def _cell(table, idx): +def then_the_width_of_cell_n_is_x_inches(context: Context, n_str: str, inches_str: str): + def _cell(table: Table, idx: int): row, col = idx // 3, idx % 3 return table.cell(row, col) idx, inches = int(n_str) - 1, float(inches_str) cell = _cell(context.table_, idx) + assert cell.width is not None assert cell.width == Inches(inches), "got %s" % cell.width.inches @then("the width of each cell is {inches} inches") -def then_the_width_of_each_cell_is_inches(context, inches): +def then_the_width_of_each_cell_is_inches(context: Context, inches: str): table = context.table_ expected_width = Inches(float(inches)) for cell in table._cells: @@ -473,7 +551,7 @@ def then_the_width_of_each_cell_is_inches(context, inches): @then("the width of each column is {inches} inches") -def then_the_width_of_each_column_is_inches(context, inches): +def then_the_width_of_each_column_is_inches(context: Context, inches: str): table = context.table_ expected_width = Inches(float(inches)) for column in table.columns: diff --git a/features/steps/tabstops.py b/features/steps/tabstops.py index b360d480..ceb9d8f9 100644 --- a/features/steps/tabstops.py +++ b/features/steps/tabstops.py @@ -1,8 +1,4 @@ -# encoding: utf-8 - -""" -Step implementations for paragraph-related features -""" +"""Step implementations for paragraph-related features.""" from behave import given, then, when @@ -13,7 +9,6 @@ from helpers import test_docx - # given =================================================== @@ -101,7 +96,7 @@ def then_I_can_access_a_tab_stop_by_index(context): @then("I can iterate the TabStops object") def then_I_can_iterate_the_TabStops_object(context): - items = [ts for ts in context.tab_stops] + items = list(context.tab_stops) assert len(items) == 3 assert all(isinstance(item, TabStop) for item in items) diff --git a/features/steps/test_files/blk-paras-and-tables.docx b/features/steps/test_files/blk-paras-and-tables.docx new file mode 100644 index 0000000000000000000000000000000000000000..85553c08ab5a13fe35ab2bf6c9b4adb3999e2b54 GIT binary patch literal 15649 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 T%lK_C1qsj&G%lHszy14vez(MZ literal 0 HcmV?d00001 diff --git a/features/steps/test_files/comments-rich-para.docx b/features/steps/test_files/comments-rich-para.docx new file mode 100644 index 0000000000000000000000000000000000000000..245c17224c22d0a6d72958be917d9ef1a899bad6 GIT binary patch literal 20023 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

    @O`g52B)oxZW++>atJ2#U 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 literal 0 HcmV?d00001 diff --git a/features/steps/test_files/par-hyperlinks.docx b/features/steps/test_files/par-hyperlinks.docx new file mode 100644 index 0000000000000000000000000000000000000000..b3a4ea27ae89e9462c09941b9004c65874d49e5b GIT binary patch literal 12385 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 literal 0 HcmV?d00001 diff --git a/features/steps/test_files/tbl-cell-props.docx b/features/steps/test_files/tbl-cell-props.docx new file mode 100644 index 0000000000000000000000000000000000000000..627fb66fc388257cd6a4659ddc433d3f88c6b9d9 GIT binary patch literal 13773 zcmbum19Y8R+cvsl+iq;zZfv8m?Z!>gu(55sv27cTZJW(W_kO>3@Ag0c8Q&Nu$yym} zu5sPZ{mgsL=ejlJr9ePY0RR9bpekufgc5ZC+7$=@*arguP~Jzigl%n{jBT8BmEG)& z9Y4{zT3gk{Ny&8!pa$H(e3M}Rl;qMGz!=yqWM52TpdC4*g?Y-ub#}z%}ity%9U1_?|S|6XKl@|dJJ8|#7A|Q$9#f> z1*Fwoeq^jtBJfBa+U2U|8YF4d@u=d4Ix>%h#X(HCQ{&R@JxOJcii-2x`Z?N-oY+^p zdaWoqPIFcGWk!`ZCT+vMZ~+4t+2%nLa8IiT7Jh;#_mSJtu@*>+46&{2z^AA|Cy3%=Bb0|P~Ws8n!2UGX=7&$Lwo z`N3q{ttfvZ?wMfc78CA_0-py1Txz;+6}Pk}LPd+v=Ik30^CtGV-l9;9QgYgv%k?;C zD>U?ak|3X+hkM0)`AH}9Q0Evz{x?IxpOrelz8mNS7yy8I|F7#{Y~@H#_v^hpW=s-< z5z*(|>syqR?5b61@SuqYQZ{?^6TpzE1!wgoO1jR=BR9BNzFaTz`u>uUdCX$}<6Ri# z@P5yMij*n!LJC-27V5Eb_0tS

    4i)GBIwBc$IDta(=_Wlq_?0%cqmvzaXjR4 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 EUuoxmC;$Ke delta 1675 zcmV;626Xwup8?XH0kDB7f47NbNh4BLufqiZ0O>UV01*HH0C#V4WG`fIV|8t1Zgehq zZEWpZTXUN@6n^io@c1Q9ttBB4c$#()hHhutnM~8&ecVwnw%Gt;K#r6B^(%3)ah%%t zlGu%t7jty^^qq5bjt-Z6{Cporox32*L!Mk-zz^V}6C^$#hROKyf8x)d-h1<+lM9v% zS;Ujz^5P-LFFt>I_i@%Aa(@~JiReg#B=65s|FSy~BJKBjxjzYFmVbytKjS$ci4Q)H zdwets{h&AF*|3KI1jSXFaX-j&xtzn2JC=7VxR|#?iWtAFf0Qm-VVR9PZ8mJJfR)CD25 zg3z3yFfut*9uvbKa&cf&4OogI#Ql_I?5iY!T#pdq=w+)2?uBY4)nB)o{xfULUpAS) z5UYl!lje<^?O*BeXu6!7E)fPgb_w;|^@Nx8Et>|xe~3*Z(dcP0_`nDYe>IPMk60eYxJ^7;I`js{*71xr)Qsog zp7{rl=IxJt!P6Z=SHan83tj5!ZEole zs&6xUw~Sm3nbgu8ZRf~+dF$#}mZ#s*s{(hdN8CWGQ2iVcaBu_ z7!+y)haUVU?u3e-;$iMv)w6figKXObe-v#9-ZH;d^EXvJ>zs5V1rEW0cour`5I&l| z!1a*Z>dn=w&=;Wrz?%9V>+}m8(;jGm*yk01vZ{j)aL;E$Y7lt_-0;->73pgc0u6h^ zu0Cds1PHQh-Dvan{CBO9R^MN~6-m3jGjkBt32611%+@*j2``;Uk~TC-si!|zf6`hZ ze-0!k5%FW62YxWt6O>@*f}6RsBC&pWgisP)h>@6aWAK2mrTcvtTfB z9XAvM6aWAK2mrTcW-iJFJy0H zb!}yCbdz9C6q7Vg8UkrAlTc1R0=qGjkWM`Ut2L9)PCEiHJd+GhMgl`alT=SZ0z68S VF-sPctxpUJP6Ge{Zc6|F007cL68r!F diff --git a/features/steps/text.py b/features/steps/text.py index 57451a1b..9fafc61f 100644 --- a/features/steps/text.py +++ b/features/steps/text.py @@ -1,25 +1,19 @@ -# encoding: utf-8 - -""" -Step implementations for text-related features -""" - -from __future__ import absolute_import, print_function, unicode_literals +"""Step implementations for text-related features.""" import hashlib from behave import given, then, when +from behave.runner import Context from docx import Document from docx.enum.text import WD_BREAK, WD_UNDERLINE -from docx.oxml import parse_xml from docx.oxml.ns import nsdecls, qn +from docx.oxml.parser import parse_xml from docx.text.font import Font from docx.text.run import Run from helpers import test_docx, test_file, test_text - # given =================================================== @@ -54,16 +48,19 @@ def given_a_run_having_mixed_text_content(context): r_xml = """\ abc - + def ghi - jkl - """ % nsdecls( - "w" - ) + + mno + + pqr + + stu + """ % nsdecls("w") r = parse_xml(r_xml) context.run = Run(r, None) @@ -86,6 +83,14 @@ def given_a_run_having_style(context, style): context.run = document.paragraphs[0].runs[run_idx] +@given("a run having {zero_or_more} rendered page breaks") +def given_a_run_having_rendered_page_breaks(context: Context, zero_or_more: str): + paragraph_idx = {"no": 0, "one": 1, "two": 3}[zero_or_more] + document = Document(test_docx("par-rendered-page-breaks")) + paragraph = document.paragraphs[paragraph_idx] + context.run = paragraph.runs[0] + + @given("a run inside a table cell retrieved from {cell_source}") def given_a_run_inside_a_table_cell_from_source(context, cell_source): document = Document() @@ -150,7 +155,7 @@ def when_I_add_text_to_the_run(context): @when("I assign mixed text to the text property") def when_I_assign_mixed_text_to_the_text_property(context): - context.run.text = "abc\tdef\nghi\rjkl" + context.run.text = "abc\ndef\rghijkl\tmno-pqr\tstu" @when("I assign {value_str} to its {bool_prop_name} property") @@ -210,6 +215,13 @@ def then_type_is_page_break(context): assert attrib == {qn("w:type"): "page"} +@then("run.contains_page_break is {value}") +def then_run_contains_page_break_is_value(context: Context, value: str): + actual = context.run.contains_page_break + expected = {"True": True, "False": False}[value] + assert actual == expected, f"expected: {expected}, got: {actual}" + + @then("run.font is the Font object for the run") def then_run_font_is_the_Font_object_for_the_run(context): run, font = context.run, context.run.font @@ -217,6 +229,13 @@ def then_run_font_is_the_Font_object_for_the_run(context): assert font.element is run.element +@then("run.iter_inner_content() generates the run text and rendered page-breaks") +def then_run_iter_inner_content_generates_text_and_page_breaks(context: Context): + actual_value = [type(item).__name__ for item in context.run.iter_inner_content()] + expected_value = ["str", "RenderedPageBreak", "str", "RenderedPageBreak", "str"] + assert actual_value == expected_value, f"expected: {expected_value}, got: {actual_value}" + + @then("run.style is styles['{style_name}']") def then_run_style_is_style(context, style_name): expected_value = context.document.styles[style_name] @@ -224,6 +243,13 @@ def then_run_style_is_style(context, style_name): assert run.style == expected_value, "got %s" % run.style +@then("run.text contains the text content of the run") +def then_run_text_contains_the_text_content_of_the_run(context): + actual = context.run.text + expected = "abc\ndef\nghijkl\tmno-pqr\tstu" + assert actual == expected, f"expected:\n'{expected}'\n\ngot:\n'{actual}'" + + @then("the last item in the run is a break") def then_last_item_in_run_is_a_break(context): run = context.run @@ -237,15 +263,15 @@ def then_the_picture_appears_at_the_end_of_the_run(context): run = context.run r = run._r blip_rId = r.xpath( - "./w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill/" - "a:blip/@r:embed" + "./w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill/a:blip/@r:embed" )[0] image_part = run.part.related_parts[blip_rId] image_sha1 = hashlib.sha1(image_part.blob).hexdigest() expected_sha1 = "79769f1e202add2e963158b532e36c2c0f76a70c" - assert ( - image_sha1 == expected_sha1 - ), "image SHA1 doesn't match, expected %s, got %s" % (expected_sha1, image_sha1) + assert image_sha1 == expected_sha1, "image SHA1 doesn't match, expected %s, got %s" % ( + expected_sha1, + image_sha1, + ) @then("the run appears in {boolean_prop_name} unconditionally") @@ -298,8 +324,3 @@ def then_the_tab_appears_at_the_end_of_the_run(context): r = context.run._r tab = r.find(qn("w:tab")) assert tab is not None - - -@then("the text of the run represents the textual run content") -def then_the_text_of_the_run_represents_the_textual_run_content(context): - assert context.run.text == "abc\tdef\nghi\njkl", "got '%s'" % context.run.text diff --git a/features/cel-add-table.feature b/features/tbl-cell-add-table.feature similarity index 100% rename from features/cel-add-table.feature rename to features/tbl-cell-add-table.feature diff --git a/features/tbl-cell-props.feature b/features/tbl-cell-props.feature index 609d2f44..456ed39a 100644 --- a/features/tbl-cell-props.feature +++ b/features/tbl-cell-props.feature @@ -4,6 +4,17 @@ Feature: Get and set table cell properties I need a way to get and set the properties of a table cell + Scenario Outline: Get _Cell.grid_span + Given a _Cell object spanning layout-grid cells + Then cell.grid_span is + + Examples: Cell.grid_span value cases + | count | + | 1 | + | 2 | + | 4 | + + Scenario Outline: Get _Cell.vertical_alignment Given a _Cell object with vertical alignment as cell Then cell.vertical_alignment is diff --git a/features/cel-text.feature b/features/tbl-cell-text.feature similarity index 100% rename from features/cel-text.feature rename to features/tbl-cell-text.feature diff --git a/features/tbl-row-props.feature b/features/tbl-row-props.feature index 377f2853..1b006f20 100644 --- a/features/tbl-row-props.feature +++ b/features/tbl-row-props.feature @@ -4,6 +4,28 @@ Feature: Get and set table row properties I need a way to get and set the properties of a table row + Scenario Outline: Get Row.grid_cols_after + Given a table row ending with empty grid columns + Then row.grid_cols_after is + + Examples: Row.grid_cols_after value cases + | count | + | 0 | + | 1 | + | 2 | + + + Scenario Outline: Get Row.grid_cols_before + Given a table row starting with empty grid columns + Then row.grid_cols_before is + + Examples: Row.grid_cols_before value cases + | count | + | 0 | + | 1 | + | 3 | + + Scenario Outline: Get Row.height_rule Given a table row having height rule Then row.height_rule is diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..e720bdd0 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,114 @@ +[build-system] +requires = ["setuptools>=61.0.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "python-docx-oss" +authors = [{ name = "Ethan St. Lee" }] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Environment :: Console", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Topic :: Office/Business :: Office Suites", + "Topic :: Software Development :: Libraries", +] +dependencies = ["lxml>=3.1.0", "typing_extensions>=4.9.0"] +description = "Create, read, and update Microsoft Word .docx files." +dynamic = ["version"] +keywords = ["docx", "office", "openxml", "word"] +license = { text = "MIT" } +readme = "README.md" +requires-python = ">=3.12" + +[dependency-groups] +dev = [ + "Jinja2>=3.1.2", + "MarkupSafe>=2.1.2", + "Sphinx>=7.0.0", + "alabaster>=0.7.12", + "behave>=1.2.6", + "pyparsing>=3.2.3", + "pyright>=1.1.401", + "pytest>=8.4.0", + "ruff>=0.11.13", + "tox>=4.26.0", + "twine>=6.1.0", + "types-lxml-multi-subclass>=2025.3.30", +] + +[tool.pyright] +include = ["src/docx", "tests"] +pythonPlatform = "All" +pythonVersion = "3.12" +reportImportCycles = false +reportUnnecessaryCast = true +reportUnnecessaryTypeIgnoreComment = true +stubPath = "./typings" +typeCheckingMode = "strict" +verboseOutput = true +venvPath = "." +venv = ".venv" + +[tool.pytest.ini_options] +filterwarnings = [ + # -- exit on any warning not explicitly ignored here -- + "error", + + # -- pytest-xdist plugin may warn about `looponfailroots` deprecation -- + "ignore::DeprecationWarning:xdist", + + # -- pytest complains when pytest-xdist is not installed -- + "ignore:Unknown config option. looponfailroots:pytest.PytestConfigWarning", +] +looponfailroots = ["src", "tests"] +norecursedirs = [ + "doc", + "docx", + "*.egg-info", + "features", + ".git", + "ref", + "_scratch", + ".tox", +] +python_files = ["test_*.py"] +python_classes = ["Test", "Describe"] +python_functions = ["it_", "its_", "they_", "and_", "but_"] + +[tool.ruff] +exclude = [] +line-length = 100 +target-version = "py312" + +[tool.ruff.lint] +ignore = [ + "COM812", # -- over-aggressively insists on trailing commas where not desired -- + "PT001", # -- wants @pytest.fixture() instead of @pytest.fixture -- +] +select = [ + "C4", # -- flake8-comprehensions -- + "COM", # -- flake8-commas -- + "E", # -- pycodestyle errors -- + "F", # -- pyflakes -- + "I", # -- isort (imports) -- + "PLR0402", # -- Name compared with itself like `foo == foo` -- + "PT", # -- flake8-pytest-style -- + "SIM", # -- flake8-simplify -- + "UP015", # -- redundant `open()` mode parameter (like "r" is default) -- + "UP018", # -- Unnecessary {literal_type} call like `str("abc")`. (rewrite as a literal) -- + "UP032", # -- Use f-string instead of `.format()` call -- + "UP034", # -- Avoid extraneous parentheses -- +] + +[tool.ruff.lint.isort] +known-first-party = ["docx"] +known-local-folder = ["helpers"] + +[tool.setuptools.dynamic] +version = { attr = "docx.__version__" } diff --git a/ref/xsd/vml-wordprocessingDrawing.xsd b/ref/xsd/vml-wordprocessingDrawing.xsd index f1041e34..f36e1acd 100644 --- a/ref/xsd/vml-wordprocessingDrawing.xsd +++ b/ref/xsd/vml-wordprocessingDrawing.xsd @@ -1,8 +1,11 @@ - + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + attributeFormDefault="unqualified" + elementFormDefault="qualified" + targetNamespace="urn:schemas-microsoft-com:office:word" +> diff --git a/requirements-dev.txt b/requirements-dev.txt index da1066f0..14d8740e 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,7 +1,7 @@ -setuptools +-r requirements-test.txt +build +ruff +setuptools>=61.0.0 +tox twine -behave>=1.2.6 -flake8>=4.0.1 -mock>=4.0.3 -pytest>=6.2.5 -pytest-mock>=3.7.0 +types-lxml diff --git a/requirements-docs.txt b/requirements-docs.txt new file mode 100644 index 00000000..f3c4df64 --- /dev/null +++ b/requirements-docs.txt @@ -0,0 +1,6 @@ +Sphinx>=7.0.0 +sphinx-book-theme +Jinja2>=3.1.2 +MarkupSafe>=2.1.2 +alabaster>=0.7.12 +-e . diff --git a/requirements-test.txt b/requirements-test.txt new file mode 100644 index 00000000..97282cbb --- /dev/null +++ b/requirements-test.txt @@ -0,0 +1,8 @@ +-r requirements.txt +behave>=1.2.3 +pyparsing>=2.0.1 +pytest>=2.5 +pytest-coverage +pytest-xdist +pytest-mock +ruff diff --git a/requirements.txt b/requirements.txt index 9b000afc..8a6f3f10 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ lxml>=4.6.5 -pyparsing>=2.4.7 +typing-extensions diff --git a/setup.py b/setup.py deleted file mode 100644 index dac81a40..00000000 --- a/setup.py +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env python - -import os -import pathlib -import re - -from setuptools import find_packages, setup - - -def text_of(relpath): - """ - Return string containing the contents of the file at *relpath* relative to - this file. - """ - thisdir = os.path.dirname(__file__) - file_path = os.path.join(thisdir, os.path.normpath(relpath)) - return pathlib.Path(file_path).read_text() - - -# Read the version from docx.__version__ without importing the package -# (and thus attempting to import packages it depends on that may not be -# installed yet) -version = re.search(r'__version__ = "([^"]+)"', text_of("docx/__init__.py"))[1] - - -NAME = "python-docx-oss" -VERSION = version -DESCRIPTION = "CRUD Microsoft Word .docx files." -KEYWORDS = "docx office openxml word python-docx-oss" -AUTHOR = "Ethan St. Lee" -AUTHOR_EMAIL = "ethan@ginolegaltech.cn" -URL = "https://github.com/lsaint/python-docx-oss" -LICENSE = text_of("LICENSE") -PACKAGES = find_packages(exclude=["tests", "tests.*"]) -PACKAGE_DATA = {"docx": ["templates/*.xml", "templates/*.docx"]} - -INSTALL_REQUIRES = ["lxml>=4.6.5"] -TEST_SUITE = "tests" -TESTS_REQUIRE = ["behave", "mock", "pyparsing", "pytest"] - -CLASSIFIERS = [ - "Development Status :: 4 - Beta", - "Environment :: Console", - "Intended Audience :: Developers", - "License :: OSI Approved :: MIT License", - "Operating System :: OS Independent", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Topic :: Office/Business :: Office Suites", - "Topic :: Software Development :: Libraries", -] - -LONG_DESCRIPTION = text_of("README.md") + "\n\n" + text_of("HISTORY.md") - -ZIP_SAFE = False - -params = { - "name": NAME, - "version": VERSION, - "description": DESCRIPTION, - "keywords": KEYWORDS, - "long_description": LONG_DESCRIPTION, - "long_description_content_type": "text/markdown", - "author": AUTHOR, - "author_email": AUTHOR_EMAIL, - "url": URL, - "license": LICENSE, - "packages": PACKAGES, - "package_data": PACKAGE_DATA, - "install_requires": INSTALL_REQUIRES, - "tests_require": TESTS_REQUIRE, - "test_suite": TEST_SUITE, - "classifiers": CLASSIFIERS, - "zip_safe": ZIP_SAFE, -} - -setup(**params) diff --git a/docx/__init__.py b/src/docx/__init__.py similarity index 66% rename from docx/__init__.py rename to src/docx/__init__.py index 4a173f6a..7fbe720c 100644 --- a/docx/__init__.py +++ b/src/docx/__init__.py @@ -1,27 +1,45 @@ +"""Initialize `docx` package. + +Export the `Document` constructor function and establish the mapping of part-type to +the part-classe that implements that type. +""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Type + from docx.api import Document + +if TYPE_CHECKING: + from docx.opc.part import Part + +__version__ = "0.1.0" + + +__all__ = ["Document"] + + +# -- register custom Part classes with opc package reader -- + from docx.opc.constants import CONTENT_TYPE as CT from docx.opc.constants import RELATIONSHIP_TYPE as RT from docx.opc.part import PartFactory from docx.opc.parts.coreprops import CorePropertiesPart from docx.opc.parts.customprops import CustomPropertiesPart +from docx.parts.comments import CommentsPart from docx.parts.customxml import CustomXmlPart from docx.parts.document import DocumentPart from docx.parts.hdrftr import FooterPart, HeaderPart from docx.parts.image import ImagePart from docx.parts.numbering import NumberingPart from docx.parts.settings import SettingsPart -from docx.parts.styles import StylesPart # noqa - -__version__ = "0.0.12" - - -# register custom Part classes with opc package reader +from docx.parts.styles import StylesPart -def part_class_selector(content_type, reltype): +def part_class_selector(content_type: str, reltype: str) -> Type[Part] | None: if reltype == RT.IMAGE: return ImagePart - elif reltype == RT.CUSTOM_XML: + if reltype == RT.CUSTOM_XML: return CustomXmlPart return None @@ -29,6 +47,7 @@ def part_class_selector(content_type, reltype): PartFactory.part_class_selector = part_class_selector PartFactory.part_type_for[CT.OPC_CORE_PROPERTIES] = CorePropertiesPart PartFactory.part_type_for[CT.OPC_CUSTOM_PROPERTIES] = CustomPropertiesPart +PartFactory.part_type_for[CT.WML_COMMENTS] = CommentsPart PartFactory.part_type_for[CT.WML_DOCUMENT_MAIN] = DocumentPart PartFactory.part_type_for[CT.WML_FOOTER] = FooterPart PartFactory.part_type_for[CT.WML_HEADER] = HeaderPart @@ -39,6 +58,8 @@ def part_class_selector(content_type, reltype): del ( CT, CorePropertiesPart, + CustomPropertiesPart, + CommentsPart, DocumentPart, FooterPart, HeaderPart, diff --git a/src/docx/api.py b/src/docx/api.py new file mode 100644 index 00000000..aea87645 --- /dev/null +++ b/src/docx/api.py @@ -0,0 +1,37 @@ +"""Directly exposed API functions and classes, :func:`Document` for now. + +Provides a syntactically more convenient API for interacting with the OpcPackage graph. +""" + +from __future__ import annotations + +import os +from typing import IO, TYPE_CHECKING, cast + +from docx.opc.constants import CONTENT_TYPE as CT +from docx.package import Package + +if TYPE_CHECKING: + from docx.document import Document as DocumentObject + from docx.parts.document import DocumentPart + + +def Document(docx: str | IO[bytes] | None = None) -> DocumentObject: + """Return a |Document| object loaded from `docx`, where `docx` can be either a path + to a ``.docx`` file (a string) or a file-like object. + + If `docx` is missing or ``None``, the built-in default document "template" is + loaded. + """ + docx = _default_docx_path() if docx is None else docx + document_part = cast("DocumentPart", Package.open(docx).main_document_part) + if document_part.content_type != CT.WML_DOCUMENT_MAIN: + tmpl = "file '%s' is not a Word file, content type is '%s'" + raise ValueError(tmpl % (docx, document_part.content_type)) + return document_part.document + + +def _default_docx_path(): + """Return the path to the built-in default .docx package.""" + _thisdir = os.path.split(__file__)[0] + return os.path.join(_thisdir, "templates", "default.docx") diff --git a/src/docx/blkcntnr.py b/src/docx/blkcntnr.py new file mode 100644 index 00000000..82c7ef72 --- /dev/null +++ b/src/docx/blkcntnr.py @@ -0,0 +1,101 @@ +# pyright: reportImportCycles=false + +"""Block item container, used by body, cell, header, etc. + +Block level items are things like paragraph and table, although there are a few other +specialized ones like structured document tags. +""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Iterator + +from typing_extensions import TypeAlias + +from docx.oxml.table import CT_Tbl +from docx.oxml.text.paragraph import CT_P +from docx.shared import StoryChild +from docx.text.paragraph import Paragraph + +if TYPE_CHECKING: + import docx.types as t + from docx.oxml.comments import CT_Comment + from docx.oxml.document import CT_Body + from docx.oxml.section import CT_HdrFtr + from docx.oxml.table import CT_Tc + from docx.shared import Length + from docx.styles.style import ParagraphStyle + from docx.table import Table + +BlockItemElement: TypeAlias = "CT_Body | CT_Comment | CT_HdrFtr | CT_Tc" + + +class BlockItemContainer(StoryChild): + """Base class for proxy objects that can contain block items. + + These containers include _Body, _Cell, header, footer, footnote, endnote, comment, + and text box objects. Provides the shared functionality to add a block item like a + paragraph or table. + """ + + def __init__(self, element: BlockItemElement, parent: t.ProvidesStoryPart): + super(BlockItemContainer, self).__init__(parent) + self._element = element + + def add_paragraph(self, text: str = "", style: str | ParagraphStyle | None = None) -> Paragraph: + """Return paragraph newly added to the end of the content in this container. + + The paragraph has `text` in a single run if present, and is given paragraph + style `style`. + + If `style` is |None|, no paragraph style is applied, which has the same effect + as applying the 'Normal' style. + """ + paragraph = self._add_paragraph() + if text: + paragraph.add_run(text) + if style is not None: + paragraph.style = style + return paragraph + + def add_table(self, rows: int, cols: int, width: Length) -> Table: + """Return table of `width` having `rows` rows and `cols` columns. + + The table is appended appended at the end of the content in this container. + + `width` is evenly distributed between the table columns. + """ + from docx.table import Table + + tbl = CT_Tbl.new_tbl(rows, cols, width) + self._element._insert_tbl(tbl) # pyright: ignore[reportPrivateUsage] + return Table(tbl, self) + + def iter_inner_content(self) -> Iterator[Paragraph | Table]: + """Generate each `Paragraph` or `Table` in this container in document order.""" + from docx.table import Table + + for element in self._element.inner_content_elements: + yield (Paragraph(element, self) if isinstance(element, CT_P) else Table(element, self)) + + @property + def paragraphs(self): + """A list containing the paragraphs in this container, in document order. + + Read-only. + """ + return [Paragraph(p, self) for p in self._element.p_lst] + + @property + def tables(self): + """A list containing the tables in this container, in document order. + + Read-only. + """ + from docx.table import Table + + return [Table(tbl, self) for tbl in self._element.tbl_lst] + + def _add_paragraph(self): + """Return paragraph newly added to the end of the content in this container.""" + return Paragraph(self._element.add_p(), self) diff --git a/src/docx/comments.py b/src/docx/comments.py new file mode 100644 index 00000000..8ea19522 --- /dev/null +++ b/src/docx/comments.py @@ -0,0 +1,163 @@ +"""Collection providing access to comments added to this document.""" + +from __future__ import annotations + +import datetime as dt +from typing import TYPE_CHECKING, Iterator + +from docx.blkcntnr import BlockItemContainer + +if TYPE_CHECKING: + from docx.oxml.comments import CT_Comment, CT_Comments + from docx.parts.comments import CommentsPart + from docx.styles.style import ParagraphStyle + from docx.text.paragraph import Paragraph + + +class Comments: + """Collection containing the comments added to this document.""" + + def __init__(self, comments_elm: CT_Comments, comments_part: CommentsPart): + self._comments_elm = comments_elm + self._comments_part = comments_part + + def __iter__(self) -> Iterator[Comment]: + """Iterator over the comments in this collection.""" + return ( + Comment(comment_elm, self._comments_part) + for comment_elm in self._comments_elm.comment_lst + ) + + def __len__(self) -> int: + """The number of comments in this collection.""" + return len(self._comments_elm.comment_lst) + + def add_comment(self, text: str = "", author: str = "", initials: str | None = "") -> Comment: + """Add a new comment to the document and return it. + + The comment is added to the end of the comments collection and is assigned a unique + comment-id. + + If `text` is provided, it is added to the comment. This option provides for the common + case where a comment contains a modest passage of plain text. Multiple paragraphs can be + added using the `text` argument by separating their text with newlines (`"\\\\n"`). + Between newlines, text is interpreted as it is in `Document.add_paragraph(text=...)`. + + The default is to place a single empty paragraph in the comment, which is the same + behavior as the Word UI when you add a comment. New runs can be added to the first + paragraph in the empty comment with `comments.paragraphs[0].add_run()` to adding more + complex text with emphasis or images. Additional paragraphs can be added using + `.add_paragraph()`. + + `author` is a required attribute, set to the empty string by default. + + `initials` is an optional attribute, set to the empty string by default. Passing |None| + for the `initials` parameter causes that attribute to be omitted from the XML. + """ + comment_elm = self._comments_elm.add_comment() + comment_elm.author = author + comment_elm.initials = initials + comment_elm.date = dt.datetime.now(dt.timezone.utc) + comment = Comment(comment_elm, self._comments_part) + + if text == "": + return comment + + para_text_iter = iter(text.split("\n")) + + first_para_text = next(para_text_iter) + first_para = comment.paragraphs[0] + first_para.add_run(first_para_text) + + for s in para_text_iter: + comment.add_paragraph(text=s) + + return comment + + def get(self, comment_id: int) -> Comment | None: + """Return the comment identified by `comment_id`, or |None| if not found.""" + comment_elm = self._comments_elm.get_comment_by_id(comment_id) + return Comment(comment_elm, self._comments_part) if comment_elm is not None else None + + +class Comment(BlockItemContainer): + """Proxy for a single comment in the document. + + Provides methods to access comment metadata such as author, initials, and date. + + A comment is also a block-item container, similar to a table cell, so it can contain both + paragraphs and tables and its paragraphs can contain rich text, hyperlinks and images, + although the common case is that a comment contains a single paragraph of plain text like a + sentence or phrase. + + Note that certain content like tables may not be displayed in the Word comment sidebar due to + space limitations. Such "over-sized" content can still be viewed in the review pane. + """ + + def __init__(self, comment_elm: CT_Comment, comments_part: CommentsPart): + super().__init__(comment_elm, comments_part) + self._comment_elm = comment_elm + + def add_paragraph(self, text: str = "", style: str | ParagraphStyle | None = None) -> Paragraph: + """Return paragraph newly added to the end of the content in this container. + + The paragraph has `text` in a single run if present, and is given paragraph style `style`. + When `style` is |None| or ommitted, the "CommentText" paragraph style is applied, which is + the default style for comments. + """ + paragraph = super().add_paragraph(text, style) + + # -- have to assign style directly to element because `paragraph.style` raises when + # -- a style is not present in the styles part + if style is None: + paragraph._p.style = "CommentText" # pyright: ignore[reportPrivateUsage] + + return paragraph + + @property + def author(self) -> str: + """Read/write. The recorded author of this comment. + + This field is required but can be set to the empty string. + """ + return self._comment_elm.author + + @author.setter + def author(self, value: str): + self._comment_elm.author = value + + @property + def comment_id(self) -> int: + """The unique identifier of this comment.""" + return self._comment_elm.id + + @property + def initials(self) -> str | None: + """Read/write. The recorded initials of the comment author. + + This attribute is optional in the XML, returns |None| if not set. Assigning |None| removes + any existing initials from the XML. + """ + return self._comment_elm.initials + + @initials.setter + def initials(self, value: str | None): + self._comment_elm.initials = value + + @property + def text(self) -> str: + """The text content of this comment as a string. + + Only content in paragraphs is included and of course all emphasis and styling is stripped. + + Paragraph boundaries are indicated with a newline (`"\\\\n"`) + """ + return "\n".join(p.text for p in self.paragraphs) + + @property + def timestamp(self) -> dt.datetime | None: + """The date and time this comment was authored. + + This attribute is optional in the XML, returns |None| if not set. + """ + return self._comment_elm.date diff --git a/docx/dml/__init__.py b/src/docx/dml/__init__.py similarity index 100% rename from docx/dml/__init__.py rename to src/docx/dml/__init__.py diff --git a/src/docx/dml/color.py b/src/docx/dml/color.py new file mode 100644 index 00000000..a8322d21 --- /dev/null +++ b/src/docx/dml/color.py @@ -0,0 +1,112 @@ +"""DrawingML objects related to color, ColorFormat being the most prominent.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, cast + +from typing_extensions import TypeAlias + +from docx.enum.dml import MSO_COLOR_TYPE +from docx.oxml.simpletypes import ST_HexColorAuto +from docx.shared import ElementProxy, RGBColor + +if TYPE_CHECKING: + from docx.enum.dml import MSO_THEME_COLOR + from docx.oxml.text.font import CT_Color + from docx.oxml.text.run import CT_R + +# -- other element types can be a parent of an `w:rPr` element, but for now only `w:r` is -- +RPrParent: TypeAlias = "CT_R" + + +class ColorFormat(ElementProxy): + """Provides access to color settings like RGB color, theme color, and luminance adjustments.""" + + def __init__(self, rPr_parent: RPrParent): + super(ColorFormat, self).__init__(rPr_parent) + self._element = rPr_parent + + @property + def rgb(self) -> RGBColor | None: + """An |RGBColor| value or |None| if no RGB color is specified. + + When :attr:`type` is `MSO_COLOR_TYPE.RGB`, the value of this property will always be an + |RGBColor| value. It may also be an |RGBColor| value if :attr:`type` is + `MSO_COLOR_TYPE.THEME`, as Word writes the current value of a theme color when one is + assigned. In that case, the RGB value should be interpreted as no more than a good guess + however, as the theme color takes precedence at rendering time. Its value is |None| + whenever :attr:`type` is either |None| or `MSO_COLOR_TYPE.AUTO`. + + Assigning an |RGBColor| value causes :attr:`type` to become `MSO_COLOR_TYPE.RGB` and any + theme color is removed. Assigning |None| causes any color to be removed such that the + effective color is inherited from the style hierarchy. + """ + color = self._color + if color is None: + return None + if color.val == ST_HexColorAuto.AUTO: + return None + return cast(RGBColor, color.val) + + @rgb.setter + def rgb(self, value: RGBColor | None): + if value is None and self._color is None: + return + rPr = self._element.get_or_add_rPr() + rPr._remove_color() # pyright: ignore[reportPrivateUsage] + if value is not None: + rPr.get_or_add_color().val = value + + @property + def theme_color(self) -> MSO_THEME_COLOR | None: + """Member of :ref:`MsoThemeColorIndex` or |None| if no theme color is specified. + + When :attr:`type` is `MSO_COLOR_TYPE.THEME`, the value of this property will always be a + member of :ref:`MsoThemeColorIndex`. When :attr:`type` has any other value, the value of + this property is |None|. + + Assigning a member of :ref:`MsoThemeColorIndex` causes :attr:`type` to become + `MSO_COLOR_TYPE.THEME`. Any existing RGB value is retained but ignored by Word. Assigning + |None| causes any color specification to be removed such that the effective color is + inherited from the style hierarchy. + """ + color = self._color + if color is None: + return None + return color.themeColor + + @theme_color.setter + def theme_color(self, value: MSO_THEME_COLOR | None): + if value is None: + if self._color is not None and self._element.rPr is not None: + self._element.rPr._remove_color() # pyright: ignore[reportPrivateUsage] + return + self._element.get_or_add_rPr().get_or_add_color().themeColor = value + + @property + def type(self) -> MSO_COLOR_TYPE | None: + """Read-only. + + A member of :ref:`MsoColorType`, one of RGB, THEME, or AUTO, corresponding to the way this + color is defined. Its value is |None| if no color is applied at this level, which causes + the effective color to be inherited from the style hierarchy. + """ + color = self._color + if color is None: + return None + if color.themeColor is not None: + return MSO_COLOR_TYPE.THEME + if color.val == ST_HexColorAuto.AUTO: + return MSO_COLOR_TYPE.AUTO + return MSO_COLOR_TYPE.RGB + + @property + def _color(self) -> CT_Color | None: + """Return `w:rPr/w:color` or |None| if not present. + + Helper to factor out repetitive element access. + """ + rPr = self._element.rPr + if rPr is None: + return None + return rPr.color diff --git a/src/docx/document.py b/src/docx/document.py new file mode 100644 index 00000000..8f52484f --- /dev/null +++ b/src/docx/document.py @@ -0,0 +1,285 @@ +# pyright: reportImportCycles=false +# pyright: reportPrivateUsage=false + +"""|Document| and closely related objects.""" + +from __future__ import annotations + +from typing import IO, TYPE_CHECKING, Iterator, List, Sequence + +from docx.blkcntnr import BlockItemContainer +from docx.enum.section import WD_SECTION +from docx.enum.text import WD_BREAK +from docx.section import Section, Sections +from docx.shared import ElementProxy, Emu, Inches, Length +from docx.text.run import Run + +if TYPE_CHECKING: + import docx.types as t + from docx.comments import Comment, Comments + from docx.opc.customprops import CustomProperties + from docx.oxml.document import CT_Body, CT_Document + from docx.parts.document import DocumentPart + from docx.settings import Settings + from docx.styles.style import ParagraphStyle, _TableStyle + from docx.table import Table + from docx.text.paragraph import Paragraph + + +class Document(ElementProxy): + """WordprocessingML (WML) document. + + Not intended to be constructed directly. Use :func:`docx.Document` to open or create + a document. + """ + + def __init__(self, element: CT_Document, part: DocumentPart): + super(Document, self).__init__(element) + self._element = element + self._part = part + self.__body = None + + def add_comment( + self, + runs: Run | Sequence[Run], + text: str | None = "", + author: str = "", + initials: str | None = "", + ) -> Comment: + """Add a comment to the document, anchored to the specified runs. + + `runs` can be a single `Run` object or a non-empty sequence of `Run` objects. Only the + first and last run of a sequence are used, it's just more convenient to pass a whole + sequence when that's what you have handy, like `paragraph.runs` for example. When `runs` + contains a single `Run` object, that run serves as both the first and last run. + + A comment can be anchored only on an even run boundary, meaning the text the comment + "references" must be a non-zero integer number of consecutive runs. The runs need not be + _contiguous_ per se, like the first can be in one paragraph and the last in the next + paragraph, but all runs between the first and the last will be included in the reference. + + The comment reference range is delimited by placing a `w:commentRangeStart` element before + the first run and a `w:commentRangeEnd` element after the last run. This is why only the + first and last run are required and why a single run can serve as both first and last. + Word works out which text to highlight in the UI based on these range markers. + + `text` allows the contents of a simple comment to be provided in the call, providing for + the common case where a comment is a single phrase or sentence without special formatting + such as bold or italics. More complex comments can be added using the returned `Comment` + object in much the same way as a `Document` or (table) `Cell` object, using methods like + `.add_paragraph()`, .add_run()`, etc. + + The `author` and `initials` parameters allow that metadata to be set for the comment. + `author` is a required attribute on a comment and is the empty string by default. + `initials` is optional on a comment and may be omitted by passing |None|, but Word adds an + `initials` attribute by default and we follow that convention by using the empty string + when no `initials` argument is provided. + """ + # -- normalize `runs` to a sequence of runs -- + runs = [runs] if isinstance(runs, Run) else runs + first_run = runs[0] + last_run = runs[-1] + + # -- Note that comments can only appear in the document part -- + comment = self.comments.add_comment(text=text, author=author, initials=initials) + + # -- let the first run orchestrate placement of the comment range start and end -- + first_run.mark_comment_range(last_run, comment.comment_id) + + return comment + + def add_heading(self, text: str = "", level: int = 1): + """Return a heading paragraph newly added to the end of the document. + + The heading paragraph will contain `text` and have its paragraph style + determined by `level`. If `level` is 0, the style is set to `Title`. If `level` + is 1 (or omitted), `Heading 1` is used. Otherwise the style is set to `Heading + {level}`. Raises |ValueError| if `level` is outside the range 0-9. + """ + if not 0 <= level <= 9: + raise ValueError("level must be in range 0-9, got %d" % level) + style = "Title" if level == 0 else "Heading %d" % level + return self.add_paragraph(text, style) + + def add_page_break(self): + """Return newly |Paragraph| object containing only a page break.""" + paragraph = self.add_paragraph() + paragraph.add_run().add_break(WD_BREAK.PAGE) + return paragraph + + def add_paragraph(self, text: str = "", style: str | ParagraphStyle | None = None) -> Paragraph: + r"""Return paragraph newly added to the end of the document. + + The paragraph is populated with `text` and having paragraph style `style`. + + `text` can contain tab (``\t``) characters, which are converted to the + appropriate XML form for a tab. `text` can also include newline (``\n``) or + carriage return (``\r``) characters, each of which is converted to a line + break. + """ + return self._body.add_paragraph(text, style) + + def add_picture( + self, + image_path_or_stream: str | IO[bytes], + width: int | Length | None = None, + height: int | Length | None = None, + ): + """Return new picture shape added in its own paragraph at end of the document. + + The picture contains the image at `image_path_or_stream`, scaled based on + `width` and `height`. If neither width nor height is specified, the picture + appears at its native size. If only one is specified, it is used to compute a + scaling factor that is then applied to the unspecified dimension, preserving the + aspect ratio of the image. The native size of the picture is calculated using + the dots-per-inch (dpi) value specified in the image file, defaulting to 72 dpi + if no value is specified, as is often the case. + """ + run = self.add_paragraph().add_run() + return run.add_picture(image_path_or_stream, width, height) + + def add_float_picture( + self, + image_path_or_stream: str | IO[bytes], + width: int | Length | None = None, + height: int | Length | None = None, + pos_x: int | Length = 0, + pos_y: int | Length = 0, + ): + """Add float picture at fixed position `pos_x` and `pos_y` to the top-left + point of page. + """ + run = self.add_paragraph().add_run() + return run.add_float_picture(image_path_or_stream, width, height, pos_x, pos_y) + + def add_section(self, start_type: WD_SECTION = WD_SECTION.NEW_PAGE): + """Return a |Section| object newly added at the end of the document. + + The optional `start_type` argument must be a member of the :ref:`WdSectionStart` + enumeration, and defaults to ``WD_SECTION.NEW_PAGE`` if not provided. + """ + new_sectPr = self._element.body.add_section_break() + new_sectPr.start_type = start_type + return Section(new_sectPr, self._part) + + def add_table(self, rows: int, cols: int, style: str | _TableStyle | None = None): + """Add a table having row and column counts of `rows` and `cols` respectively. + + `style` may be a table style object or a table style name. If `style` is |None|, + the table inherits the default table style of the document. + """ + table = self._body.add_table(rows, cols, self._block_width) + table.style = style + return table + + @property + def comments(self) -> Comments: + """A |Comments| object providing access to comments added to the document.""" + return self._part.comments + + @property + def core_properties(self): + """A |CoreProperties| object providing Dublin Core properties of document.""" + return self._part.core_properties + + @property + def custom_properties(self) -> CustomProperties: + """A |CustomProperties| object providing custom properties of document.""" + return self._part.custom_properties + + @property + def inline_shapes(self): + """The |InlineShapes| collection for this document. + + An inline shape is a graphical object, such as a picture, contained in a run of + text and behaving like a character glyph, being flowed like other text in a + paragraph. + """ + return self._part.inline_shapes + + def iter_inner_content(self) -> Iterator[Paragraph | Table]: + """Generate each `Paragraph` or `Table` in this document in document order.""" + return self._body.iter_inner_content() + + @property + def paragraphs(self) -> List[Paragraph]: + """The |Paragraph| instances in the document, in document order. + + Note that paragraphs within revision marks such as ```` or ```` do + not appear in this list. + """ + return self._body.paragraphs + + @property + def part(self) -> DocumentPart: + """The |DocumentPart| object of this document.""" + return self._part + + def save(self, path_or_stream: str | IO[bytes]): + """Save this document to `path_or_stream`. + + `path_or_stream` can be either a path to a filesystem location (a string) or a + file-like object. + """ + self._part.save(path_or_stream) + + @property + def sections(self) -> Sections: + """|Sections| object providing access to each section in this document.""" + return Sections(self._element, self._part) + + @property + def settings(self) -> Settings: + """A |Settings| object providing access to the document-level settings.""" + return self._part.settings + + @property + def styles(self): + """A |Styles| object providing access to the styles in this document.""" + return self._part.styles + + @property + def tables(self) -> List[Table]: + """All |Table| instances in the document, in document order. + + Note that only tables appearing at the top level of the document appear in this + list; a table nested inside a table cell does not appear. A table within + revision marks such as ```` or ```` will also not appear in the + list. + """ + return self._body.tables + + @property + def _block_width(self) -> Length: + """A |Length| object specifying the space between margins in last section.""" + section = self.sections[-1] + page_width = section.page_width or Inches(8.5) + left_margin = section.left_margin or Inches(1) + right_margin = section.right_margin or Inches(1) + return Emu(page_width - left_margin - right_margin) + + @property + def _body(self) -> _Body: + """The |_Body| instance containing the content for this document.""" + if self.__body is None: + self.__body = _Body(self._element.body, self) + return self.__body + + +class _Body(BlockItemContainer): + """Proxy for `` element in this document. + + It's primary role is a container for document content. + """ + + def __init__(self, body_elm: CT_Body, parent: t.ProvidesStoryPart): + super(_Body, self).__init__(body_elm, parent) + self._body = body_elm + + def clear_content(self) -> _Body: + """Return this |_Body| instance after clearing it of all content. + + Section properties for the main document story, if present, are preserved. + """ + self._body.clear_content() + return self diff --git a/src/docx/drawing/__init__.py b/src/docx/drawing/__init__.py new file mode 100644 index 00000000..00d1f51b --- /dev/null +++ b/src/docx/drawing/__init__.py @@ -0,0 +1,59 @@ +"""DrawingML-related objects are in this subpackage.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +from docx.oxml.drawing import CT_Drawing +from docx.shared import Parented + +if TYPE_CHECKING: + import docx.types as t + from docx.image.image import Image + + +class Drawing(Parented): + """Container for a DrawingML object.""" + + def __init__(self, drawing: CT_Drawing, parent: t.ProvidesStoryPart): + super().__init__(parent) + self._parent = parent + self._drawing = self._element = drawing + + @property + def has_picture(self) -> bool: + """True when `drawing` contains an embedded picture. + + A drawing can contain a picture, but it can also contain a chart, SmartArt, or a + drawing canvas. Methods related to a picture, like `.image`, will raise when the drawing + does not contain a picture. Use this value to determine whether image methods will succeed. + + This value is `False` when a linked picture is present. This should be relatively rare and + the image would only be retrievable from the filesystem. + + Note this does not distinguish between inline and floating images. The presence of either + one will cause this value to be `True`. + """ + xpath_expr = ( + # -- an inline picture -- + "./wp:inline/a:graphic/a:graphicData/pic:pic" + # -- a floating picture -- + " | ./wp:anchor/a:graphic/a:graphicData/pic:pic" + ) + # -- xpath() will return a list, empty if there are no matches -- + return bool(self._drawing.xpath(xpath_expr)) + + @property + def image(self) -> Image: + """An `Image` proxy object for the image in this (picture) drawing. + + Raises `ValueError` when this drawing does contains something other than a picture. Use + `.has_picture` to qualify drawing objects before using this property. + """ + picture_rIds = self._drawing.xpath(".//pic:blipFill/a:blip/@r:embed") + if not picture_rIds: + raise ValueError("drawing does not contain a picture") + rId = picture_rIds[0] + doc_part = self.part + image_part = doc_part.related_parts[rId] + return image_part.image diff --git a/docx/opc/__init__.py b/src/docx/enum/__init__.py similarity index 100% rename from docx/opc/__init__.py rename to src/docx/enum/__init__.py diff --git a/src/docx/enum/base.py b/src/docx/enum/base.py new file mode 100644 index 00000000..66e98975 --- /dev/null +++ b/src/docx/enum/base.py @@ -0,0 +1,150 @@ +"""Base classes and other objects used by enumerations.""" + +from __future__ import annotations + +import enum +import textwrap +from typing import TYPE_CHECKING, Any, Dict, Type, TypeVar + +if TYPE_CHECKING: + from typing_extensions import Self + +_T = TypeVar("_T", bound="BaseXmlEnum") + + +class BaseEnum(int, enum.Enum): + """Base class for Enums that do not map XML attr values. + + The enum's value will be an integer, corresponding to the integer assigned the + corresponding member in the MS API enum of the same name. + """ + + def __new__(cls, ms_api_value: int, docstr: str): + self = int.__new__(cls, ms_api_value) + self._value_ = ms_api_value + self.__doc__ = docstr.strip() + return self + + def __str__(self): + """The symbolic name and string value of this member, e.g. 'MIDDLE (3)'.""" + return f"{self.name} ({self.value})" + + +class BaseXmlEnum(int, enum.Enum): + """Base class for Enums that also map XML attr values. + + The enum's value will be an integer, corresponding to the integer assigned the + corresponding member in the MS API enum of the same name. + """ + + xml_value: str | None + + def __new__(cls, ms_api_value: int, xml_value: str | None, docstr: str): + self = int.__new__(cls, ms_api_value) + self._value_ = ms_api_value + self.xml_value = xml_value + self.__doc__ = docstr.strip() + return self + + def __str__(self): + """The symbolic name and string value of this member, e.g. 'MIDDLE (3)'.""" + return f"{self.name} ({self.value})" + + @classmethod + def from_xml(cls, xml_value: str | None) -> Self: + """Enumeration member corresponding to XML attribute value `xml_value`. + + Example:: + + >>> WD_PARAGRAPH_ALIGNMENT.from_xml("center") + WD_PARAGRAPH_ALIGNMENT.CENTER + + """ + member = next((member for member in cls if member.xml_value == xml_value), None) + if member is None: + raise ValueError(f"{cls.__name__} has no XML mapping for '{xml_value}'") + return member + + @classmethod + def to_xml(cls: Type[_T], value: int | _T | None) -> str | None: + """XML value of this enum member, generally an XML attribute value.""" + # -- presence of multi-arg `__new__()` method fools type-checker, but getting a + # -- member by its value using EnumCls(val) works as usual. + member = cls(value) + xml_value = member.xml_value + if not xml_value: + raise ValueError(f"{cls.__name__}.{member.name} has no XML representation") + return xml_value + + +class DocsPageFormatter: + """Generate an .rst doc page for an enumeration. + + Formats a RestructuredText documention page (string) for the enumeration class parts + passed to the constructor. An immutable one-shot service object. + """ + + def __init__(self, clsname: str, clsdict: Dict[str, Any]): + self._clsname = clsname + self._clsdict = clsdict + + @property + def page_str(self): + """The RestructuredText documentation page for the enumeration. + + This is the only API member for the class. + """ + tmpl = ".. _%s:\n\n%s\n\n%s\n\n----\n\n%s" + components = ( + self._ms_name, + self._page_title, + self._intro_text, + self._member_defs, + ) + return tmpl % components + + @property + def _intro_text(self): + """Docstring of the enumeration, formatted for documentation page.""" + try: + cls_docstring = self._clsdict["__doc__"] + except KeyError: + cls_docstring = "" + + if cls_docstring is None: + return "" + + return textwrap.dedent(cls_docstring).strip() + + def _member_def(self, member: BaseEnum | BaseXmlEnum): + """Return an individual member definition formatted as an RST glossary entry, + wrapped to fit within 78 columns.""" + assert member.__doc__ is not None + member_docstring = textwrap.dedent(member.__doc__).strip() + member_docstring = textwrap.fill( + member_docstring, + width=78, + initial_indent=" " * 4, + subsequent_indent=" " * 4, + ) + return "%s\n%s\n" % (member.name, member_docstring) + + @property + def _member_defs(self): + """A single string containing the aggregated member definitions section of the + documentation page.""" + members = self._clsdict["__members__"] + member_defs = [self._member_def(member) for member in members if member.name is not None] + return "\n".join(member_defs) + + @property + def _ms_name(self): + """The Microsoft API name for this enumeration.""" + return self._clsdict["__ms_name__"] + + @property + def _page_title(self): + """The title for the documentation page, formatted as code (surrounded in + double-backtics) and underlined with '=' characters.""" + title_underscore = "=" * (len(self._clsname) + 4) + return "``%s``\n%s" % (self._clsname, title_underscore) diff --git a/src/docx/enum/dml.py b/src/docx/enum/dml.py new file mode 100644 index 00000000..27c63a28 --- /dev/null +++ b/src/docx/enum/dml.py @@ -0,0 +1,103 @@ +"""Enumerations used by DrawingML objects.""" + +from .base import BaseEnum, BaseXmlEnum + + +class MSO_COLOR_TYPE(BaseEnum): + """Specifies the color specification scheme. + + Example:: + + from docx.enum.dml import MSO_COLOR_TYPE + + assert font.color.type == MSO_COLOR_TYPE.SCHEME + + MS API name: `MsoColorType` + + http://msdn.microsoft.com/en-us/library/office/ff864912(v=office.15).aspx + """ + + RGB = (1, "Color is specified by an |RGBColor| value.") + """Color is specified by an |RGBColor| value.""" + + THEME = (2, "Color is one of the preset theme colors.") + """Color is one of the preset theme colors.""" + + AUTO = (101, "Color is determined automatically by the application.") + """Color is determined automatically by the application.""" + + +class MSO_THEME_COLOR_INDEX(BaseXmlEnum): + """Indicates the Office theme color, one of those shown in the color gallery on the + formatting ribbon. + + Alias: ``MSO_THEME_COLOR`` + + Example:: + + from docx.enum.dml import MSO_THEME_COLOR + + font.color.theme_color = MSO_THEME_COLOR.ACCENT_1 + + MS API name: `MsoThemeColorIndex` + + http://msdn.microsoft.com/en-us/library/office/ff860782(v=office.15).aspx + """ + + NOT_THEME_COLOR = (0, "UNMAPPED", "Indicates the color is not a theme color.") + """Indicates the color is not a theme color.""" + + ACCENT_1 = (5, "accent1", "Specifies the Accent 1 theme color.") + """Specifies the Accent 1 theme color.""" + + ACCENT_2 = (6, "accent2", "Specifies the Accent 2 theme color.") + """Specifies the Accent 2 theme color.""" + + ACCENT_3 = (7, "accent3", "Specifies the Accent 3 theme color.") + """Specifies the Accent 3 theme color.""" + + ACCENT_4 = (8, "accent4", "Specifies the Accent 4 theme color.") + """Specifies the Accent 4 theme color.""" + + ACCENT_5 = (9, "accent5", "Specifies the Accent 5 theme color.") + """Specifies the Accent 5 theme color.""" + + ACCENT_6 = (10, "accent6", "Specifies the Accent 6 theme color.") + """Specifies the Accent 6 theme color.""" + + BACKGROUND_1 = (14, "background1", "Specifies the Background 1 theme color.") + """Specifies the Background 1 theme color.""" + + BACKGROUND_2 = (16, "background2", "Specifies the Background 2 theme color.") + """Specifies the Background 2 theme color.""" + + DARK_1 = (1, "dark1", "Specifies the Dark 1 theme color.") + """Specifies the Dark 1 theme color.""" + + DARK_2 = (3, "dark2", "Specifies the Dark 2 theme color.") + """Specifies the Dark 2 theme color.""" + + FOLLOWED_HYPERLINK = ( + 12, + "followedHyperlink", + "Specifies the theme color for a clicked hyperlink.", + ) + """Specifies the theme color for a clicked hyperlink.""" + + HYPERLINK = (11, "hyperlink", "Specifies the theme color for a hyperlink.") + """Specifies the theme color for a hyperlink.""" + + LIGHT_1 = (2, "light1", "Specifies the Light 1 theme color.") + """Specifies the Light 1 theme color.""" + + LIGHT_2 = (4, "light2", "Specifies the Light 2 theme color.") + """Specifies the Light 2 theme color.""" + + TEXT_1 = (13, "text1", "Specifies the Text 1 theme color.") + """Specifies the Text 1 theme color.""" + + TEXT_2 = (15, "text2", "Specifies the Text 2 theme color.") + """Specifies the Text 2 theme color.""" + + +MSO_THEME_COLOR = MSO_THEME_COLOR_INDEX diff --git a/src/docx/enum/section.py b/src/docx/enum/section.py new file mode 100644 index 00000000..982e1911 --- /dev/null +++ b/src/docx/enum/section.py @@ -0,0 +1,86 @@ +"""Enumerations related to the main document in WordprocessingML files.""" + +from .base import BaseXmlEnum + + +class WD_HEADER_FOOTER_INDEX(BaseXmlEnum): + """Alias: **WD_HEADER_FOOTER** + + Specifies one of the three possible header/footer definitions for a section. + + For internal use only; not part of the python-docx API. + + MS API name: `WdHeaderFooterIndex` + URL: https://docs.microsoft.com/en-us/office/vba/api/word.wdheaderfooterindex + """ + + PRIMARY = (1, "default", "Header for odd pages or all if no even header.") + """Header for odd pages or all if no even header.""" + + FIRST_PAGE = (2, "first", "Header for first page of section.") + """Header for first page of section.""" + + EVEN_PAGE = (3, "even", "Header for even pages of recto/verso section.") + """Header for even pages of recto/verso section.""" + + +WD_HEADER_FOOTER = WD_HEADER_FOOTER_INDEX + + +class WD_ORIENTATION(BaseXmlEnum): + """Alias: **WD_ORIENT** + + Specifies the page layout orientation. + + Example:: + + from docx.enum.section import WD_ORIENT + + section = document.sections[-1] section.orientation = WD_ORIENT.LANDSCAPE + + MS API name: `WdOrientation` + MS API URL: http://msdn.microsoft.com/en-us/library/office/ff837902.aspx + """ + + PORTRAIT = (0, "portrait", "Portrait orientation.") + """Portrait orientation.""" + + LANDSCAPE = (1, "landscape", "Landscape orientation.") + """Landscape orientation.""" + + +WD_ORIENT = WD_ORIENTATION + + +class WD_SECTION_START(BaseXmlEnum): + """Alias: **WD_SECTION** + + Specifies the start type of a section break. + + Example:: + + from docx.enum.section import WD_SECTION + + section = document.sections[0] section.start_type = WD_SECTION.NEW_PAGE + + MS API name: `WdSectionStart` + MS API URL: http://msdn.microsoft.com/en-us/library/office/ff840975.aspx + """ + + CONTINUOUS = (0, "continuous", "Continuous section break.") + """Continuous section break.""" + + NEW_COLUMN = (1, "nextColumn", "New column section break.") + """New column section break.""" + + NEW_PAGE = (2, "nextPage", "New page section break.") + """New page section break.""" + + EVEN_PAGE = (3, "evenPage", "Even pages section break.") + """Even pages section break.""" + + ODD_PAGE = (4, "oddPage", "Section begins on next odd page.") + """Section begins on next odd page.""" + + +WD_SECTION = WD_SECTION_START diff --git a/src/docx/enum/shape.py b/src/docx/enum/shape.py new file mode 100644 index 00000000..ed086c38 --- /dev/null +++ b/src/docx/enum/shape.py @@ -0,0 +1,19 @@ +"""Enumerations related to DrawingML shapes in WordprocessingML files.""" + +import enum + + +class WD_INLINE_SHAPE_TYPE(enum.Enum): + """Corresponds to WdInlineShapeType enumeration. + + http://msdn.microsoft.com/en-us/library/office/ff192587.aspx. + """ + + CHART = 12 + LINKED_PICTURE = 4 + PICTURE = 3 + SMART_ART = 15 + NOT_IMPLEMENTED = -6 + + +WD_INLINE_SHAPE = WD_INLINE_SHAPE_TYPE diff --git a/src/docx/enum/style.py b/src/docx/enum/style.py new file mode 100644 index 00000000..d2474611 --- /dev/null +++ b/src/docx/enum/style.py @@ -0,0 +1,452 @@ +"""Enumerations related to styles.""" + +from .base import BaseEnum, BaseXmlEnum + + +class WD_BUILTIN_STYLE(BaseEnum): + """Alias: **WD_STYLE** + + Specifies a built-in Microsoft Word style. + + Example:: + + from docx import Document + from docx.enum.style import WD_STYLE + + document = Document() + styles = document.styles + style = styles[WD_STYLE.BODY_TEXT] + + + MS API name: `WdBuiltinStyle` + + http://msdn.microsoft.com/en-us/library/office/ff835210.aspx + """ + + BLOCK_QUOTATION = (-85, "Block Text.") + """Block Text.""" + + BODY_TEXT = (-67, "Body Text.") + """Body Text.""" + + BODY_TEXT_2 = (-81, "Body Text 2.") + """Body Text 2.""" + + BODY_TEXT_3 = (-82, "Body Text 3.") + """Body Text 3.""" + + BODY_TEXT_FIRST_INDENT = (-78, "Body Text First Indent.") + """Body Text First Indent.""" + + BODY_TEXT_FIRST_INDENT_2 = (-79, "Body Text First Indent 2.") + """Body Text First Indent 2.""" + + BODY_TEXT_INDENT = (-68, "Body Text Indent.") + """Body Text Indent.""" + + BODY_TEXT_INDENT_2 = (-83, "Body Text Indent 2.") + """Body Text Indent 2.""" + + BODY_TEXT_INDENT_3 = (-84, "Body Text Indent 3.") + """Body Text Indent 3.""" + + BOOK_TITLE = (-265, "Book Title.") + """Book Title.""" + + CAPTION = (-35, "Caption.") + """Caption.""" + + CLOSING = (-64, "Closing.") + """Closing.""" + + COMMENT_REFERENCE = (-40, "Comment Reference.") + """Comment Reference.""" + + COMMENT_TEXT = (-31, "Comment Text.") + """Comment Text.""" + + DATE = (-77, "Date.") + """Date.""" + + DEFAULT_PARAGRAPH_FONT = (-66, "Default Paragraph Font.") + """Default Paragraph Font.""" + + EMPHASIS = (-89, "Emphasis.") + """Emphasis.""" + + ENDNOTE_REFERENCE = (-43, "Endnote Reference.") + """Endnote Reference.""" + + ENDNOTE_TEXT = (-44, "Endnote Text.") + """Endnote Text.""" + + ENVELOPE_ADDRESS = (-37, "Envelope Address.") + """Envelope Address.""" + + ENVELOPE_RETURN = (-38, "Envelope Return.") + """Envelope Return.""" + + FOOTER = (-33, "Footer.") + """Footer.""" + + FOOTNOTE_REFERENCE = (-39, "Footnote Reference.") + """Footnote Reference.""" + + FOOTNOTE_TEXT = (-30, "Footnote Text.") + """Footnote Text.""" + + HEADER = (-32, "Header.") + """Header.""" + + HEADING_1 = (-2, "Heading 1.") + """Heading 1.""" + + HEADING_2 = (-3, "Heading 2.") + """Heading 2.""" + + HEADING_3 = (-4, "Heading 3.") + """Heading 3.""" + + HEADING_4 = (-5, "Heading 4.") + """Heading 4.""" + + HEADING_5 = (-6, "Heading 5.") + """Heading 5.""" + + HEADING_6 = (-7, "Heading 6.") + """Heading 6.""" + + HEADING_7 = (-8, "Heading 7.") + """Heading 7.""" + + HEADING_8 = (-9, "Heading 8.") + """Heading 8.""" + + HEADING_9 = (-10, "Heading 9.") + """Heading 9.""" + + HTML_ACRONYM = (-96, "HTML Acronym.") + """HTML Acronym.""" + + HTML_ADDRESS = (-97, "HTML Address.") + """HTML Address.""" + + HTML_CITE = (-98, "HTML Cite.") + """HTML Cite.""" + + HTML_CODE = (-99, "HTML Code.") + """HTML Code.""" + + HTML_DFN = (-100, "HTML Definition.") + """HTML Definition.""" + + HTML_KBD = (-101, "HTML Keyboard.") + """HTML Keyboard.""" + + HTML_NORMAL = (-95, "Normal (Web).") + """Normal (Web).""" + + HTML_PRE = (-102, "HTML Preformatted.") + """HTML Preformatted.""" + + HTML_SAMP = (-103, "HTML Sample.") + """HTML Sample.""" + + HTML_TT = (-104, "HTML Typewriter.") + """HTML Typewriter.""" + + HTML_VAR = (-105, "HTML Variable.") + """HTML Variable.""" + + HYPERLINK = (-86, "Hyperlink.") + """Hyperlink.""" + + HYPERLINK_FOLLOWED = (-87, "Followed Hyperlink.") + """Followed Hyperlink.""" + + INDEX_1 = (-11, "Index 1.") + """Index 1.""" + + INDEX_2 = (-12, "Index 2.") + """Index 2.""" + + INDEX_3 = (-13, "Index 3.") + """Index 3.""" + + INDEX_4 = (-14, "Index 4.") + """Index 4.""" + + INDEX_5 = (-15, "Index 5.") + """Index 5.""" + + INDEX_6 = (-16, "Index 6.") + """Index 6.""" + + INDEX_7 = (-17, "Index 7.") + """Index 7.""" + + INDEX_8 = (-18, "Index 8.") + """Index 8.""" + + INDEX_9 = (-19, "Index 9.") + """Index 9.""" + + INDEX_HEADING = (-34, "Index Heading") + """Index Heading""" + + INTENSE_EMPHASIS = (-262, "Intense Emphasis.") + """Intense Emphasis.""" + + INTENSE_QUOTE = (-182, "Intense Quote.") + """Intense Quote.""" + + INTENSE_REFERENCE = (-264, "Intense Reference.") + """Intense Reference.""" + + LINE_NUMBER = (-41, "Line Number.") + """Line Number.""" + + LIST = (-48, "List.") + """List.""" + + LIST_2 = (-51, "List 2.") + """List 2.""" + + LIST_3 = (-52, "List 3.") + """List 3.""" + + LIST_4 = (-53, "List 4.") + """List 4.""" + + LIST_5 = (-54, "List 5.") + """List 5.""" + + LIST_BULLET = (-49, "List Bullet.") + """List Bullet.""" + + LIST_BULLET_2 = (-55, "List Bullet 2.") + """List Bullet 2.""" + + LIST_BULLET_3 = (-56, "List Bullet 3.") + """List Bullet 3.""" + + LIST_BULLET_4 = (-57, "List Bullet 4.") + """List Bullet 4.""" + + LIST_BULLET_5 = (-58, "List Bullet 5.") + """List Bullet 5.""" + + LIST_CONTINUE = (-69, "List Continue.") + """List Continue.""" + + LIST_CONTINUE_2 = (-70, "List Continue 2.") + """List Continue 2.""" + + LIST_CONTINUE_3 = (-71, "List Continue 3.") + """List Continue 3.""" + + LIST_CONTINUE_4 = (-72, "List Continue 4.") + """List Continue 4.""" + + LIST_CONTINUE_5 = (-73, "List Continue 5.") + """List Continue 5.""" + + LIST_NUMBER = (-50, "List Number.") + """List Number.""" + + LIST_NUMBER_2 = (-59, "List Number 2.") + """List Number 2.""" + + LIST_NUMBER_3 = (-60, "List Number 3.") + """List Number 3.""" + + LIST_NUMBER_4 = (-61, "List Number 4.") + """List Number 4.""" + + LIST_NUMBER_5 = (-62, "List Number 5.") + """List Number 5.""" + + LIST_PARAGRAPH = (-180, "List Paragraph.") + """List Paragraph.""" + + MACRO_TEXT = (-46, "Macro Text.") + """Macro Text.""" + + MESSAGE_HEADER = (-74, "Message Header.") + """Message Header.""" + + NAV_PANE = (-90, "Document Map.") + """Document Map.""" + + NORMAL = (-1, "Normal.") + """Normal.""" + + NORMAL_INDENT = (-29, "Normal Indent.") + """Normal Indent.""" + + NORMAL_OBJECT = (-158, "Normal (applied to an object).") + """Normal (applied to an object).""" + + NORMAL_TABLE = (-106, "Normal (applied within a table).") + """Normal (applied within a table).""" + + NOTE_HEADING = (-80, "Note Heading.") + """Note Heading.""" + + PAGE_NUMBER = (-42, "Page Number.") + """Page Number.""" + + PLAIN_TEXT = (-91, "Plain Text.") + """Plain Text.""" + + QUOTE = (-181, "Quote.") + """Quote.""" + + SALUTATION = (-76, "Salutation.") + """Salutation.""" + + SIGNATURE = (-65, "Signature.") + """Signature.""" + + STRONG = (-88, "Strong.") + """Strong.""" + + SUBTITLE = (-75, "Subtitle.") + """Subtitle.""" + + SUBTLE_EMPHASIS = (-261, "Subtle Emphasis.") + """Subtle Emphasis.""" + + SUBTLE_REFERENCE = (-263, "Subtle Reference.") + """Subtle Reference.""" + + TABLE_COLORFUL_GRID = (-172, "Colorful Grid.") + """Colorful Grid.""" + + TABLE_COLORFUL_LIST = (-171, "Colorful List.") + """Colorful List.""" + + TABLE_COLORFUL_SHADING = (-170, "Colorful Shading.") + """Colorful Shading.""" + + TABLE_DARK_LIST = (-169, "Dark List.") + """Dark List.""" + + TABLE_LIGHT_GRID = (-161, "Light Grid.") + """Light Grid.""" + + TABLE_LIGHT_GRID_ACCENT_1 = (-175, "Light Grid Accent 1.") + """Light Grid Accent 1.""" + + TABLE_LIGHT_LIST = (-160, "Light List.") + """Light List.""" + + TABLE_LIGHT_LIST_ACCENT_1 = (-174, "Light List Accent 1.") + """Light List Accent 1.""" + + TABLE_LIGHT_SHADING = (-159, "Light Shading.") + """Light Shading.""" + + TABLE_LIGHT_SHADING_ACCENT_1 = (-173, "Light Shading Accent 1.") + """Light Shading Accent 1.""" + + TABLE_MEDIUM_GRID_1 = (-166, "Medium Grid 1.") + """Medium Grid 1.""" + + TABLE_MEDIUM_GRID_2 = (-167, "Medium Grid 2.") + """Medium Grid 2.""" + + TABLE_MEDIUM_GRID_3 = (-168, "Medium Grid 3.") + """Medium Grid 3.""" + + TABLE_MEDIUM_LIST_1 = (-164, "Medium List 1.") + """Medium List 1.""" + + TABLE_MEDIUM_LIST_1_ACCENT_1 = (-178, "Medium List 1 Accent 1.") + """Medium List 1 Accent 1.""" + + TABLE_MEDIUM_LIST_2 = (-165, "Medium List 2.") + """Medium List 2.""" + + TABLE_MEDIUM_SHADING_1 = (-162, "Medium Shading 1.") + """Medium Shading 1.""" + + TABLE_MEDIUM_SHADING_1_ACCENT_1 = (-176, "Medium Shading 1 Accent 1.") + """Medium Shading 1 Accent 1.""" + + TABLE_MEDIUM_SHADING_2 = (-163, "Medium Shading 2.") + """Medium Shading 2.""" + + TABLE_MEDIUM_SHADING_2_ACCENT_1 = (-177, "Medium Shading 2 Accent 1.") + """Medium Shading 2 Accent 1.""" + + TABLE_OF_AUTHORITIES = (-45, "Table of Authorities.") + """Table of Authorities.""" + + TABLE_OF_FIGURES = (-36, "Table of Figures.") + """Table of Figures.""" + + TITLE = (-63, "Title.") + """Title.""" + + TOAHEADING = (-47, "TOA Heading.") + """TOA Heading.""" + + TOC_1 = (-20, "TOC 1.") + """TOC 1.""" + + TOC_2 = (-21, "TOC 2.") + """TOC 2.""" + + TOC_3 = (-22, "TOC 3.") + """TOC 3.""" + + TOC_4 = (-23, "TOC 4.") + """TOC 4.""" + + TOC_5 = (-24, "TOC 5.") + """TOC 5.""" + + TOC_6 = (-25, "TOC 6.") + """TOC 6.""" + + TOC_7 = (-26, "TOC 7.") + """TOC 7.""" + + TOC_8 = (-27, "TOC 8.") + """TOC 8.""" + + TOC_9 = (-28, "TOC 9.") + """TOC 9.""" + + +WD_STYLE = WD_BUILTIN_STYLE + + +class WD_STYLE_TYPE(BaseXmlEnum): + """Specifies one of the four style types: paragraph, character, list, or table. + + Example:: + + from docx import Document + from docx.enum.style import WD_STYLE_TYPE + + styles = Document().styles + assert styles[0].type == WD_STYLE_TYPE.PARAGRAPH + + MS API name: `WdStyleType` + + http://msdn.microsoft.com/en-us/library/office/ff196870.aspx + """ + + CHARACTER = (2, "character", "Character style.") + """Character style.""" + + LIST = (4, "numbering", "List style.") + """List style.""" + + PARAGRAPH = (1, "paragraph", "Paragraph style.") + """Paragraph style.""" + + TABLE = (3, "table", "Table style.") + """Table style.""" diff --git a/src/docx/enum/table.py b/src/docx/enum/table.py new file mode 100644 index 00000000..eb1eb9dc --- /dev/null +++ b/src/docx/enum/table.py @@ -0,0 +1,136 @@ +"""Enumerations related to tables in WordprocessingML files.""" + +from docx.enum.base import BaseEnum, BaseXmlEnum + + +class WD_CELL_VERTICAL_ALIGNMENT(BaseXmlEnum): + """Alias: **WD_ALIGN_VERTICAL** + + Specifies the vertical alignment of text in one or more cells of a table. + + Example:: + + from docx.enum.table import WD_ALIGN_VERTICAL + + table = document.add_table(3, 3) + table.cell(0, 0).vertical_alignment = WD_ALIGN_VERTICAL.BOTTOM + + MS API name: `WdCellVerticalAlignment` + + https://msdn.microsoft.com/en-us/library/office/ff193345.aspx + """ + + TOP = (0, "top", "Text is aligned to the top border of the cell.") + """Text is aligned to the top border of the cell.""" + + CENTER = (1, "center", "Text is aligned to the center of the cell.") + """Text is aligned to the center of the cell.""" + + BOTTOM = (3, "bottom", "Text is aligned to the bottom border of the cell.") + """Text is aligned to the bottom border of the cell.""" + + BOTH = ( + 101, + "both", + "This is an option in the OpenXml spec, but not in Word itself. It's not" + " clear what Word behavior this setting produces. If you find out please" + " let us know and we'll update this documentation. Otherwise, probably best" + " to avoid this option.", + ) + """This is an option in the OpenXml spec, but not in Word itself. + + It's not clear what Word behavior this setting produces. If you find out please let + us know and we'll update this documentation. Otherwise, probably best to avoid this + option. + """ + + +WD_ALIGN_VERTICAL = WD_CELL_VERTICAL_ALIGNMENT + + +class WD_ROW_HEIGHT_RULE(BaseXmlEnum): + """Alias: **WD_ROW_HEIGHT** + + Specifies the rule for determining the height of a table row + + Example:: + + from docx.enum.table import WD_ROW_HEIGHT_RULE + + table = document.add_table(3, 3) + table.rows[0].height_rule = WD_ROW_HEIGHT_RULE.EXACTLY + + MS API name: `WdRowHeightRule` + + https://msdn.microsoft.com/en-us/library/office/ff193620.aspx + """ + + AUTO = ( + 0, + "auto", + "The row height is adjusted to accommodate the tallest value in the row.", + ) + """The row height is adjusted to accommodate the tallest value in the row.""" + + AT_LEAST = (1, "atLeast", "The row height is at least a minimum specified value.") + """The row height is at least a minimum specified value.""" + + EXACTLY = (2, "exact", "The row height is an exact value.") + """The row height is an exact value.""" + + +WD_ROW_HEIGHT = WD_ROW_HEIGHT_RULE + + +class WD_TABLE_ALIGNMENT(BaseXmlEnum): + """Specifies table justification type. + + Example:: + + from docx.enum.table import WD_TABLE_ALIGNMENT + + table = document.add_table(3, 3) + table.alignment = WD_TABLE_ALIGNMENT.CENTER + + MS API name: `WdRowAlignment` + + http://office.microsoft.com/en-us/word-help/HV080607259.aspx + """ + + LEFT = (0, "left", "Left-aligned") + """Left-aligned""" + + CENTER = (1, "center", "Center-aligned.") + """Center-aligned.""" + + RIGHT = (2, "right", "Right-aligned.") + """Right-aligned.""" + + +class WD_TABLE_DIRECTION(BaseEnum): + """Specifies the direction in which an application orders cells in the specified + table or row. + + Example:: + + from docx.enum.table import WD_TABLE_DIRECTION + + table = document.add_table(3, 3) + table.direction = WD_TABLE_DIRECTION.RTL + + MS API name: `WdTableDirection` + + http://msdn.microsoft.com/en-us/library/ff835141.aspx + """ + + LTR = ( + 0, + "The table or row is arranged with the first column in the leftmost position.", + ) + """The table or row is arranged with the first column in the leftmost position.""" + + RTL = ( + 1, + "The table or row is arranged with the first column in the rightmost position.", + ) + """The table or row is arranged with the first column in the rightmost position.""" diff --git a/src/docx/enum/text.py b/src/docx/enum/text.py new file mode 100644 index 00000000..99e776fe --- /dev/null +++ b/src/docx/enum/text.py @@ -0,0 +1,367 @@ +"""Enumerations related to text in WordprocessingML files.""" + +from __future__ import annotations + +import enum + +from docx.enum.base import BaseXmlEnum + + +class WD_PARAGRAPH_ALIGNMENT(BaseXmlEnum): + """Alias: **WD_ALIGN_PARAGRAPH** + + Specifies paragraph justification type. + + Example:: + + from docx.enum.text import WD_ALIGN_PARAGRAPH + + paragraph = document.add_paragraph() + paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER + """ + + LEFT = (0, "left", "Left-aligned") + """Left-aligned""" + + CENTER = (1, "center", "Center-aligned.") + """Center-aligned.""" + + RIGHT = (2, "right", "Right-aligned.") + """Right-aligned.""" + + JUSTIFY = (3, "both", "Fully justified.") + """Fully justified.""" + + DISTRIBUTE = ( + 4, + "distribute", + "Paragraph characters are distributed to fill entire width of paragraph.", + ) + """Paragraph characters are distributed to fill entire width of paragraph.""" + + JUSTIFY_MED = ( + 5, + "mediumKashida", + "Justified with a medium character compression ratio.", + ) + """Justified with a medium character compression ratio.""" + + JUSTIFY_HI = ( + 7, + "highKashida", + "Justified with a high character compression ratio.", + ) + """Justified with a high character compression ratio.""" + + JUSTIFY_LOW = (8, "lowKashida", "Justified with a low character compression ratio.") + """Justified with a low character compression ratio.""" + + THAI_JUSTIFY = ( + 9, + "thaiDistribute", + "Justified according to Thai formatting layout.", + ) + """Justified according to Thai formatting layout.""" + + +WD_ALIGN_PARAGRAPH = WD_PARAGRAPH_ALIGNMENT + + +class WD_BREAK_TYPE(enum.Enum): + """Corresponds to WdBreakType enumeration. + + http://msdn.microsoft.com/en-us/library/office/ff195905.aspx. + """ + + COLUMN = 8 + LINE = 6 + LINE_CLEAR_LEFT = 9 + LINE_CLEAR_RIGHT = 10 + LINE_CLEAR_ALL = 11 # -- added for consistency, not in MS version -- + PAGE = 7 + SECTION_CONTINUOUS = 3 + SECTION_EVEN_PAGE = 4 + SECTION_NEXT_PAGE = 2 + SECTION_ODD_PAGE = 5 + TEXT_WRAPPING = 11 + + +WD_BREAK = WD_BREAK_TYPE + + +class WD_COLOR_INDEX(BaseXmlEnum): + """Specifies a standard preset color to apply. + + Used for font highlighting and perhaps other applications. + + * MS API name: `WdColorIndex` + * URL: https://msdn.microsoft.com/EN-US/library/office/ff195343.aspx + """ + + INHERITED = (-1, None, "Color is inherited from the style hierarchy.") + """Color is inherited from the style hierarchy.""" + + AUTO = (0, "default", "Automatic color. Default; usually black.") + """Automatic color. Default; usually black.""" + + BLACK = (1, "black", "Black color.") + """Black color.""" + + BLUE = (2, "blue", "Blue color") + """Blue color""" + + BRIGHT_GREEN = (4, "green", "Bright green color.") + """Bright green color.""" + + DARK_BLUE = (9, "darkBlue", "Dark blue color.") + """Dark blue color.""" + + DARK_RED = (13, "darkRed", "Dark red color.") + """Dark red color.""" + + DARK_YELLOW = (14, "darkYellow", "Dark yellow color.") + """Dark yellow color.""" + + GRAY_25 = (16, "lightGray", "25% shade of gray color.") + """25% shade of gray color.""" + + GRAY_50 = (15, "darkGray", "50% shade of gray color.") + """50% shade of gray color.""" + + GREEN = (11, "darkGreen", "Green color.") + """Green color.""" + + PINK = (5, "magenta", "Pink color.") + """Pink color.""" + + RED = (6, "red", "Red color.") + """Red color.""" + + TEAL = (10, "darkCyan", "Teal color.") + """Teal color.""" + + TURQUOISE = (3, "cyan", "Turquoise color.") + """Turquoise color.""" + + VIOLET = (12, "darkMagenta", "Violet color.") + """Violet color.""" + + WHITE = (8, "white", "White color.") + """White color.""" + + YELLOW = (7, "yellow", "Yellow color.") + """Yellow color.""" + + +WD_COLOR = WD_COLOR_INDEX + + +class WD_LINE_SPACING(BaseXmlEnum): + """Specifies a line spacing format to be applied to a paragraph. + + Example:: + + from docx.enum.text import WD_LINE_SPACING + + paragraph = document.add_paragraph() + paragraph.line_spacing_rule = WD_LINE_SPACING.EXACTLY + + + MS API name: `WdLineSpacing` + + URL: http://msdn.microsoft.com/en-us/library/office/ff844910.aspx + """ + + SINGLE = (0, "UNMAPPED", "Single spaced (default).") + """Single spaced (default).""" + + ONE_POINT_FIVE = (1, "UNMAPPED", "Space-and-a-half line spacing.") + """Space-and-a-half line spacing.""" + + DOUBLE = (2, "UNMAPPED", "Double spaced.") + """Double spaced.""" + + AT_LEAST = ( + 3, + "atLeast", + "Minimum line spacing is specified amount. Amount is specified separately.", + ) + """Minimum line spacing is specified amount. Amount is specified separately.""" + + EXACTLY = ( + 4, + "exact", + "Line spacing is exactly specified amount. Amount is specified separately.", + ) + """Line spacing is exactly specified amount. Amount is specified separately.""" + + MULTIPLE = ( + 5, + "auto", + "Line spacing is specified as multiple of line heights. Changing font size" + " will change line spacing proportionately.", + ) + """Line spacing is specified as multiple of line heights. Changing font size will + change the line spacing proportionately.""" + + +class WD_TAB_ALIGNMENT(BaseXmlEnum): + """Specifies the tab stop alignment to apply. + + MS API name: `WdTabAlignment` + + URL: https://msdn.microsoft.com/EN-US/library/office/ff195609.aspx + """ + + LEFT = (0, "left", "Left-aligned.") + """Left-aligned.""" + + CENTER = (1, "center", "Center-aligned.") + """Center-aligned.""" + + RIGHT = (2, "right", "Right-aligned.") + """Right-aligned.""" + + DECIMAL = (3, "decimal", "Decimal-aligned.") + """Decimal-aligned.""" + + BAR = (4, "bar", "Bar-aligned.") + """Bar-aligned.""" + + LIST = (6, "list", "List-aligned. (deprecated)") + """List-aligned. (deprecated)""" + + CLEAR = (101, "clear", "Clear an inherited tab stop.") + """Clear an inherited tab stop.""" + + END = (102, "end", "Right-aligned. (deprecated)") + """Right-aligned. (deprecated)""" + + NUM = (103, "num", "Left-aligned. (deprecated)") + """Left-aligned. (deprecated)""" + + START = (104, "start", "Left-aligned. (deprecated)") + """Left-aligned. (deprecated)""" + + +class WD_TAB_LEADER(BaseXmlEnum): + """Specifies the character to use as the leader with formatted tabs. + + MS API name: `WdTabLeader` + + URL: https://msdn.microsoft.com/en-us/library/office/ff845050.aspx + """ + + SPACES = (0, "none", "Spaces. Default.") + """Spaces. Default.""" + + DOTS = (1, "dot", "Dots.") + """Dots.""" + + DASHES = (2, "hyphen", "Dashes.") + """Dashes.""" + + LINES = (3, "underscore", "Double lines.") + """Double lines.""" + + HEAVY = (4, "heavy", "A heavy line.") + """A heavy line.""" + + MIDDLE_DOT = (5, "middleDot", "A vertically-centered dot.") + """A vertically-centered dot.""" + + +class WD_UNDERLINE(BaseXmlEnum): + """Specifies the style of underline applied to a run of characters. + + MS API name: `WdUnderline` + + URL: http://msdn.microsoft.com/en-us/library/office/ff822388.aspx + """ + + INHERITED = (-1, None, "Inherit underline setting from containing paragraph.") + """Inherit underline setting from containing paragraph.""" + + NONE = ( + 0, + "none", + "No underline.\n\nThis setting overrides any inherited underline value, so can" + " be used to remove underline from a run that inherits underlining from its" + " containing paragraph. Note this is not the same as assigning |None| to" + " Run.underline. |None| is a valid assignment value, but causes the run to" + " inherit its underline value. Assigning `WD_UNDERLINE.NONE` causes" + " underlining to be unconditionally turned off.", + ) + """No underline. + + This setting overrides any inherited underline value, so can be used to remove + underline from a run that inherits underlining from its containing paragraph. Note + this is not the same as assigning |None| to Run.underline. |None| is a valid + assignment value, but causes the run to inherit its underline value. Assigning + ``WD_UNDERLINE.NONE`` causes underlining to be unconditionally turned off. + """ + + SINGLE = ( + 1, + "single", + "A single line.\n\nNote that this setting is write-only in the sense that" + " |True| (rather than `WD_UNDERLINE.SINGLE`) is returned for a run having" + " this setting.", + ) + """A single line. + + Note that this setting is write-only in the sense that |True| + (rather than ``WD_UNDERLINE.SINGLE``) is returned for a run having this setting. + """ + + WORDS = (2, "words", "Underline individual words only.") + """Underline individual words only.""" + + DOUBLE = (3, "double", "A double line.") + """A double line.""" + + DOTTED = (4, "dotted", "Dots.") + """Dots.""" + + THICK = (6, "thick", "A single thick line.") + """A single thick line.""" + + DASH = (7, "dash", "Dashes.") + """Dashes.""" + + DOT_DASH = (9, "dotDash", "Alternating dots and dashes.") + """Alternating dots and dashes.""" + + DOT_DOT_DASH = (10, "dotDotDash", "An alternating dot-dot-dash pattern.") + """An alternating dot-dot-dash pattern.""" + + WAVY = (11, "wave", "A single wavy line.") + """A single wavy line.""" + + DOTTED_HEAVY = (20, "dottedHeavy", "Heavy dots.") + """Heavy dots.""" + + DASH_HEAVY = (23, "dashedHeavy", "Heavy dashes.") + """Heavy dashes.""" + + DOT_DASH_HEAVY = (25, "dashDotHeavy", "Alternating heavy dots and heavy dashes.") + """Alternating heavy dots and heavy dashes.""" + + DOT_DOT_DASH_HEAVY = ( + 26, + "dashDotDotHeavy", + "An alternating heavy dot-dot-dash pattern.", + ) + """An alternating heavy dot-dot-dash pattern.""" + + WAVY_HEAVY = (27, "wavyHeavy", "A heavy wavy line.") + """A heavy wavy line.""" + + DASH_LONG = (39, "dashLong", "Long dashes.") + """Long dashes.""" + + WAVY_DOUBLE = (43, "wavyDouble", "A double wavy line.") + """A double wavy line.""" + + DASH_LONG_HEAVY = (55, "dashLongHeavy", "Long heavy dashes.") + """Long heavy dashes.""" diff --git a/src/docx/exceptions.py b/src/docx/exceptions.py new file mode 100644 index 00000000..e26f4c3b --- /dev/null +++ b/src/docx/exceptions.py @@ -0,0 +1,18 @@ +"""Exceptions used with python-docx. + +The base exception class is PythonDocxError. +""" + + +class PythonDocxError(Exception): + """Generic error class.""" + + +class InvalidSpanError(PythonDocxError): + """Raised when an invalid merge region is specified in a request to merge table + cells.""" + + +class InvalidXmlError(PythonDocxError): + """Raised when invalid XML is encountered, such as on attempt to access a missing + required child element.""" diff --git a/docx/image/__init__.py b/src/docx/image/__init__.py similarity index 74% rename from docx/image/__init__.py rename to src/docx/image/__init__.py index 47576c49..8535144e 100644 --- a/docx/image/__init__.py +++ b/src/docx/image/__init__.py @@ -1,11 +1,10 @@ -# encoding: utf-8 +"""Provides objects that can characterize image streams. -""" -Provides objects that can characterize image streams as to content type and -size, as a required step in including them in a document. +That characterization is as to content type and size, as a required step in including +them in a document. """ -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import annotations from docx.image.bmp import Bmp from docx.image.emf import Emf @@ -15,7 +14,6 @@ from docx.image.svg import Svg from docx.image.tiff import Tiff - SIGNATURES = ( # class, offset, signature_bytes (Png, 0, b"\x89PNG\x0D\x0A\x1A\x0A"), @@ -28,6 +26,7 @@ (Tiff, 0, b"II*\x00"), # little-endian (Intel) TIFF (Bmp, 0, b"BM"), (Emf, 0, b"\x01\x00\x00\x00"), + (Emf, 40, b"\x20\x45\x4D\x46"), (Svg, 0, b"L" return self._read_int(fmt, base, offset) def read_short(self, base, offset=0): - """ - Return the int value of the two bytes at the file position determined - by *base* and *offset*, similarly to ``read_long()`` above. - """ + """Return the int value of the two bytes at the file position determined by + `base` and `offset`, similarly to ``read_long()`` above.""" fmt = b"H" return self._read_int(fmt, base, offset) def read_str(self, char_count, base, offset=0): - """ - Return a string containing the *char_count* bytes at the file - position determined by self._base_offset + *base* + *offset*. - """ + """Return a string containing the `char_count` bytes at the file position + determined by self._base_offset + `base` + `offset`.""" def str_struct(char_count): format_ = "%ds" % char_count @@ -77,9 +67,7 @@ def seek(self, base, offset=0): self._stream.seek(location) def tell(self): - """ - Allow pass-through tell() call - """ + """Allow pass-through tell() call.""" return self._stream.tell() def _read_bytes(self, byte_count, base, offset): diff --git a/src/docx/image/image.py b/src/docx/image/image.py new file mode 100644 index 00000000..bbdd6ef5 --- /dev/null +++ b/src/docx/image/image.py @@ -0,0 +1,237 @@ +"""Provides objects that can characterize image streams. + +That characterization is as to content type and size, as a required step in including +them in a document. +""" + +from __future__ import annotations + +import hashlib +import io +import os +from typing import IO, Tuple + +from docx.image.exceptions import UnrecognizedImageError +from docx.shared import Emu, Inches, Length, lazyproperty + + +class Image: + """Graphical image stream such as JPEG, PNG, or GIF with properties and methods + required by ImagePart.""" + + def __init__(self, blob: bytes, filename: str, image_header: BaseImageHeader): + super(Image, self).__init__() + self._blob = blob + self._filename = filename + self._image_header = image_header + + @classmethod + def from_blob(cls, blob: bytes) -> Image: + """Return a new |Image| subclass instance parsed from the image binary contained + in `blob`.""" + stream = io.BytesIO(blob) + return cls._from_stream(stream, blob) + + @classmethod + def from_file(cls, image_descriptor: str | IO[bytes]): + """Return a new |Image| subclass instance loaded from the image file identified + by `image_descriptor`, a path or file-like object.""" + if isinstance(image_descriptor, str): + path = image_descriptor + with open(path, "rb") as f: + blob = f.read() + stream = io.BytesIO(blob) + filename = os.path.basename(path) + else: + stream = image_descriptor + stream.seek(0) + blob = stream.read() + filename = None + return cls._from_stream(stream, blob, filename) + + @property + def blob(self): + """The bytes of the image 'file'.""" + return self._blob + + @property + def content_type(self) -> str: + """MIME content type for this image, e.g. ``'image/jpeg'`` for a JPEG image.""" + return self._image_header.content_type + + @lazyproperty + def ext(self): + """The file extension for the image. + + If an actual one is available from a load filename it is used. Otherwise a + canonical extension is assigned based on the content type. Does not contain the + leading period, e.g. 'jpg', not '.jpg'. + """ + return os.path.splitext(self._filename)[1][1:] + + @property + def filename(self): + """Original image file name, if loaded from disk, or a generic filename if + loaded from an anonymous stream.""" + return self._filename + + @property + def px_width(self) -> int: + """The horizontal pixel dimension of the image.""" + return self._image_header.px_width + + @property + def px_height(self) -> int: + """The vertical pixel dimension of the image.""" + return self._image_header.px_height + + @property + def horz_dpi(self) -> int: + """Integer dots per inch for the width of this image. + + Defaults to 72 when not present in the file, as is often the case. + """ + return self._image_header.horz_dpi + + @property + def vert_dpi(self) -> int: + """Integer dots per inch for the height of this image. + + Defaults to 72 when not present in the file, as is often the case. + """ + return self._image_header.vert_dpi + + @property + def width(self) -> Inches: + """A |Length| value representing the native width of the image, calculated from + the values of `px_width` and `horz_dpi`.""" + return Inches(self.px_width / self.horz_dpi) + + @property + def height(self) -> Inches: + """A |Length| value representing the native height of the image, calculated from + the values of `px_height` and `vert_dpi`.""" + return Inches(self.px_height / self.vert_dpi) + + def scaled_dimensions( + self, width: int | Length | None = None, height: int | Length | None = None + ) -> Tuple[Length, Length]: + """(cx, cy) pair representing scaled dimensions of this image. + + The native dimensions of the image are scaled by applying the following rules to + the `width` and `height` arguments. + + * If both `width` and `height` are specified, the return value is (`width`, + `height`); no scaling is performed. + * If only one is specified, it is used to compute a scaling factor that is then + applied to the unspecified dimension, preserving the aspect ratio of the image. + * If both `width` and `height` are |None|, the native dimensions are returned. + + The native dimensions are calculated using the dots-per-inch (dpi) value + embedded in the image, defaulting to 72 dpi if no value is specified, as is + often the case. The returned values are both |Length| objects. + """ + if width is None and height is None: + return self.width, self.height + + if width is None: + assert height is not None + scaling_factor = float(height) / float(self.height) + width = round(self.width * scaling_factor) + + if height is None: + scaling_factor = float(width) / float(self.width) + height = round(self.height * scaling_factor) + + return Emu(width), Emu(height) + + @lazyproperty + def sha1(self): + """SHA1 hash digest of the image blob.""" + return hashlib.sha1(self._blob).hexdigest() + + @classmethod + def _from_stream( + cls, + stream: IO[bytes], + blob: bytes, + filename: str | None = None, + ) -> Image: + """Return an instance of the |Image| subclass corresponding to the format of the + image in `stream`.""" + image_header = _ImageHeaderFactory(stream) + if filename is None: + filename = "image.%s" % image_header.default_ext + return cls(blob, filename, image_header) + + +def _ImageHeaderFactory(stream: IO[bytes]): + """A |BaseImageHeader| subclass instance that can parse headers of image in `stream`.""" + from docx.image import SIGNATURES + from docx.image.svg import Svg + + def read_32(stream: IO[bytes]): + stream.seek(0) + return stream.read(32) + + header = read_32(stream) + if header.startswith(b" str: + """Abstract property definition, must be implemented by all subclasses.""" + msg = "content_type property must be implemented by all subclasses of BaseImageHeader" + raise NotImplementedError(msg) + + @property + def default_ext(self) -> str: + """Default filename extension for images of this type. + + An abstract property definition, must be implemented by all subclasses. + """ + raise NotImplementedError( + "default_ext property must be implemented by all subclasses of BaseImageHeader" + ) + + @property + def px_width(self): + """The horizontal pixel dimension of the image.""" + return self._px_width + + @property + def px_height(self): + """The vertical pixel dimension of the image.""" + return self._px_height + + @property + def horz_dpi(self): + """Integer dots per inch for the width of this image. + + Defaults to 72 when not present in the file, as is often the case. + """ + return self._horz_dpi + + @property + def vert_dpi(self): + """Integer dots per inch for the height of this image. + + Defaults to 72 when not present in the file, as is often the case. + """ + return self._vert_dpi diff --git a/docx/image/jpeg.py b/src/docx/image/jpeg.py similarity index 66% rename from docx/image/jpeg.py rename to src/docx/image/jpeg.py index 513287d0..fc37ca3a 100644 --- a/docx/image/jpeg.py +++ b/src/docx/image/jpeg.py @@ -1,41 +1,36 @@ +"""Objects related to parsing headers of JPEG image streams. + +Includes both JFIF and Exif sub-formats. """ -Objects related to parsing headers of JPEG image streams, both JFIF and Exif -sub-formats. -""" -from ..compat import BytesIO -from .constants import JPEG_MARKER_CODE, MIME_TYPE -from .helpers import BIG_ENDIAN, StreamReader -from .image import BaseImageHeader -from .tiff import Tiff + +import io + +from docx.image.constants import JPEG_MARKER_CODE, MIME_TYPE +from docx.image.helpers import BIG_ENDIAN, StreamReader +from docx.image.image import BaseImageHeader +from docx.image.tiff import Tiff class Jpeg(BaseImageHeader): - """ - Base class for JFIF and EXIF subclasses. - """ + """Base class for JFIF and EXIF subclasses.""" @property def content_type(self): - """ - MIME content type for this image, unconditionally `image/jpeg` for - JPEG images. - """ + """MIME content type for this image, unconditionally `image/jpeg` for JPEG + images.""" return MIME_TYPE.JPEG @property def default_ext(self): - """ - Default filename extension, always 'jpg' for JPG images. - """ + """Default filename extension, always 'jpg' for JPG images.""" return "jpg" DEFAULT_DPI = 72 @classmethod def from_stream(cls, stream): - """ - If APP0 or APP1 is missing, the DPI values will be set to the default value of |DEFAULT_DPI|(72). - """ + """If APP0 or APP1 is missing, the DPI values will be set to the default value of + |DEFAULT_DPI|(72).""" markers = _JfifMarkers.from_stream(stream) px_width = markers.sof.px_width px_height = markers.sof.px_height @@ -76,17 +71,14 @@ def _try_get_dpi_from_app1(markers): class Exif(Jpeg): - """ - Image header parser for Exif image format - """ + """Image header parser for Exif image format.""" @classmethod def from_stream(cls, stream): - """ - Return |Exif| instance having header properties parsed from Exif - image in *stream*. - """ + """Return |Exif| instance having header properties parsed from Exif image in + `stream`.""" markers = _JfifMarkers.from_stream(stream) + # print('\n%s' % markers) px_width = markers.sof.px_width px_height = markers.sof.px_height @@ -97,16 +89,12 @@ def from_stream(cls, stream): class Jfif(Jpeg): - """ - Image header parser for JFIF image format - """ + """Image header parser for JFIF image format.""" @classmethod def from_stream(cls, stream): - """ - Return a |Jfif| instance having header properties parsed from image - in *stream*. - """ + """Return a |Jfif| instance having header properties parsed from image in + `stream`.""" markers = _JfifMarkers.from_stream(stream) px_width = markers.sof.px_width @@ -117,21 +105,17 @@ def from_stream(cls, stream): return cls(px_width, px_height, horz_dpi, vert_dpi) -class _JfifMarkers(object): - """ - Sequence of markers in a JPEG file, perhaps truncated at first SOS marker - for performance reasons. - """ +class _JfifMarkers: + """Sequence of markers in a JPEG file, perhaps truncated at first SOS marker for + performance reasons.""" def __init__(self, markers): super(_JfifMarkers, self).__init__() self._markers = list(markers) def __str__(self): # pragma: no cover - """ - Returns a tabular listing of the markers in this instance, which can - be handy for debugging and perhaps other uses. - """ + """Returns a tabular listing of the markers in this instance, which can be handy + for debugging and perhaps other uses.""" header = " offset seglen mc name\n======= ====== == =====" tmpl = "%7d %6d %02X %s" rows = [] @@ -150,10 +134,8 @@ def __str__(self): # pragma: no cover @classmethod def from_stream(cls, stream): - """ - Return a |_JfifMarkers| instance containing a |_JfifMarker| subclass - instance for each marker in *stream*. - """ + """Return a |_JfifMarkers| instance containing a |_JfifMarker| subclass instance + for each marker in `stream`.""" marker_parser = _MarkerParser.from_stream(stream) markers = [] for marker in marker_parser.iter_markers(): @@ -164,9 +146,7 @@ def from_stream(cls, stream): @property def app0(self): - """ - First APP0 marker in image markers. - """ + """First APP0 marker in image markers.""" for m in self._markers: if m.marker_code == JPEG_MARKER_CODE.APP0: return m @@ -174,9 +154,7 @@ def app0(self): @property def app1(self): - """ - First APP1 marker in image markers. - """ + """First APP1 marker in image markers.""" for m in self._markers: if m.marker_code == JPEG_MARKER_CODE.APP1: return m @@ -184,20 +162,16 @@ def app1(self): @property def sof(self): - """ - First start of frame (SOFn) marker in this sequence. - """ + """First start of frame (SOFn) marker in this sequence.""" for m in self._markers: if m.marker_code in JPEG_MARKER_CODE.SOF_MARKER_CODES: return m raise KeyError("no start of frame (SOFn) marker in image") -class _MarkerParser(object): - """ - Service class that knows how to parse a JFIF stream and iterate over its - markers. - """ +class _MarkerParser: + """Service class that knows how to parse a JFIF stream and iterate over its + markers.""" def __init__(self, stream_reader): super(_MarkerParser, self).__init__() @@ -205,18 +179,13 @@ def __init__(self, stream_reader): @classmethod def from_stream(cls, stream): - """ - Return a |_MarkerParser| instance to parse JFIF markers from - *stream*. - """ + """Return a |_MarkerParser| instance to parse JFIF markers from `stream`.""" stream_reader = StreamReader(stream, BIG_ENDIAN) return cls(stream_reader) def iter_markers(self): - """ - Generate a (marker_code, segment_offset) 2-tuple for each marker in - the JPEG *stream*, in the order they occur in the stream. - """ + """Generate a (marker_code, segment_offset) 2-tuple for each marker in the JPEG + `stream`, in the order they occur in the stream.""" marker_finder = _MarkerFinder.from_stream(self._stream) start = 0 marker_code = None @@ -227,10 +196,8 @@ def iter_markers(self): start = segment_offset + marker.segment_length -class _MarkerFinder(object): - """ - Service class that knows how to find the next JFIF marker in a stream. - """ +class _MarkerFinder: + """Service class that knows how to find the next JFIF marker in a stream.""" def __init__(self, stream): super(_MarkerFinder, self).__init__() @@ -238,18 +205,16 @@ def __init__(self, stream): @classmethod def from_stream(cls, stream): - """ - Return a |_MarkerFinder| instance to find JFIF markers in *stream*. - """ + """Return a |_MarkerFinder| instance to find JFIF markers in `stream`.""" return cls(stream) def next(self, start): - """ - Return a (marker_code, segment_offset) 2-tuple identifying and - locating the first marker in *stream* occuring after offset *start*. - The returned *segment_offset* points to the position immediately - following the 2-byte marker code, the start of the marker segment, - for those markers that have a segment. + """Return a (marker_code, segment_offset) 2-tuple identifying and locating the + first marker in `stream` occuring after offset `start`. + + The returned `segment_offset` points to the position immediately following the + 2-byte marker code, the start of the marker segment, for those markers that have + a segment. """ position = start while True: @@ -266,36 +231,37 @@ def next(self, start): return marker_code, segment_offset def _next_non_ff_byte(self, start): - """ - Return an offset, byte 2-tuple for the next byte in *stream* that is - not '\xFF', starting with the byte at offset *start*. If the byte at - offset *start* is not '\xFF', *start* and the returned *offset* will - be the same. + """Return an offset, byte 2-tuple for the next byte in `stream` that is not + '\xff', starting with the byte at offset `start`. + + If the byte at offset `start` is not '\xff', `start` and the returned `offset` + will be the same. """ self._stream.seek(start) byte_ = self._read_byte() - while byte_ == b"\xFF": + while byte_ == b"\xff": byte_ = self._read_byte() offset_of_non_ff_byte = self._stream.tell() - 1 return offset_of_non_ff_byte, byte_ def _offset_of_next_ff_byte(self, start): - """ - Return the offset of the next '\xFF' byte in *stream* starting with - the byte at offset *start*. Returns *start* if the byte at that - offset is a hex 255; it does not necessarily advance in the stream. + """Return the offset of the next '\xff' byte in `stream` starting with the byte + at offset `start`. + + Returns `start` if the byte at that offset is a hex 255; it does not necessarily + advance in the stream. """ self._stream.seek(start) byte_ = self._read_byte() - while byte_ != b"\xFF": + while byte_ != b"\xff": byte_ = self._read_byte() offset_of_ff_byte = self._stream.tell() - 1 return offset_of_ff_byte def _read_byte(self): - """ - Return the next byte read from stream. Raise Exception if stream is - at end of file. + """Return the next byte read from stream. + + Raise Exception if stream is at end of file. """ byte_ = self._stream.read(1) if not byte_: # pragma: no cover @@ -304,10 +270,8 @@ def _read_byte(self): def _MarkerFactory(marker_code, stream, offset): - """ - Return |_Marker| or subclass instance appropriate for marker at *offset* - in *stream* having *marker_code*. - """ + """Return |_Marker| or subclass instance appropriate for marker at `offset` in + `stream` having `marker_code`.""" if marker_code == JPEG_MARKER_CODE.APP0: marker_cls = _App0Marker elif marker_code == JPEG_MARKER_CODE.APP1: @@ -319,10 +283,10 @@ def _MarkerFactory(marker_code, stream, offset): return marker_cls.from_stream(stream, marker_code, offset) -class _Marker(object): - """ - Base class for JFIF marker classes. Represents a marker and its segment - occuring in a JPEG byte stream. +class _Marker: + """Base class for JFIF marker classes. + + Represents a marker and its segment occuring in a JPEG byte stream. """ def __init__(self, marker_code, offset, segment_length): @@ -333,10 +297,8 @@ def __init__(self, marker_code, offset, segment_length): @classmethod def from_stream(cls, stream, marker_code, offset): - """ - Return a generic |_Marker| instance for the marker at *offset* in - *stream* having *marker_code*. - """ + """Return a generic |_Marker| instance for the marker at `offset` in `stream` + having `marker_code`.""" if JPEG_MARKER_CODE.is_standalone(marker_code): segment_length = 0 else: @@ -345,10 +307,8 @@ def from_stream(cls, stream, marker_code, offset): @property def marker_code(self): - """ - The single-byte code that identifies the type of this marker, e.g. - ``'\xE0'`` for start of image (SOI). - """ + """The single-byte code that identifies the type of this marker, e.g. ``'\xe0'`` + for start of image (SOI).""" return self._marker_code @property @@ -361,20 +321,14 @@ def offset(self): # pragma: no cover @property def segment_length(self): - """ - The length in bytes of this marker's segment - """ + """The length in bytes of this marker's segment.""" return self._segment_length class _App0Marker(_Marker): - """ - Represents a JFIF APP0 marker segment. - """ + """Represents a JFIF APP0 marker segment.""" - def __init__( - self, marker_code, offset, length, density_units, x_density, y_density - ): + def __init__(self, marker_code, offset, length, density_units, x_density, y_density): super(_App0Marker, self).__init__(marker_code, offset, length) self._density_units = density_units self._x_density = x_density @@ -382,24 +336,18 @@ def __init__( @property def horz_dpi(self): - """ - Horizontal dots per inch specified in this marker, defaults to 72 if - not specified. - """ + """Horizontal dots per inch specified in this marker, defaults to 72 if not + specified.""" return self._dpi(self._x_density) @property def vert_dpi(self): - """ - Vertical dots per inch specified in this marker, defaults to 72 if - not specified. - """ + """Vertical dots per inch specified in this marker, defaults to 72 if not + specified.""" return self._dpi(self._y_density) def _dpi(self, density): - """ - Return dots per inch corresponding to *density* value. - """ + """Return dots per inch corresponding to `density` value.""" if self._density_units == 1: dpi = density elif self._density_units == 2: @@ -410,10 +358,8 @@ def _dpi(self, density): @classmethod def from_stream(cls, stream, marker_code, offset): - """ - Return an |_App0Marker| instance for the APP0 marker at *offset* in - *stream*. - """ + """Return an |_App0Marker| instance for the APP0 marker at `offset` in + `stream`.""" # field off type notes # ------------------ --- ----- ------------------- # segment length 0 short @@ -428,15 +374,11 @@ def from_stream(cls, stream, marker_code, offset): density_units = stream.read_byte(offset, 9) x_density = stream.read_short(offset, 10) y_density = stream.read_short(offset, 12) - return cls( - marker_code, offset, segment_length, density_units, x_density, y_density - ) + return cls(marker_code, offset, segment_length, density_units, x_density, y_density) class _App1Marker(_Marker): - """ - Represents a JFIF APP1 (Exif) marker segment. - """ + """Represents a JFIF APP1 (Exif) marker segment.""" def __init__(self, marker_code, offset, length, horz_dpi, vert_dpi): super(_App1Marker, self).__init__(marker_code, offset, length) @@ -445,10 +387,8 @@ def __init__(self, marker_code, offset, length, horz_dpi, vert_dpi): @classmethod def from_stream(cls, stream, marker_code, offset): - """ - Extract the horizontal and vertical dots-per-inch value from the APP1 - header at *offset* in *stream*. - """ + """Extract the horizontal and vertical dots-per-inch value from the APP1 header + at `offset` in `stream`.""" # field off len type notes # -------------------- --- --- ----- ---------------------------- # segment length 0 2 short @@ -465,48 +405,38 @@ def from_stream(cls, stream, marker_code, offset): @property def horz_dpi(self): - """ - Horizontal dots per inch specified in this marker, defaults to 72 if - not specified. - """ + """Horizontal dots per inch specified in this marker, defaults to 72 if not + specified.""" return self._horz_dpi @property def vert_dpi(self): - """ - Vertical dots per inch specified in this marker, defaults to 72 if - not specified. - """ + """Vertical dots per inch specified in this marker, defaults to 72 if not + specified.""" return self._vert_dpi @classmethod def _is_non_Exif_APP1_segment(cls, stream, offset): - """ - Return True if the APP1 segment at *offset* in *stream* is NOT an - Exif segment, as determined by the ``'Exif\x00\x00'`` signature at - offset 2 in the segment. - """ + """Return True if the APP1 segment at `offset` in `stream` is NOT an Exif + segment, as determined by the ``'Exif\x00\x00'`` signature at offset 2 in the + segment.""" stream.seek(offset + 2) exif_signature = stream.read(6) return exif_signature != b"Exif\x00\x00" @classmethod def _tiff_from_exif_segment(cls, stream, offset, segment_length): - """ - Return a |Tiff| instance parsed from the Exif APP1 segment of - *segment_length* at *offset* in *stream*. - """ + """Return a |Tiff| instance parsed from the Exif APP1 segment of + `segment_length` at `offset` in `stream`.""" # wrap full segment in its own stream and feed to Tiff() stream.seek(offset + 8) segment_bytes = stream.read(segment_length - 8) - substream = BytesIO(segment_bytes) + substream = io.BytesIO(segment_bytes) return Tiff.from_stream(substream) class _SofMarker(_Marker): - """ - Represents a JFIF start of frame (SOFx) marker segment. - """ + """Represents a JFIF start of frame (SOFx) marker segment.""" def __init__(self, marker_code, offset, segment_length, px_width, px_height): super(_SofMarker, self).__init__(marker_code, offset, segment_length) @@ -515,10 +445,7 @@ def __init__(self, marker_code, offset, segment_length, px_width, px_height): @classmethod def from_stream(cls, stream, marker_code, offset): - """ - Return an |_SofMarker| instance for the SOFn marker at *offset* in - stream. - """ + """Return an |_SofMarker| instance for the SOFn marker at `offset` in stream.""" # field off type notes # ------------------ --- ----- ---------------------------- # segment length 0 short @@ -533,14 +460,10 @@ def from_stream(cls, stream, marker_code, offset): @property def px_height(self): - """ - Image height in pixels - """ + """Image height in pixels.""" return self._px_height @property def px_width(self): - """ - Image width in pixels - """ + """Image width in pixels.""" return self._px_width diff --git a/docx/image/png.py b/src/docx/image/png.py similarity index 62% rename from docx/image/png.py rename to src/docx/image/png.py index c2e4ae82..dd3cf819 100644 --- a/docx/image/png.py +++ b/src/docx/image/png.py @@ -1,7 +1,3 @@ -# encoding: utf-8 - -from __future__ import absolute_import, division, print_function - from .constants import MIME_TYPE, PNG_CHUNK_TYPE from .exceptions import InvalidImageStreamError from .helpers import BIG_ENDIAN, StreamReader @@ -9,31 +5,23 @@ class Png(BaseImageHeader): - """ - Image header parser for PNG images - """ + """Image header parser for PNG images.""" @property def content_type(self): - """ - MIME content type for this image, unconditionally `image/png` for - PNG images. - """ + """MIME content type for this image, unconditionally `image/png` for PNG + images.""" return MIME_TYPE.PNG @property def default_ext(self): - """ - Default filename extension, always 'png' for PNG images. - """ + """Default filename extension, always 'png' for PNG images.""" return "png" @classmethod def from_stream(cls, stream): - """ - Return a |Png| instance having header properties parsed from image in - *stream*. - """ + """Return a |Png| instance having header properties parsed from image in + `stream`.""" parser = _PngParser.parse(stream) px_width = parser.px_width @@ -44,11 +32,8 @@ def from_stream(cls, stream): return cls(px_width, px_height, horz_dpi, vert_dpi) -class _PngParser(object): - """ - Parses a PNG image stream to extract the image properties found in its - chunks. - """ +class _PngParser: + """Parses a PNG image stream to extract the image properties found in its chunks.""" def __init__(self, chunks): super(_PngParser, self).__init__() @@ -56,34 +41,28 @@ def __init__(self, chunks): @classmethod def parse(cls, stream): - """ - Return a |_PngParser| instance containing the header properties - parsed from the PNG image in *stream*. - """ + """Return a |_PngParser| instance containing the header properties parsed from + the PNG image in `stream`.""" chunks = _Chunks.from_stream(stream) return cls(chunks) @property def px_width(self): - """ - The number of pixels in each row of the image. - """ + """The number of pixels in each row of the image.""" IHDR = self._chunks.IHDR return IHDR.px_width @property def px_height(self): - """ - The number of stacked rows of pixels in the image. - """ + """The number of stacked rows of pixels in the image.""" IHDR = self._chunks.IHDR return IHDR.px_height @property def horz_dpi(self): - """ - Integer dots per inch for the width of this image. Defaults to 72 - when not present in the file, as is often the case. + """Integer dots per inch for the width of this image. + + Defaults to 72 when not present in the file, as is often the case. """ pHYs = self._chunks.pHYs if pHYs is None: @@ -92,9 +71,9 @@ def horz_dpi(self): @property def vert_dpi(self): - """ - Integer dots per inch for the height of this image. Defaults to 72 - when not present in the file, as is often the case. + """Integer dots per inch for the height of this image. + + Defaults to 72 when not present in the file, as is often the case. """ pHYs = self._chunks.pHYs if pHYs is None: @@ -103,19 +82,15 @@ def vert_dpi(self): @staticmethod def _dpi(units_specifier, px_per_unit): - """ - Return dots per inch value calculated from *units_specifier* and - *px_per_unit*. - """ + """Return dots per inch value calculated from `units_specifier` and + `px_per_unit`.""" if units_specifier == 1 and px_per_unit: return int(round(px_per_unit * 0.0254)) return 72 -class _Chunks(object): - """ - Collection of the chunks parsed from a PNG image stream - """ +class _Chunks: + """Collection of the chunks parsed from a PNG image stream.""" def __init__(self, chunk_iterable): super(_Chunks, self).__init__() @@ -123,18 +98,14 @@ def __init__(self, chunk_iterable): @classmethod def from_stream(cls, stream): - """ - Return a |_Chunks| instance containing the PNG chunks in *stream*. - """ + """Return a |_Chunks| instance containing the PNG chunks in `stream`.""" chunk_parser = _ChunkParser.from_stream(stream) - chunks = [chunk for chunk in chunk_parser.iter_chunks()] + chunks = list(chunk_parser.iter_chunks()) return cls(chunks) @property def IHDR(self): - """ - IHDR chunk in PNG image - """ + """IHDR chunk in PNG image.""" match = lambda chunk: chunk.type_name == PNG_CHUNK_TYPE.IHDR # noqa IHDR = self._find_first(match) if IHDR is None: @@ -143,27 +114,20 @@ def IHDR(self): @property def pHYs(self): - """ - pHYs chunk in PNG image, or |None| if not present - """ + """PHYs chunk in PNG image, or |None| if not present.""" match = lambda chunk: chunk.type_name == PNG_CHUNK_TYPE.pHYs # noqa return self._find_first(match) def _find_first(self, match): - """ - Return first chunk in stream order returning True for function - *match*. - """ + """Return first chunk in stream order returning True for function `match`.""" for chunk in self._chunks: if match(chunk): return chunk return None -class _ChunkParser(object): - """ - Extracts chunks from a PNG image stream - """ +class _ChunkParser: + """Extracts chunks from a PNG image stream.""" def __init__(self, stream_rdr): super(_ChunkParser, self).__init__() @@ -171,27 +135,23 @@ def __init__(self, stream_rdr): @classmethod def from_stream(cls, stream): - """ - Return a |_ChunkParser| instance that can extract the chunks from the - PNG image in *stream*. - """ + """Return a |_ChunkParser| instance that can extract the chunks from the PNG + image in `stream`.""" stream_rdr = StreamReader(stream, BIG_ENDIAN) return cls(stream_rdr) def iter_chunks(self): - """ - Generate a |_Chunk| subclass instance for each chunk in this parser's - PNG stream, in the order encountered in the stream. - """ + """Generate a |_Chunk| subclass instance for each chunk in this parser's PNG + stream, in the order encountered in the stream.""" for chunk_type, offset in self._iter_chunk_offsets(): chunk = _ChunkFactory(chunk_type, self._stream_rdr, offset) yield chunk def _iter_chunk_offsets(self): - """ - Generate a (chunk_type, chunk_offset) 2-tuple for each of the chunks - in the PNG image stream. Iteration stops after the IEND chunk is - returned. + """Generate a (chunk_type, chunk_offset) 2-tuple for each of the chunks in the + PNG image stream. + + Iteration stops after the IEND chunk is returned. """ chunk_offset = 8 while True: @@ -206,10 +166,8 @@ def _iter_chunk_offsets(self): def _ChunkFactory(chunk_type, stream_rdr, offset): - """ - Return a |_Chunk| subclass instance appropriate to *chunk_type* parsed - from *stream_rdr* at *offset*. - """ + """Return a |_Chunk| subclass instance appropriate to `chunk_type` parsed from + `stream_rdr` at `offset`.""" chunk_cls_map = { PNG_CHUNK_TYPE.IHDR: _IHDRChunk, PNG_CHUNK_TYPE.pHYs: _pHYsChunk, @@ -218,10 +176,10 @@ def _ChunkFactory(chunk_type, stream_rdr, offset): return chunk_cls.from_offset(chunk_type, stream_rdr, offset) -class _Chunk(object): - """ - Base class for specific chunk types. Also serves as the default chunk - type. +class _Chunk: + """Base class for specific chunk types. + + Also serves as the default chunk type. """ def __init__(self, chunk_type): @@ -230,23 +188,17 @@ def __init__(self, chunk_type): @classmethod def from_offset(cls, chunk_type, stream_rdr, offset): - """ - Return a default _Chunk instance that only knows its chunk type. - """ + """Return a default _Chunk instance that only knows its chunk type.""" return cls(chunk_type) @property def type_name(self): - """ - The chunk type name, e.g. 'IHDR', 'pHYs', etc. - """ + """The chunk type name, e.g. 'IHDR', 'pHYs', etc.""" return self._chunk_type class _IHDRChunk(_Chunk): - """ - IHDR chunk, contains the image dimensions - """ + """IHDR chunk, contains the image dimensions.""" def __init__(self, chunk_type, px_width, px_height): super(_IHDRChunk, self).__init__(chunk_type) @@ -255,10 +207,8 @@ def __init__(self, chunk_type, px_width, px_height): @classmethod def from_offset(cls, chunk_type, stream_rdr, offset): - """ - Return an _IHDRChunk instance containing the image dimensions - extracted from the IHDR chunk in *stream* at *offset*. - """ + """Return an _IHDRChunk instance containing the image dimensions extracted from + the IHDR chunk in `stream` at `offset`.""" px_width = stream_rdr.read_long(offset) px_height = stream_rdr.read_long(offset, 4) return cls(chunk_type, px_width, px_height) @@ -273,9 +223,7 @@ def px_height(self): class _pHYsChunk(_Chunk): - """ - pYHs chunk, contains the image dpi information - """ + """PYHs chunk, contains the image dpi information.""" def __init__(self, chunk_type, horz_px_per_unit, vert_px_per_unit, units_specifier): super(_pHYsChunk, self).__init__(chunk_type) @@ -285,10 +233,8 @@ def __init__(self, chunk_type, horz_px_per_unit, vert_px_per_unit, units_specifi @classmethod def from_offset(cls, chunk_type, stream_rdr, offset): - """ - Return a _pHYsChunk instance containing the image resolution - extracted from the pHYs chunk in *stream* at *offset*. - """ + """Return a _pHYsChunk instance containing the image resolution extracted from + the pHYs chunk in `stream` at `offset`.""" horz_px_per_unit = stream_rdr.read_long(offset) vert_px_per_unit = stream_rdr.read_long(offset, 4) units_specifier = stream_rdr.read_byte(offset, 8) diff --git a/docx/image/svg.py b/src/docx/image/svg.py similarity index 100% rename from docx/image/svg.py rename to src/docx/image/svg.py diff --git a/docx/image/tiff.py b/src/docx/image/tiff.py similarity index 52% rename from docx/image/tiff.py rename to src/docx/image/tiff.py index 5b5e8b74..1194929a 100644 --- a/docx/image/tiff.py +++ b/src/docx/image/tiff.py @@ -1,39 +1,29 @@ -# encoding: utf-8 - -from __future__ import absolute_import, division, print_function - from .constants import MIME_TYPE, TIFF_FLD, TIFF_TAG from .helpers import BIG_ENDIAN, LITTLE_ENDIAN, StreamReader from .image import BaseImageHeader class Tiff(BaseImageHeader): - """ - Image header parser for TIFF images. Handles both big and little endian - byte ordering. + """Image header parser for TIFF images. + + Handles both big and little endian byte ordering. """ @property def content_type(self): - """ - Return the MIME type of this TIFF image, unconditionally the string - ``image/tiff``. - """ + """Return the MIME type of this TIFF image, unconditionally the string + ``image/tiff``.""" return MIME_TYPE.TIFF @property def default_ext(self): - """ - Default filename extension, always 'tiff' for TIFF images. - """ + """Default filename extension, always 'tiff' for TIFF images.""" return "tiff" @classmethod def from_stream(cls, stream): - """ - Return a |Tiff| instance containing the properties of the TIFF image - in *stream*. - """ + """Return a |Tiff| instance containing the properties of the TIFF image in + `stream`.""" parser = _TiffParser.parse(stream) px_width = parser.px_width @@ -44,11 +34,9 @@ def from_stream(cls, stream): return cls(px_width, px_height, horz_dpi, vert_dpi) -class _TiffParser(object): - """ - Parses a TIFF image stream to extract the image properties found in its - main image file directory (IFD) - """ +class _TiffParser: + """Parses a TIFF image stream to extract the image properties found in its main + image file directory (IFD)""" def __init__(self, ifd_entries): super(_TiffParser, self).__init__() @@ -56,10 +44,8 @@ def __init__(self, ifd_entries): @classmethod def parse(cls, stream): - """ - Return an instance of |_TiffParser| containing the properties parsed - from the TIFF image in *stream*. - """ + """Return an instance of |_TiffParser| containing the properties parsed from the + TIFF image in `stream`.""" stream_rdr = cls._make_stream_reader(stream) ifd0_offset = stream_rdr.read_long(4) ifd_entries = _IfdEntries.from_stream(stream_rdr, ifd0_offset) @@ -67,55 +53,43 @@ def parse(cls, stream): @property def horz_dpi(self): - """ - The horizontal dots per inch value calculated from the XResolution - and ResolutionUnit tags of the IFD; defaults to 72 if those tags are - not present. - """ + """The horizontal dots per inch value calculated from the XResolution and + ResolutionUnit tags of the IFD; defaults to 72 if those tags are not present.""" return self._dpi(TIFF_TAG.X_RESOLUTION) @property def vert_dpi(self): - """ - The vertical dots per inch value calculated from the XResolution and - ResolutionUnit tags of the IFD; defaults to 72 if those tags are not - present. - """ + """The vertical dots per inch value calculated from the XResolution and + ResolutionUnit tags of the IFD; defaults to 72 if those tags are not present.""" return self._dpi(TIFF_TAG.Y_RESOLUTION) @property def px_height(self): - """ - The number of stacked rows of pixels in the image, |None| if the IFD - contains no ``ImageLength`` tag, the expected case when the TIFF is - embeded in an Exif image. - """ + """The number of stacked rows of pixels in the image, |None| if the IFD contains + no ``ImageLength`` tag, the expected case when the TIFF is embeded in an Exif + image.""" return self._ifd_entries.get(TIFF_TAG.IMAGE_LENGTH) @property def px_width(self): - """ - The number of pixels in each row in the image, |None| if the IFD - contains no ``ImageWidth`` tag, the expected case when the TIFF is - embeded in an Exif image. - """ + """The number of pixels in each row in the image, |None| if the IFD contains no + ``ImageWidth`` tag, the expected case when the TIFF is embeded in an Exif + image.""" return self._ifd_entries.get(TIFF_TAG.IMAGE_WIDTH) @classmethod def _detect_endian(cls, stream): - """ - Return either BIG_ENDIAN or LITTLE_ENDIAN depending on the endian - indicator found in the TIFF *stream* header, either 'MM' or 'II'. - """ + """Return either BIG_ENDIAN or LITTLE_ENDIAN depending on the endian indicator + found in the TIFF `stream` header, either 'MM' or 'II'.""" stream.seek(0) endian_str = stream.read(2) return BIG_ENDIAN if endian_str == b"MM" else LITTLE_ENDIAN def _dpi(self, resolution_tag): - """ - Return the dpi value calculated for *resolution_tag*, which can be - either TIFF_TAG.X_RESOLUTION or TIFF_TAG.Y_RESOLUTION. The - calculation is based on the values of both that tag and the + """Return the dpi value calculated for `resolution_tag`, which can be either + TIFF_TAG.X_RESOLUTION or TIFF_TAG.Y_RESOLUTION. + + The calculation is based on the values of both that tag and the TIFF_TAG.RESOLUTION_UNIT tag in this parser's |_IfdEntries| instance. """ ifd_entries = self._ifd_entries @@ -124,11 +98,7 @@ def _dpi(self, resolution_tag): return 72 # resolution unit defaults to inches (2) - resolution_unit = ( - ifd_entries[TIFF_TAG.RESOLUTION_UNIT] - if TIFF_TAG.RESOLUTION_UNIT in ifd_entries - else 2 - ) + resolution_unit = ifd_entries.get(TIFF_TAG.RESOLUTION_UNIT, 2) if resolution_unit == 1: # aspect ratio only return 72 @@ -139,60 +109,45 @@ def _dpi(self, resolution_tag): @classmethod def _make_stream_reader(cls, stream): - """ - Return a |StreamReader| instance with wrapping *stream* and having - "endian-ness" determined by the 'MM' or 'II' indicator in the TIFF - stream header. - """ + """Return a |StreamReader| instance with wrapping `stream` and having "endian- + ness" determined by the 'MM' or 'II' indicator in the TIFF stream header.""" endian = cls._detect_endian(stream) return StreamReader(stream, endian) -class _IfdEntries(object): - """ - Image File Directory for a TIFF image, having mapping (dict) semantics - allowing "tag" values to be retrieved by tag code. - """ +class _IfdEntries: + """Image File Directory for a TIFF image, having mapping (dict) semantics allowing + "tag" values to be retrieved by tag code.""" def __init__(self, entries): super(_IfdEntries, self).__init__() self._entries = entries def __contains__(self, key): - """ - Provides ``in`` operator, e.g. ``tag in ifd_entries`` - """ + """Provides ``in`` operator, e.g. ``tag in ifd_entries``""" return self._entries.__contains__(key) def __getitem__(self, key): - """ - Provides indexed access, e.g. ``tag_value = ifd_entries[tag_code]`` - """ + """Provides indexed access, e.g. ``tag_value = ifd_entries[tag_code]``""" return self._entries.__getitem__(key) @classmethod def from_stream(cls, stream, offset): - """ - Return a new |_IfdEntries| instance parsed from *stream* starting at - *offset*. - """ + """Return a new |_IfdEntries| instance parsed from `stream` starting at + `offset`.""" ifd_parser = _IfdParser(stream, offset) - entries = dict((e.tag, e.value) for e in ifd_parser.iter_entries()) + entries = {e.tag: e.value for e in ifd_parser.iter_entries()} return cls(entries) def get(self, tag_code, default=None): - """ - Return value of IFD entry having tag matching *tag_code*, or - *default* if no matching tag found. - """ + """Return value of IFD entry having tag matching `tag_code`, or `default` if no + matching tag found.""" return self._entries.get(tag_code, default) -class _IfdParser(object): - """ - Service object that knows how to extract directory entries from an Image - File Directory (IFD) - """ +class _IfdParser: + """Service object that knows how to extract directory entries from an Image File + Directory (IFD)""" def __init__(self, stream_rdr, offset): super(_IfdParser, self).__init__() @@ -200,10 +155,8 @@ def __init__(self, stream_rdr, offset): self._offset = offset def iter_entries(self): - """ - Generate an |_IfdEntry| instance corresponding to each entry in the - directory. - """ + """Generate an |_IfdEntry| instance corresponding to each entry in the + directory.""" for idx in range(self._entry_count): dir_entry_offset = self._offset + 2 + (idx * 12) ifd_entry = _IfdEntryFactory(self._stream_rdr, dir_entry_offset) @@ -211,17 +164,13 @@ def iter_entries(self): @property def _entry_count(self): - """ - The count of directory entries, read from the top of the IFD header - """ + """The count of directory entries, read from the top of the IFD header.""" return self._stream_rdr.read_short(self._offset) def _IfdEntryFactory(stream_rdr, offset): - """ - Return an |_IfdEntry| subclass instance containing the value of the - directory entry at *offset* in *stream_rdr*. - """ + """Return an |_IfdEntry| subclass instance containing the value of the directory + entry at `offset` in `stream_rdr`.""" ifd_entry_classes = { TIFF_FLD.ASCII: _AsciiIfdEntry, TIFF_FLD.SHORT: _ShortIfdEntry, @@ -229,17 +178,14 @@ def _IfdEntryFactory(stream_rdr, offset): TIFF_FLD.RATIONAL: _RationalIfdEntry, } field_type = stream_rdr.read_short(offset, 2) - if field_type in ifd_entry_classes: - entry_cls = ifd_entry_classes[field_type] - else: - entry_cls = _IfdEntry - return entry_cls.from_stream(stream_rdr, offset) + EntryCls = ifd_entry_classes.get(field_type, _IfdEntry) + return EntryCls.from_stream(stream_rdr, offset) -class _IfdEntry(object): - """ - Base class for IFD entry classes. Subclasses are differentiated by value - type, e.g. ASCII, long int, etc. +class _IfdEntry: + """Base class for IFD entry classes. + + Subclasses are differentiated by value type, e.g. ASCII, long int, etc. """ def __init__(self, tag_code, value): @@ -249,11 +195,11 @@ def __init__(self, tag_code, value): @classmethod def from_stream(cls, stream_rdr, offset): - """ - Return an |_IfdEntry| subclass instance containing the tag and value - of the tag parsed from *stream_rdr* at *offset*. Note this method is - common to all subclasses. Override the ``_parse_value()`` method to - provide distinctive behavior based on field type. + """Return an |_IfdEntry| subclass instance containing the tag and value of the + tag parsed from `stream_rdr` at `offset`. + + Note this method is common to all subclasses. Override the ``_parse_value()`` + method to provide distinctive behavior based on field type. """ tag_code = stream_rdr.read_short(offset, 0) value_count = stream_rdr.read_long(offset, 4) @@ -263,52 +209,45 @@ def from_stream(cls, stream_rdr, offset): @classmethod def _parse_value(cls, stream_rdr, offset, value_count, value_offset): - """ - Return the value of this field parsed from *stream_rdr* at *offset*. + """Return the value of this field parsed from `stream_rdr` at `offset`. + Intended to be overridden by subclasses. """ return "UNIMPLEMENTED FIELD TYPE" # pragma: no cover @property def tag(self): - """ - Short int code that identifies this IFD entry - """ + """Short int code that identifies this IFD entry.""" return self._tag_code @property def value(self): - """ - Value of this tag, its type being dependent on the tag. - """ + """Value of this tag, its type being dependent on the tag.""" return self._value class _AsciiIfdEntry(_IfdEntry): - """ - IFD entry having the form of a NULL-terminated ASCII string - """ + """IFD entry having the form of a NULL-terminated ASCII string.""" @classmethod def _parse_value(cls, stream_rdr, offset, value_count, value_offset): - """ - Return the ASCII string parsed from *stream_rdr* at *value_offset*. - The length of the string, including a terminating '\x00' (NUL) - character, is in *value_count*. + """Return the ASCII string parsed from `stream_rdr` at `value_offset`. + + The length of the string, including a terminating '\x00' (NUL) character, is in + `value_count`. """ return stream_rdr.read_str(value_count - 1, value_offset) class _ShortIfdEntry(_IfdEntry): - """ - IFD entry expressed as a short (2-byte) integer - """ + """IFD entry expressed as a short (2-byte) integer.""" @classmethod def _parse_value(cls, stream_rdr, offset, value_count, value_offset): - """ - Return the short int value contained in the *value_offset* field of - this entry. Only supports single values at present. + """Return the short int value contained in the `value_offset` field of this + entry. + + Only supports single values at present. """ if value_count == 1: return stream_rdr.read_short(offset, 8) @@ -317,15 +256,14 @@ def _parse_value(cls, stream_rdr, offset, value_count, value_offset): class _LongIfdEntry(_IfdEntry): - """ - IFD entry expressed as a long (4-byte) integer - """ + """IFD entry expressed as a long (4-byte) integer.""" @classmethod def _parse_value(cls, stream_rdr, offset, value_count, value_offset): - """ - Return the long int value contained in the *value_offset* field of - this entry. Only supports single values at present. + """Return the long int value contained in the `value_offset` field of this + entry. + + Only supports single values at present. """ if value_count == 1: return stream_rdr.read_long(offset, 8) @@ -334,16 +272,14 @@ def _parse_value(cls, stream_rdr, offset, value_count, value_offset): class _RationalIfdEntry(_IfdEntry): - """ - IFD entry expressed as a numerator, denominator pair - """ + """IFD entry expressed as a numerator, denominator pair.""" @classmethod def _parse_value(cls, stream_rdr, offset, value_count, value_offset): - """ - Return the rational (numerator / denominator) value at *value_offset* - in *stream_rdr* as a floating-point number. Only supports single - values at present. + """Return the rational (numerator / denominator) value at `value_offset` in + `stream_rdr` as a floating-point number. + + Only supports single values at present. """ if value_count == 1: numerator = stream_rdr.read_long(value_offset) diff --git a/docx/opc/parts/__init__.py b/src/docx/opc/__init__.py similarity index 100% rename from docx/opc/parts/__init__.py rename to src/docx/opc/__init__.py diff --git a/src/docx/opc/constants.py b/src/docx/opc/constants.py new file mode 100644 index 00000000..9b9a3c05 --- /dev/null +++ b/src/docx/opc/constants.py @@ -0,0 +1,307 @@ +"""Constant values related to the Open Packaging Convention. + +In particular it includes content types and relationship types. +""" + + +class CONTENT_TYPE: + """Content type URIs (like MIME-types) that specify a part's format.""" + + BMP = "image/bmp" + DML_CHART = "application/vnd.openxmlformats-officedocument.drawingml.chart+xml" + DML_CHARTSHAPES = "application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml" + DML_DIAGRAM_COLORS = "application/vnd.openxmlformats-officedocument.drawingml.diagramColors+xml" + DML_DIAGRAM_DATA = "application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml" + DML_DIAGRAM_LAYOUT = "application/vnd.openxmlformats-officedocument.drawingml.diagramLayout+xml" + DML_DIAGRAM_STYLE = "application/vnd.openxmlformats-officedocument.drawingml.diagramStyle+xml" + GIF = "image/gif" + JPEG = "image/jpeg" + MS_PHOTO = "image/vnd.ms-photo" + OFC_CUSTOM_PROPERTIES = "application/vnd.openxmlformats-officedocument.custom-properties+xml" + OFC_CUSTOM_XML_PROPERTIES = ( + "application/vnd.openxmlformats-officedocument.customXmlProperties+xml" + ) + OFC_DRAWING = "application/vnd.openxmlformats-officedocument.drawing+xml" + OFC_EXTENDED_PROPERTIES = ( + "application/vnd.openxmlformats-officedocument.extended-properties+xml" + ) + OFC_OLE_OBJECT = "application/vnd.openxmlformats-officedocument.oleObject" + OFC_PACKAGE = "application/vnd.openxmlformats-officedocument.package" + OFC_THEME = "application/vnd.openxmlformats-officedocument.theme+xml" + OFC_THEME_OVERRIDE = "application/vnd.openxmlformats-officedocument.themeOverride+xml" + OFC_VML_DRAWING = "application/vnd.openxmlformats-officedocument.vmlDrawing" + OPC_CORE_PROPERTIES = "application/vnd.openxmlformats-package.core-properties+xml" + OPC_CUSTOM_PROPERTIES = "application/vnd.openxmlformats-officedocument.custom-properties+xml" + OPC_DIGITAL_SIGNATURE_CERTIFICATE = ( + "application/vnd.openxmlformats-package.digital-signature-certificate" + ) + OPC_DIGITAL_SIGNATURE_ORIGIN = "application/vnd.openxmlformats-package.digital-signature-origin" + OPC_DIGITAL_SIGNATURE_XMLSIGNATURE = ( + "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml" + ) + OPC_RELATIONSHIPS = "application/vnd.openxmlformats-package.relationships+xml" + PML_COMMENTS = "application/vnd.openxmlformats-officedocument.presentationml.comments+xml" + PML_COMMENT_AUTHORS = ( + "application/vnd.openxmlformats-officedocument.presentationml.commentAuthors+xml" + ) + PML_HANDOUT_MASTER = ( + "application/vnd.openxmlformats-officedocument.presentationml.handoutMaster+xml" + ) + PML_NOTES_MASTER = ( + "application/vnd.openxmlformats-officedocument.presentationml.notesMaster+xml" + ) + PML_NOTES_SLIDE = "application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml" + PML_PRESENTATION_MAIN = ( + "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml" + ) + PML_PRES_PROPS = "application/vnd.openxmlformats-officedocument.presentationml.presProps+xml" + PML_PRINTER_SETTINGS = ( + "application/vnd.openxmlformats-officedocument.presentationml.printerSettings" + ) + PML_SLIDE = "application/vnd.openxmlformats-officedocument.presentationml.slide+xml" + PML_SLIDESHOW_MAIN = ( + "application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml" + ) + PML_SLIDE_LAYOUT = ( + "application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml" + ) + PML_SLIDE_MASTER = ( + "application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml" + ) + PML_SLIDE_UPDATE_INFO = ( + "application/vnd.openxmlformats-officedocument.presentationml.slideUpdateInfo+xml" + ) + PML_TABLE_STYLES = ( + "application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml" + ) + PML_TAGS = "application/vnd.openxmlformats-officedocument.presentationml.tags+xml" + PML_TEMPLATE_MAIN = ( + "application/vnd.openxmlformats-officedocument.presentationml.template.main+xml" + ) + PML_VIEW_PROPS = "application/vnd.openxmlformats-officedocument.presentationml.viewProps+xml" + PNG = "image/png" + SML_CALC_CHAIN = "application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml" + SML_CHARTSHEET = "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml" + SML_COMMENTS = "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml" + SML_CONNECTIONS = "application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml" + SML_CUSTOM_PROPERTY = ( + "application/vnd.openxmlformats-officedocument.spreadsheetml.customProperty" + ) + SML_DIALOGSHEET = "application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml" + SML_EXTERNAL_LINK = ( + "application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml" + ) + SML_PIVOT_CACHE_DEFINITION = ( + "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml" + ) + SML_PIVOT_CACHE_RECORDS = ( + "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheRecords+xml" + ) + SML_PIVOT_TABLE = "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml" + SML_PRINTER_SETTINGS = ( + "application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings" + ) + SML_QUERY_TABLE = "application/vnd.openxmlformats-officedocument.spreadsheetml.queryTable+xml" + SML_REVISION_HEADERS = ( + "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionHeaders+xml" + ) + SML_REVISION_LOG = "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionLog+xml" + SML_SHARED_STRINGS = ( + "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml" + ) + SML_SHEET = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" + SML_SHEET_MAIN = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" + SML_SHEET_METADATA = ( + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml" + ) + SML_STYLES = "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml" + SML_TABLE = "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml" + SML_TABLE_SINGLE_CELLS = ( + "application/vnd.openxmlformats-officedocument.spreadsheetml.tableSingleCells+xml" + ) + SML_TEMPLATE_MAIN = ( + "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml" + ) + SML_USER_NAMES = "application/vnd.openxmlformats-officedocument.spreadsheetml.userNames+xml" + SML_VOLATILE_DEPENDENCIES = ( + "application/vnd.openxmlformats-officedocument.spreadsheetml.volatileDependencies+xml" + ) + SML_WORKSHEET = "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" + TIFF = "image/tiff" + WML_COMMENTS = "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml" + WML_DOCUMENT = "application/vnd.openxmlformats-officedocument.wordprocessingml.document" + WML_DOCUMENT_GLOSSARY = ( + "application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml" + ) + WML_DOCUMENT_MAIN = ( + "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml" + ) + WML_ENDNOTES = "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml" + WML_FONT_TABLE = "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml" + WML_FOOTER = "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml" + WML_FOOTNOTES = "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml" + WML_HEADER = "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml" + WML_NUMBERING = "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml" + WML_PRINTER_SETTINGS = ( + "application/vnd.openxmlformats-officedocument.wordprocessingml.printerSettings" + ) + WML_SETTINGS = "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml" + WML_STYLES = "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml" + WML_WEB_SETTINGS = ( + "application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml" + ) + XML = "application/xml" + X_EMF = "image/x-emf" + X_FONTDATA = "application/x-fontdata" + X_FONT_TTF = "application/x-font-ttf" + X_WMF = "image/x-wmf" + + +class NAMESPACE: + """Constant values for OPC XML namespaces.""" + + DML_WORDPROCESSING_DRAWING = ( + "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" + ) + OFC_RELATIONSHIPS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + OPC_RELATIONSHIPS = "http://schemas.openxmlformats.org/package/2006/relationships" + OPC_CONTENT_TYPES = "http://schemas.openxmlformats.org/package/2006/content-types" + WML_MAIN = "http://schemas.openxmlformats.org/wordprocessingml/2006/main" + + +class RELATIONSHIP_TARGET_MODE: + """Open XML relationship target modes.""" + + EXTERNAL = "External" + INTERNAL = "Internal" + + +class RELATIONSHIP_TYPE: + AUDIO = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/audio" + A_F_CHUNK = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/aFChunk" + CALC_CHAIN = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/calcChain" + CERTIFICATE = ( + "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/certificate" + ) + CHART = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart" + CHARTSHEET = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartsheet" + CHART_USER_SHAPES = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartUserShapes" + ) + COMMENTS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments" + COMMENT_AUTHORS = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/commentAuthors" + ) + CONNECTIONS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/connections" + CONTROL = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/control" + CORE_PROPERTIES = ( + "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" + ) + CUSTOM_PROPERTIES = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties" + ) + CUSTOM_PROPERTY = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customProperty" + ) + CUSTOM_XML = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml" + CUSTOM_XML_PROPS = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps" + ) + DIAGRAM_COLORS = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramColors" + ) + DIAGRAM_DATA = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramData" + DIAGRAM_LAYOUT = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramLayout" + ) + DIAGRAM_QUICK_STYLE = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/diagramQuickStyle" + ) + DIALOGSHEET = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/dialogsheet" + DRAWING = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing" + ENDNOTES = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes" + EXTENDED_PROPERTIES = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" + ) + EXTERNAL_LINK = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLink" + ) + FONT = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/font" + FONT_TABLE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" + FOOTER = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer" + FOOTNOTES = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" + GLOSSARY_DOCUMENT = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/glossaryDocument" + ) + HANDOUT_MASTER = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/handoutMaster" + ) + HEADER = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" + HYPERLINK = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" + IMAGE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" + NOTES_MASTER = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesMaster" + NOTES_SLIDE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide" + NUMBERING = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering" + OFFICE_DOCUMENT = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" + ) + OLE_OBJECT = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject" + ORIGIN = "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin" + PACKAGE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package" + PIVOT_CACHE_DEFINITION = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheDefinition" + ) + PIVOT_CACHE_RECORDS = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships" + "/spreadsheetml/pivotCacheRecords" + ) + PIVOT_TABLE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable" + PRES_PROPS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/presProps" + PRINTER_SETTINGS = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/printerSettings" + ) + QUERY_TABLE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/queryTable" + REVISION_HEADERS = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/revisionHeaders" + ) + REVISION_LOG = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/revisionLog" + SETTINGS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" + SHARED_STRINGS = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" + ) + SHEET_METADATA = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata" + ) + SIGNATURE = ( + "http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/signature" + ) + SLIDE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide" + SLIDE_LAYOUT = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout" + SLIDE_MASTER = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster" + SLIDE_UPDATE_INFO = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideUpdateInfo" + ) + STYLES = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" + TABLE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table" + TABLE_SINGLE_CELLS = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/tableSingleCells" + ) + TABLE_STYLES = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/tableStyles" + TAGS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/tags" + THEME = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" + THEME_OVERRIDE = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/themeOverride" + ) + THUMBNAIL = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail" + USERNAMES = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/usernames" + VIDEO = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/video" + VIEW_PROPS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/viewProps" + VML_DRAWING = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing" + VOLATILE_DEPENDENCIES = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/volatileDependencies" + ) + WEB_SETTINGS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings" + WORKSHEET_SOURCE = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheetSource" + ) + XML_MAPS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/xmlMaps" diff --git a/docx/opc/coreprops.py b/src/docx/opc/coreprops.py similarity index 67% rename from docx/opc/coreprops.py rename to src/docx/opc/coreprops.py index 02204dc0..62f0c5ab 100644 --- a/docx/opc/coreprops.py +++ b/src/docx/opc/coreprops.py @@ -1,16 +1,24 @@ +"""Provides CoreProperties, Dublin-Core attributes of the document. + +These are broadly-standardized attributes like author, last-modified, etc. """ -The :mod:`pptx.packaging` module coheres around the concerns of reading and -writing presentations to and from a .pptx file. -""" + +from __future__ import annotations + +import datetime as dt +from typing import TYPE_CHECKING + +from docx.oxml.coreprops import CT_CoreProperties + +if TYPE_CHECKING: + from docx.oxml.coreprops import CT_CoreProperties -class CoreProperties(object): - """ - Corresponds to part named ``/docProps/core.xml``, containing the core - document properties for this document package. - """ +class CoreProperties: + """Corresponds to part named ``/docProps/core.xml``, containing the core document + properties for this document package.""" - def __init__(self, element): + def __init__(self, element: CT_CoreProperties): self._element = element @property @@ -18,7 +26,7 @@ def author(self): return self._element.author_text @author.setter - def author(self, value): + def author(self, value: str): self._element.author_text = value @property @@ -26,7 +34,7 @@ def category(self): return self._element.category_text @category.setter - def category(self, value): + def category(self, value: str): self._element.category_text = value @property @@ -34,7 +42,7 @@ def comments(self): return self._element.comments_text @comments.setter - def comments(self, value): + def comments(self, value: str): self._element.comments_text = value @property @@ -42,7 +50,7 @@ def content_status(self): return self._element.contentStatus_text @content_status.setter - def content_status(self, value): + def content_status(self, value: str): self._element.contentStatus_text = value @property @@ -50,7 +58,7 @@ def created(self): return self._element.created_datetime @created.setter - def created(self, value): + def created(self, value: dt.datetime): self._element.created_datetime = value @property @@ -58,7 +66,7 @@ def identifier(self): return self._element.identifier_text @identifier.setter - def identifier(self, value): + def identifier(self, value: str): self._element.identifier_text = value @property @@ -66,7 +74,7 @@ def keywords(self): return self._element.keywords_text @keywords.setter - def keywords(self, value): + def keywords(self, value: str): self._element.keywords_text = value @property @@ -74,7 +82,7 @@ def language(self): return self._element.language_text @language.setter - def language(self, value): + def language(self, value: str): self._element.language_text = value @property @@ -82,7 +90,7 @@ def last_modified_by(self): return self._element.lastModifiedBy_text @last_modified_by.setter - def last_modified_by(self, value): + def last_modified_by(self, value: str): self._element.lastModifiedBy_text = value @property @@ -90,7 +98,7 @@ def last_printed(self): return self._element.lastPrinted_datetime @last_printed.setter - def last_printed(self, value): + def last_printed(self, value: dt.datetime): self._element.lastPrinted_datetime = value @property @@ -98,7 +106,7 @@ def modified(self): return self._element.modified_datetime @modified.setter - def modified(self, value): + def modified(self, value: dt.datetime): self._element.modified_datetime = value @property @@ -106,7 +114,7 @@ def revision(self): return self._element.revision_number @revision.setter - def revision(self, value): + def revision(self, value: int): self._element.revision_number = value @property @@ -114,7 +122,7 @@ def subject(self): return self._element.subject_text @subject.setter - def subject(self, value): + def subject(self, value: str): self._element.subject_text = value @property @@ -122,7 +130,7 @@ def title(self): return self._element.title_text @title.setter - def title(self, value): + def title(self, value: str): self._element.title_text = value @property @@ -130,5 +138,5 @@ def version(self): return self._element.version_text @version.setter - def version(self, value): + def version(self, value: str): self._element.version_text = value diff --git a/docx/opc/customprops.py b/src/docx/opc/customprops.py similarity index 100% rename from docx/opc/customprops.py rename to src/docx/opc/customprops.py diff --git a/src/docx/opc/exceptions.py b/src/docx/opc/exceptions.py new file mode 100644 index 00000000..c5583d30 --- /dev/null +++ b/src/docx/opc/exceptions.py @@ -0,0 +1,12 @@ +"""Exceptions specific to python-opc. + +The base exception class is OpcError. +""" + + +class OpcError(Exception): + """Base error class for python-opc.""" + + +class PackageNotFoundError(OpcError): + """Raised when a package cannot be found at the specified path.""" diff --git a/docx/opc/oxml.py b/src/docx/opc/oxml.py similarity index 50% rename from docx/opc/oxml.py rename to src/docx/opc/oxml.py index 432dcf9f..7d3c489d 100644 --- a/docx/opc/oxml.py +++ b/src/docx/opc/oxml.py @@ -1,18 +1,20 @@ -# encoding: utf-8 +# pyright: reportPrivateUsage=false -""" -Temporary stand-in for main oxml module that came across with the -PackageReader transplant. Probably much will get replaced with objects from -the pptx.oxml.core and then this module will either get deleted or only hold -the package related custom element classes. +"""Temporary stand-in for main oxml module. + +This module came across with the PackageReader transplant. Probably much will get +replaced with objects from the pptx.oxml.core and then this module will either get +deleted or only hold the package related custom element classes. """ -from __future__ import absolute_import, print_function, unicode_literals +from __future__ import annotations -from lxml import etree +from typing import cast -from .constants import NAMESPACE as NS, RELATIONSHIP_TARGET_MODE as RTM +from lxml import etree +from docx.opc.constants import NAMESPACE as NS +from docx.opc.constants import RELATIONSHIP_TARGET_MODE as RTM # configure XML parser element_class_lookup = etree.ElementNamespaceClassLookup() @@ -31,17 +33,16 @@ # =========================================================================== -def parse_xml(text): - """ - ``etree.fromstring()`` replacement that uses oxml parser - """ +def parse_xml(text: str) -> etree._Element: + """`etree.fromstring()` replacement that uses oxml parser.""" return etree.fromstring(text, oxml_parser) -def qn(tag): - """ - Stands for "qualified name", a utility function to turn a namespace - prefixed tag name into a Clark-notation qualified tag name for lxml. For +def qn(tag: str) -> str: + """Stands for "qualified name", a utility function to turn a namespace prefixed tag + name into a Clark-notation qualified tag name for lxml. + + For example, ``qn('p:cSld')`` returns ``'{http://schemas.../main}cSld'``. """ prefix, tagroot = tag.split(":") @@ -49,19 +50,19 @@ def qn(tag): return "{%s}%s" % (uri, tagroot) -def serialize_part_xml(part_elm): - """ - Serialize *part_elm* etree element to XML suitable for storage as an XML - part. That is to say, no insignificant whitespace added for readability, - and an appropriate XML declaration added with UTF-8 encoding specified. +def serialize_part_xml(part_elm: etree._Element) -> bytes: + """Serialize `part_elm` etree element to XML suitable for storage as an XML part. + + That is to say, no insignificant whitespace added for readability, and an + appropriate XML declaration added with UTF-8 encoding specified. """ return etree.tostring(part_elm, encoding="UTF-8", standalone=True) -def serialize_for_reading(element): - """ - Serialize *element* to human-readable XML suitable for tests. No XML - declaration. +def serialize_for_reading(element: etree._Element) -> str: + """Serialize `element` to human-readable XML suitable for tests. + + No XML declaration. """ return etree.tostring(element, encoding="unicode", pretty_print=True) @@ -72,49 +73,38 @@ def serialize_for_reading(element): class BaseOxmlElement(etree.ElementBase): - """ - Base class for all custom element classes, to add standardized behavior - to all classes in one place. - """ + """Base class for all custom element classes, to add standardized behavior to all + classes in one place.""" @property - def xml(self): - """ - Return XML string for this element, suitable for testing purposes. - Pretty printed for readability and without an XML declaration at the - top. + def xml(self) -> str: + """Return XML string for this element, suitable for testing purposes. + + Pretty printed for readability and without an XML declaration at the top. """ return serialize_for_reading(self) class CT_Default(BaseOxmlElement): - """ - ```` element, specifying the default content type to be applied - to a part with the specified extension. + """`` element that appears in `[Content_Types].xml` part. + + Used to specify a default content type to be applied to any part with the specified extension. """ @property def content_type(self): - """ - String held in the ``ContentType`` attribute of this ```` - element. - """ + """String held in the ``ContentType`` attribute of this ```` + element.""" return self.get("ContentType") @property def extension(self): - """ - String held in the ``Extension`` attribute of this ```` - element. - """ + """String held in the ``Extension`` attribute of this ```` element.""" return self.get("Extension") @staticmethod - def new(ext, content_type): - """ - Return a new ```` element with attributes set to parameter - values. - """ + def new(ext: str, content_type: str): + """Return a new ```` element with attributes set to parameter values.""" xml = '' % nsmap["ct"] default = parse_xml(xml) default.set("Extension", ext) @@ -123,25 +113,18 @@ def new(ext, content_type): class CT_Override(BaseOxmlElement): - """ - ```` element, specifying the content type to be applied for a - part with the specified partname. - """ + """```` element, specifying the content type to be applied for a part with + the specified partname.""" @property def content_type(self): - """ - String held in the ``ContentType`` attribute of this ```` - element. - """ + """String held in the ``ContentType`` attribute of this ```` + element.""" return self.get("ContentType") @staticmethod def new(partname, content_type): - """ - Return a new ```` element with attributes set to parameter - values. - """ + """Return a new ```` element with attributes set to parameter values.""" xml = '' % nsmap["ct"] override = parse_xml(xml) override.set("PartName", partname) @@ -150,24 +133,16 @@ def new(partname, content_type): @property def partname(self): - """ - String held in the ``PartName`` attribute of this ```` - element. - """ + """String held in the ``PartName`` attribute of this ```` element.""" return self.get("PartName") class CT_Relationship(BaseOxmlElement): - """ - ```` element, representing a single relationship from a - source to a target part. - """ + """`` element, representing a single relationship from source to target part.""" @staticmethod - def new(rId, reltype, target, target_mode=RTM.INTERNAL): - """ - Return a new ```` element. - """ + def new(rId: str, reltype: str, target: str, target_mode: str = RTM.INTERNAL): + """Return a new ```` element.""" xml = '' % nsmap["pr"] relationship = parse_xml(xml) relationship.set("Id", rId) @@ -179,96 +154,70 @@ def new(rId, reltype, target, target_mode=RTM.INTERNAL): @property def rId(self): - """ - String held in the ``Id`` attribute of this ```` - element. - """ + """String held in the ``Id`` attribute of this ```` element.""" return self.get("Id") @property def reltype(self): - """ - String held in the ``Type`` attribute of this ```` - element. - """ + """String held in the ``Type`` attribute of this ```` element.""" return self.get("Type") @property def target_ref(self): - """ - String held in the ``Target`` attribute of this ```` - element. - """ + """String held in the ``Target`` attribute of this ```` + element.""" return self.get("Target") @property def target_mode(self): - """ - String held in the ``TargetMode`` attribute of this - ```` element, either ``Internal`` or ``External``. + """String held in the ``TargetMode`` attribute of this ```` + element, either ``Internal`` or ``External``. + Defaults to ``Internal``. """ return self.get("TargetMode", RTM.INTERNAL) class CT_Relationships(BaseOxmlElement): - """ - ```` element, the root element in a .rels file. - """ + """```` element, the root element in a .rels file.""" - def add_rel(self, rId, reltype, target, is_external=False): - """ - Add a child ```` element with attributes set according - to parameter values. - """ + def add_rel(self, rId: str, reltype: str, target: str, is_external: bool = False): + """Add a child ```` element with attributes set according to + parameter values.""" target_mode = RTM.EXTERNAL if is_external else RTM.INTERNAL relationship = CT_Relationship.new(rId, reltype, target, target_mode) self.append(relationship) @staticmethod - def new(): - """ - Return a new ```` element. - """ + def new() -> CT_Relationships: + """Return a new ```` element.""" xml = '' % nsmap["pr"] - relationships = parse_xml(xml) - return relationships + return cast(CT_Relationships, parse_xml(xml)) @property def Relationship_lst(self): - """ - Return a list containing all the ```` child elements. - """ + """Return a list containing all the ```` child elements.""" return self.findall(qn("pr:Relationship")) @property def xml(self): - """ - Return XML string for this element, suitable for saving in a .rels - stream, not pretty printed and with an XML declaration at the top. - """ + """Return XML string for this element, suitable for saving in a .rels stream, + not pretty printed and with an XML declaration at the top.""" return serialize_part_xml(self) class CT_Types(BaseOxmlElement): - """ - ```` element, the container element for Default and Override - elements in [Content_Types].xml. - """ + """```` element, the container element for Default and Override elements in + [Content_Types].xml.""" def add_default(self, ext, content_type): - """ - Add a child ```` element with attributes set to parameter - values. - """ + """Add a child ```` element with attributes set to parameter values.""" default = CT_Default.new(ext, content_type) self.append(default) def add_override(self, partname, content_type): - """ - Add a child ```` element with attributes set to parameter - values. - """ + """Add a child ```` element with attributes set to parameter + values.""" override = CT_Override.new(partname, content_type) self.append(override) @@ -278,9 +227,7 @@ def defaults(self): @staticmethod def new(): - """ - Return a new ```` element. - """ + """Return a new ```` element.""" xml = '' % nsmap["ct"] types = parse_xml(xml) return types diff --git a/docx/opc/package.py b/src/docx/opc/package.py similarity index 51% rename from docx/opc/package.py rename to src/docx/opc/package.py index 49c9d810..5092c6b4 100644 --- a/docx/opc/package.py +++ b/src/docx/opc/package.py @@ -1,59 +1,63 @@ """Objects that implement reading and writing OPC packages.""" -from typing import Callable + +from __future__ import annotations + +from typing import IO, TYPE_CHECKING, Callable, Iterator, cast from docx.opc.constants import RELATIONSHIP_TYPE as RT from docx.opc.packuri import PACKAGE_URI, PackURI -from docx.opc.part import Part, PartFactory +from docx.opc.part import PartFactory from docx.opc.parts.coreprops import CorePropertiesPart from docx.opc.parts.customprops import CustomPropertiesPart from docx.opc.pkgreader import PackageReader from docx.opc.pkgwriter import PackageWriter from docx.opc.rel import Relationships, _Relationship -from docx.opc.shared import lazyproperty +from docx.shared import lazyproperty + +if TYPE_CHECKING: + from typing_extensions import Self + from docx.opc.coreprops import CoreProperties + from docx.opc.customprops import CustomProperties + from docx.opc.part import Part + from docx.opc.rel import _Relationship # pyright: ignore[reportPrivateUsage] -class OpcPackage(object): + +class OpcPackage: """Main API class for |python-opc|. A new instance is constructed by calling the :meth:`open` class method with a path to a package file or file-like object containing one. """ - def __init__(self): - super(OpcPackage, self).__init__() - def after_unmarshal(self): - """ - Entry point for any post-unmarshaling processing. May be overridden - by subclasses without forwarding call to super. + """Entry point for any post-unmarshaling processing. + + May be overridden by subclasses without forwarding call to super. """ # don't place any code here, just catch call if not overridden by # subclass pass @property - def core_properties(self): - """ - |CoreProperties| object providing read/write access to the Dublin - Core properties for this document. - """ + def core_properties(self) -> CoreProperties: + """|CoreProperties| object providing read/write access to the Dublin Core + properties for this document.""" return self._core_properties_part.core_properties @property - def custom_properties(self): - """ - |CustomProperties| object providing read/write access to the Dublin - Core properties for this document. - """ + def custom_properties(self) -> CustomProperties: + """|CustomProperties| object providing read/write access to the custom + properties for this document.""" return self._custom_properties_part.custom_properties - def iter_rels(self): - """ - Generate exactly one reference to each relationship in the package by - performing a depth-first traversal of the rels graph. - """ + def iter_rels(self) -> Iterator[_Relationship]: + """Generate exactly one reference to each relationship in the package by + performing a depth-first traversal of the rels graph.""" - def walk_rels(source, visited=None): + def walk_rels( + source: OpcPackage | Part, visited: list[Part] | None = None + ) -> Iterator[_Relationship]: visited = [] if visited is None else visited for rel in source.rels.values(): yield rel @@ -70,13 +74,11 @@ def walk_rels(source, visited=None): for rel in walk_rels(self): yield rel - def iter_parts(self): - """ - Generate exactly one reference to each of the parts in the package by - performing a depth-first traversal of the rels graph. - """ + def iter_parts(self) -> Iterator[Part]: + """Generate exactly one reference to each of the parts in the package by + performing a depth-first traversal of the rels graph.""" - def walk_parts(source, visited=list()): + def walk_parts(source, visited=[]): for rel in source.rels.values(): if rel.is_external: continue @@ -92,32 +94,31 @@ def walk_parts(source, visited=list()): for part in walk_parts(self): yield part - def load_rel(self, reltype, target, rId, is_external=False): - """ - Return newly added |_Relationship| instance of *reltype* between this - part and *target* with key *rId*. Target mode is set to - ``RTM.EXTERNAL`` if *is_external* is |True|. Intended for use during - load from a serialized package, where the rId is well known. Other - methods exist for adding a new relationship to the package during - processing. + def load_rel(self, reltype: str, target: Part | str, rId: str, is_external: bool = False): + """Return newly added |_Relationship| instance of `reltype` between this part + and `target` with key `rId`. + + Target mode is set to ``RTM.EXTERNAL`` if `is_external` is |True|. Intended for + use during load from a serialized package, where the rId is well known. Other + methods exist for adding a new relationship to the package during processing. """ return self.rels.add_relationship(reltype, target, rId, is_external) @property def main_document_part(self): - """ - Return a reference to the main document part for this package. - Examples include a document part for a WordprocessingML package, a - presentation part for a PresentationML package, or a workbook part - for a SpreadsheetML package. + """Return a reference to the main document part for this package. + + Examples include a document part for a WordprocessingML package, a presentation + part for a PresentationML package, or a workbook part for a SpreadsheetML + package. """ return self.part_related_by(RT.OFFICE_DOCUMENT) - def next_partname(self, template): - """Return a |PackURI| instance representing partname matching *template*. + def next_partname(self, template: str) -> PackURI: + """Return a |PackURI| instance representing partname matching `template`. The returned part-name has the next available numeric suffix to distinguish it - from other parts of its type. *template* is a printf (%)-style template string + from other parts of its type. `template` is a printf (%)-style template string containing a single replacement item, a '%d' to be used to insert the integer portion of the partname. Example: "/word/header%d.xml" """ @@ -128,106 +129,100 @@ def next_partname(self, template): return PackURI(candidate_partname) @classmethod - def open(cls, pkg_file): - """ - Return an |OpcPackage| instance loaded with the contents of - *pkg_file*. - """ + def open(cls, pkg_file: str | IO[bytes]) -> Self: + """Return an |OpcPackage| instance loaded with the contents of `pkg_file`.""" pkg_reader = PackageReader.from_file(pkg_file) package = cls() Unmarshaller.unmarshal(pkg_reader, package, PartFactory) return package - def part_related_by(self, reltype): - """ - Return part to which this package has a relationship of *reltype*. - Raises |KeyError| if no such relationship is found and |ValueError| - if more than one such relationship is found. + def part_related_by(self, reltype: str) -> Part: + """Return part to which this package has a relationship of `reltype`. + + Raises |KeyError| if no such relationship is found and |ValueError| if more than + one such relationship is found. """ return self.rels.part_with_reltype(reltype) - @lazyproperty + @property def parts(self) -> list[Part]: - """ - Return a list containing a reference to each of the parts in this - package. - """ + """Return a list containing a reference to each of the parts in this package.""" return list(self.iter_parts()) - def relate_to(self, part, reltype): - """ - Return rId key of relationship to *part*, from the existing - relationship if there is one, otherwise a newly created one. + def relate_to(self, part: Part, reltype: str): + """Return rId key of new or existing relationship to `part`. + + If a relationship of `reltype` to `part` already exists, its rId is returned. Otherwise a + new relationship is created and that rId is returned. """ rel = self.rels.get_or_add(reltype, part) return rel.rId - @lazyproperty + @property def rels(self) -> Relationships: - """ - Return a reference to the |Relationships| instance holding the - collection of relationships for this package. - """ - return Relationships(PACKAGE_URI.baseURI) + """Return a reference to the |Relationships| instance holding the collection of + relationships for this package.""" + if not hasattr(self, "_rels"): + self._rels = Relationships(PACKAGE_URI.baseURI) + return self._rels @rels.setter def rels(self, new_rels: Relationships): + """Set the relationships collection for this package.""" self._rels = new_rels def drop_rels(self, cmp: Callable[[_Relationship], bool]) -> list[str]: - """ - Drop _Relationship by cmp function, related parts will be ignored when save. - """ + """Drop _Relationship by cmp function, related parts will be ignored when save.""" rids = [rid for rid, rel in self.rels.items() if cmp(rel)] for rid in rids: del self.rels[rid] return rids - def save(self, pkg_file): - """ - Save this package to *pkg_file*, where *file* can be either a path to - a file (a string) or a file-like object. + def save(self, pkg_file: str | IO[bytes]): + """Save this package to `pkg_file`. + + `pkg_file` can be either a file-path or a file-like object. """ for part in self.parts: part.before_marshal() PackageWriter.write(pkg_file, self.rels, self.parts) @property - def _core_properties_part(self): - """ - |CorePropertiesPart| object related to this package. Creates - a default core properties part if one is not present (not common). + def _core_properties_part(self) -> CorePropertiesPart: + """|CorePropertiesPart| object related to this package. + + Creates a default core properties part if one is not present (not common). """ try: - return self.part_related_by(RT.CORE_PROPERTIES) + return cast(CorePropertiesPart, self.part_related_by(RT.CORE_PROPERTIES)) except KeyError: core_properties_part = CorePropertiesPart.default(self) self.relate_to(core_properties_part, RT.CORE_PROPERTIES) return core_properties_part @property - def _custom_properties_part(self): - """ - |CustomPropertiesPart| object related to this package. Creates - a default custom properties part if one is not present (not common). + def _custom_properties_part(self) -> CustomPropertiesPart: + """|CustomPropertiesPart| object related to this package. + + Creates a default custom properties part if one is not present. """ try: - return self.part_related_by(RT.CUSTOM_PROPERTIES) + return cast(CustomPropertiesPart, self.part_related_by(RT.CUSTOM_PROPERTIES)) except KeyError: custom_properties_part = CustomPropertiesPart.default(self) self.relate_to(custom_properties_part, RT.CUSTOM_PROPERTIES) return custom_properties_part -class Unmarshaller(object): +class Unmarshaller: """Hosts static methods for unmarshalling a package from a |PackageReader|.""" @staticmethod def unmarshal(pkg_reader, package, part_factory): - """ - Construct graph of parts and realized relationships based on the - contents of *pkg_reader*, delegating construction of each part to - *part_factory*. Package relationships are added to *pkg*. + """Construct graph of parts and realized relationships based on the contents of + `pkg_reader`, delegating construction of each part to `part_factory`. + + Package relationships are added to `pkg`. """ parts = Unmarshaller._unmarshal_parts(pkg_reader, package, part_factory) Unmarshaller._unmarshal_relationships(pkg_reader, package, parts) @@ -237,28 +232,23 @@ def unmarshal(pkg_reader, package, part_factory): @staticmethod def _unmarshal_parts(pkg_reader, package, part_factory): - """ - Return a dictionary of |Part| instances unmarshalled from - *pkg_reader*, keyed by partname. Side-effect is that each part in - *pkg_reader* is constructed using *part_factory*. + """Return a dictionary of |Part| instances unmarshalled from `pkg_reader`, keyed + by partname. + + Side-effect is that each part in `pkg_reader` is constructed using + `part_factory`. """ parts = {} for partname, content_type, reltype, blob in pkg_reader.iter_sparts(): - parts[partname] = part_factory( - partname, content_type, reltype, blob, package - ) + parts[partname] = part_factory(partname, content_type, reltype, blob, package) return parts @staticmethod def _unmarshal_relationships(pkg_reader, package, parts): - """ - Add a relationship to the source object corresponding to each of the - relationships in *pkg_reader* with its target_part set to the actual - target part in *parts*. - """ + """Add a relationship to the source object corresponding to each of the + relationships in `pkg_reader` with its target_part set to the actual target part + in `parts`.""" for source_uri, srel in pkg_reader.iter_srels(): source = package if source_uri == "/" else parts[source_uri] - target = ( - srel.target_ref if srel.is_external else parts[srel.target_partname] - ) + target = srel.target_ref if srel.is_external else parts[srel.target_partname] source.load_rel(srel.reltype, target, srel.rId, srel.is_external) diff --git a/src/docx/opc/packuri.py b/src/docx/opc/packuri.py new file mode 100644 index 00000000..89437b16 --- /dev/null +++ b/src/docx/opc/packuri.py @@ -0,0 +1,109 @@ +"""Provides the PackURI value type. + +Also some useful known pack URI strings such as PACKAGE_URI. +""" + +from __future__ import annotations + +import posixpath +import re + + +class PackURI(str): + """Provides access to pack URI components such as the baseURI and the filename slice. + + Behaves as |str| otherwise. + """ + + _filename_re = re.compile("([a-zA-Z]+)([1-9][0-9]*)?") + + def __new__(cls, pack_uri_str: str): + if pack_uri_str[0] != "/": + tmpl = "PackURI must begin with slash, got '%s'" + raise ValueError(tmpl % pack_uri_str) + return str.__new__(cls, pack_uri_str) + + @staticmethod + def from_rel_ref(baseURI: str, relative_ref: str) -> PackURI: + """The absolute PackURI formed by translating `relative_ref` onto `baseURI`.""" + joined_uri = posixpath.join(baseURI, relative_ref) + abs_uri = posixpath.abspath(joined_uri) + return PackURI(abs_uri) + + @property + def baseURI(self) -> str: + """The base URI of this pack URI, the directory portion, roughly speaking. + + E.g. ``'/ppt/slides'`` for ``'/ppt/slides/slide1.xml'``. For the package pseudo- + partname '/', baseURI is '/'. + """ + return posixpath.split(self)[0] + + @property + def ext(self) -> str: + """The extension portion of this pack URI, e.g. ``'xml'`` for ``'/word/document.xml'``. + + Note the period is not included. + """ + # raw_ext is either empty string or starts with period, e.g. '.xml' + raw_ext = posixpath.splitext(self)[1] + return raw_ext[1:] if raw_ext.startswith(".") else raw_ext + + @property + def filename(self): + """The "filename" portion of this pack URI, e.g. ``'slide1.xml'`` for + ``'/ppt/slides/slide1.xml'``. + + For the package pseudo-partname '/', filename is ''. + """ + return posixpath.split(self)[1] + + @property + def idx(self): + """Return partname index as integer for tuple partname or None for singleton + partname, e.g. ``21`` for ``'/ppt/slides/slide21.xml'`` and |None| for + ``'/ppt/presentation.xml'``.""" + filename = self.filename + if not filename: + return None + name_part = posixpath.splitext(filename)[0] # filename w/ext removed + match = self._filename_re.match(name_part) + if match is None: + return None + if match.group(2): + return int(match.group(2)) + return None + + @property + def membername(self): + """The pack URI with the leading slash stripped off, the form used as the Zip + file membername for the package item. + + Returns '' for the package pseudo-partname '/'. + """ + return self[1:] + + def relative_ref(self, baseURI: str): + """Return string containing relative reference to package item from `baseURI`. + + E.g. PackURI('/ppt/slideLayouts/slideLayout1.xml') would return + '../slideLayouts/slideLayout1.xml' for baseURI '/ppt/slides'. + """ + # workaround for posixpath bug in 2.6, doesn't generate correct + # relative path when `start` (second) parameter is root ('/') + return self[1:] if baseURI == "/" else posixpath.relpath(self, baseURI) + + @property + def rels_uri(self): + """The pack URI of the .rels part corresponding to the current pack URI. + + Only produces sensible output if the pack URI is a partname or the package + pseudo-partname '/'. + """ + rels_filename = "%s.rels" % self.filename + rels_uri_str = posixpath.join(self.baseURI, "_rels", rels_filename) + return PackURI(rels_uri_str) + + +PACKAGE_URI = PackURI("/") +CONTENT_TYPES_URI = PackURI("/[Content_Types].xml") diff --git a/src/docx/opc/part.py b/src/docx/opc/part.py new file mode 100644 index 00000000..a9f67a29 --- /dev/null +++ b/src/docx/opc/part.py @@ -0,0 +1,267 @@ +# pyright: reportImportCycles=false + +"""Open Packaging Convention (OPC) objects related to package parts.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Callable, Type, cast + +from docx.opc.oxml import serialize_part_xml +from docx.opc.packuri import PackURI +from docx.opc.rel import Relationships, _Relationship +from docx.opc.shared import cls_method_fn +from docx.oxml.parser import parse_xml +from docx.shared import lazyproperty + +if TYPE_CHECKING: + from docx.oxml.xmlchemy import BaseOxmlElement + from docx.package import Package + + +class Part: + """Base class for package parts. + + Provides common properties and methods, but intended to be subclassed in client code + to implement specific part behaviors. + """ + + def __init__( + self, + partname: PackURI, + content_type: str, + blob: bytes | None = None, + package: Package | None = None, + ): + super(Part, self).__init__() + self._partname = partname + self._content_type = content_type + self._blob = blob + self._package = package + + def after_unmarshal(self): + """Entry point for post-unmarshaling processing, for example to parse the part + XML. + + May be overridden by subclasses without forwarding call to super. + """ + # don't place any code here, just catch call if not overridden by + # subclass + pass + + def before_marshal(self): + """Entry point for pre-serialization processing, for example to finalize part + naming if necessary. + + May be overridden by subclasses without forwarding call to super. + """ + # don't place any code here, just catch call if not overridden by + # subclass + pass + + @property + def blob(self) -> bytes: + """Contents of this package part as a sequence of bytes. + + May be text or binary. Intended to be overridden by subclasses. Default behavior + is to return load blob. + """ + return self._blob or b"" + + @property + def content_type(self): + """Content type of this part.""" + return self._content_type + + def drop_rel(self, rId: str): + """Remove the relationship identified by `rId` if its reference count is less + than 2. + + Relationships with a reference count of 0 are implicit relationships. + """ + if self._rel_ref_count(rId) < 2: + del self.rels[rId] + + def drop_rels(self, cmp: Callable[[_Relationship], bool]) -> list[str]: + rids = [rid for rid, rel in self.rels.items() if cmp(rel)] + for rid in rids: + del self.rels[rid] + return rids + + @classmethod + def load(cls, partname: PackURI, content_type: str, blob: bytes, package: Package): + return cls(partname, content_type, blob, package) + + def load_rel(self, reltype: str, target: Part | str, rId: str, is_external: bool = False): + """Return newly added |_Relationship| instance of `reltype`. + + The new relationship relates the `target` part to this part with key `rId`. + + Target mode is set to ``RTM.EXTERNAL`` if `is_external` is |True|. Intended for + use during load from a serialized package, where the rId is well-known. Other + methods exist for adding a new relationship to a part when manipulating a part. + """ + return self.rels.add_relationship(reltype, target, rId, is_external) + + @property + def package(self): + """|OpcPackage| instance this part belongs to.""" + return self._package + + @property + def partname(self): + """|PackURI| instance holding partname of this part, e.g. + '/ppt/slides/slide1.xml'.""" + return self._partname + + @partname.setter + def partname(self, partname: str): + if not isinstance(partname, PackURI): + tmpl = "partname must be instance of PackURI, got '%s'" + raise TypeError(tmpl % type(partname).__name__) + self._partname = partname + + def __eq__(self, other: object) -> bool: + return type(self) == type(other) and self.partname == other.partname + + def part_related_by(self, reltype: str) -> Part: + """Return part to which this part has a relationship of `reltype`. + + Raises |KeyError| if no such relationship is found and |ValueError| if more than + one such relationship is found. Provides ability to resolve implicitly related + part, such as Slide -> SlideLayout. + """ + return self.rels.part_with_reltype(reltype) + + def relate_to(self, target: Part | str, reltype: str, is_external: bool = False) -> str: + """Return rId key of relationship of `reltype` to `target`. + + The returned `rId` is from an existing relationship if there is one, otherwise a + new relationship is created. + """ + if is_external: + return self.rels.get_or_add_ext_rel(reltype, cast(str, target)) + else: + rel = self.rels.get_or_add(reltype, cast(Part, target)) + return rel.rId + + @property + def related_parts(self): + """Dictionary mapping related parts by rId, so child objects can resolve + explicit relationships present in the part XML, e.g. sldIdLst to a specific + |Slide| instance.""" + return self.rels.related_parts + + @lazyproperty + def rels(self): + """|Relationships| instance holding the relationships for this part.""" + # -- prevent breakage in `python-docx-template` by retaining legacy `._rels` attribute -- + self._rels = Relationships(self._partname.baseURI) + return self._rels + + def target_ref(self, rId: str) -> str: + """Return URL contained in target ref of relationship identified by `rId`.""" + rel = self.rels[rId] + return rel.target_ref + + def _rel_ref_count(self, rId: str) -> int: + """Return the count of references in this part to the relationship identified by `rId`. + + Only an XML part can contain references, so this is 0 for `Part`. + """ + return 0 + + +class PartFactory: + """Provides a way for client code to specify a subclass of |Part| to be constructed + by |Unmarshaller| based on its content type and/or a custom callable. + + Setting ``PartFactory.part_class_selector`` to a callable object will cause that + object to be called with the parameters ``content_type, reltype``, once for each + part in the package. If the callable returns an object, it is used as the class for + that part. If it returns |None|, part class selection falls back to the content type + map defined in ``PartFactory.part_type_for``. If no class is returned from either of + these, the class contained in ``PartFactory.default_part_type`` is used to construct + the part, which is by default ``opc.package.Part``. + """ + + part_class_selector: Callable[[str, str], Type[Part] | None] | None + part_type_for: dict[str, Type[Part]] = {} + default_part_type = Part + + def __new__( + cls, + partname: PackURI, + content_type: str, + reltype: str, + blob: bytes, + package: Package, + ): + PartClass: Type[Part] | None = None + if cls.part_class_selector is not None: + part_class_selector = cls_method_fn(cls, "part_class_selector") + PartClass = part_class_selector(content_type, reltype) + if PartClass is None: + PartClass = cls._part_cls_for(content_type) + return PartClass.load(partname, content_type, blob, package) + + @classmethod + def _part_cls_for(cls, content_type: str): + """Return the custom part class registered for `content_type`, or the default + part class if no custom class is registered for `content_type`.""" + if content_type in cls.part_type_for: + return cls.part_type_for[content_type] + return cls.default_part_type + + +class XmlPart(Part): + """Base class for package parts containing an XML payload, which is most of them. + + Provides additional methods to the |Part| base class that take care of parsing and + reserializing the XML payload and managing relationships to other parts. + """ + + def __init__( + self, partname: PackURI, content_type: str, element: BaseOxmlElement, package: Package + ): + super(XmlPart, self).__init__(partname, content_type, package=package) + self._element = element + + @property + def blob(self): + return serialize_part_xml(self._element) + + @property + def element(self): + """The root XML element of this XML part.""" + return self._element + + @element.setter + def element(self, e: BaseOxmlElement): + self._element = e + + @classmethod + def load(cls, partname: PackURI, content_type: str, blob: bytes, package: Package): + element = parse_xml(blob) + return cls(partname, content_type, element, package) + + @property + def part(self): + """Part of the parent protocol, "children" of the document will not know the + part that contains them so must ask their parent object. + + That chain of delegation ends here for child objects. + """ + return self + + def _rel_ref_count(self, rId: str) -> int: + """Return the number of XML attributes referencing `rId` in this part.""" + element = getattr(self, "_element", None) + if element is None: + return 0 + + count = 0 + for child in element.iter(): + for value in child.attrib.values(): + if value == rId: + count += 1 + return count diff --git a/docx/oxml/text/__init__.py b/src/docx/opc/parts/__init__.py similarity index 100% rename from docx/oxml/text/__init__.py rename to src/docx/opc/parts/__init__.py diff --git a/src/docx/opc/parts/coreprops.py b/src/docx/opc/parts/coreprops.py new file mode 100644 index 00000000..fda01121 --- /dev/null +++ b/src/docx/opc/parts/coreprops.py @@ -0,0 +1,48 @@ +"""Core properties part, corresponds to ``/docProps/core.xml`` part in package.""" + +from __future__ import annotations + +import datetime as dt +from typing import TYPE_CHECKING + +from docx.opc.constants import CONTENT_TYPE as CT +from docx.opc.coreprops import CoreProperties +from docx.opc.packuri import PackURI +from docx.opc.part import XmlPart +from docx.oxml.coreprops import CT_CoreProperties + +if TYPE_CHECKING: + from docx.opc.package import OpcPackage + + +class CorePropertiesPart(XmlPart): + """Corresponds to part named ``/docProps/core.xml``. + + The "core" is short for "Dublin Core" and contains document metadata relatively common across + documents of all types, not just DOCX. + """ + + @classmethod + def default(cls, package: OpcPackage): + """Return a new |CorePropertiesPart| object initialized with default values for + its base properties.""" + core_properties_part = cls._new(package) + core_properties = core_properties_part.core_properties + core_properties.title = "Word Document" + core_properties.last_modified_by = "python-docx" + core_properties.revision = 1 + core_properties.modified = dt.datetime.now(dt.timezone.utc) + return core_properties_part + + @property + def core_properties(self): + """A |CoreProperties| object providing read/write access to the core properties + contained in this core properties part.""" + return CoreProperties(self.element) + + @classmethod + def _new(cls, package: OpcPackage) -> CorePropertiesPart: + partname = PackURI("/docProps/core.xml") + content_type = CT.OPC_CORE_PROPERTIES + coreProperties = CT_CoreProperties.new() + return CorePropertiesPart(partname, content_type, coreProperties, package) diff --git a/docx/opc/parts/customprops.py b/src/docx/opc/parts/customprops.py similarity index 100% rename from docx/opc/parts/customprops.py rename to src/docx/opc/parts/customprops.py diff --git a/docx/opc/phys_pkg.py b/src/docx/opc/phys_pkg.py similarity index 50% rename from docx/opc/phys_pkg.py rename to src/docx/opc/phys_pkg.py index 6d68198d..5ec32237 100644 --- a/docx/opc/phys_pkg.py +++ b/src/docx/opc/phys_pkg.py @@ -1,28 +1,18 @@ -# encoding: utf-8 - -""" -Provides a general interface to a *physical* OPC package, such as a zip file. -""" - -from __future__ import absolute_import +"""Provides a general interface to a `physical` OPC package, such as a zip file.""" import os +from zipfile import ZIP_DEFLATED, ZipFile, is_zipfile -from zipfile import ZipFile, is_zipfile, ZIP_DEFLATED +from docx.opc.exceptions import PackageNotFoundError +from docx.opc.packuri import CONTENT_TYPES_URI -from .compat import is_string -from .exceptions import PackageNotFoundError -from .packuri import CONTENT_TYPES_URI - -class PhysPkgReader(object): - """ - Factory for physical package reader objects. - """ +class PhysPkgReader: + """Factory for physical package reader objects.""" def __new__(cls, pkg_file): - # if *pkg_file* is a string, treat it as a path - if is_string(pkg_file): + # if `pkg_file` is a string, treat it as a path + if isinstance(pkg_file, str): if os.path.isdir(pkg_file): reader_cls = _DirPkgReader elif is_zipfile(pkg_file): @@ -35,57 +25,42 @@ def __new__(cls, pkg_file): return super(PhysPkgReader, cls).__new__(reader_cls) -class PhysPkgWriter(object): - """ - Factory for physical package writer objects. - """ +class PhysPkgWriter: + """Factory for physical package writer objects.""" def __new__(cls, pkg_file): return super(PhysPkgWriter, cls).__new__(_ZipPkgWriter) class _DirPkgReader(PhysPkgReader): - """ - Implements |PhysPkgReader| interface for an OPC package extracted into a - directory. - """ + """Implements |PhysPkgReader| interface for an OPC package extracted into a + directory.""" def __init__(self, path): - """ - *path* is the path to a directory containing an expanded package. - """ + """`path` is the path to a directory containing an expanded package.""" super(_DirPkgReader, self).__init__() self._path = os.path.abspath(path) def blob_for(self, pack_uri): - """ - Return contents of file corresponding to *pack_uri* in package - directory. - """ + """Return contents of file corresponding to `pack_uri` in package directory.""" path = os.path.join(self._path, pack_uri.membername) with open(path, "rb") as f: blob = f.read() return blob def close(self): - """ - Provides interface consistency with |ZipFileSystem|, but does - nothing, a directory file system doesn't need closing. - """ + """Provides interface consistency with |ZipFileSystem|, but does nothing, a + directory file system doesn't need closing.""" pass @property def content_types_xml(self): - """ - Return the `[Content_Types].xml` blob from the package. - """ + """Return the `[Content_Types].xml` blob from the package.""" return self.blob_for(CONTENT_TYPES_URI) def rels_xml_for(self, source_uri): - """ - Return rels item XML for source with *source_uri*, or None if the - item has no rels item. - """ + """Return rels item XML for source with `source_uri`, or None if the item has no + rels item.""" try: rels_xml = self.blob_for(source_uri.rels_uri) except IOError: @@ -94,39 +69,31 @@ def rels_xml_for(self, source_uri): class _ZipPkgReader(PhysPkgReader): - """ - Implements |PhysPkgReader| interface for a zip file OPC package. - """ + """Implements |PhysPkgReader| interface for a zip file OPC package.""" def __init__(self, pkg_file): super(_ZipPkgReader, self).__init__() self._zipf = ZipFile(pkg_file, "r") def blob_for(self, pack_uri): - """ - Return blob corresponding to *pack_uri*. Raises |ValueError| if no - matching member is present in zip archive. + """Return blob corresponding to `pack_uri`. + + Raises |ValueError| if no matching member is present in zip archive. """ return self._zipf.read(pack_uri.membername) def close(self): - """ - Close the zip archive, releasing any resources it is using. - """ + """Close the zip archive, releasing any resources it is using.""" self._zipf.close() @property def content_types_xml(self): - """ - Return the `[Content_Types].xml` blob from the zip package. - """ + """Return the `[Content_Types].xml` blob from the zip package.""" return self.blob_for(CONTENT_TYPES_URI) def rels_xml_for(self, source_uri): - """ - Return rels item XML for source with *source_uri* or None if no rels - item is present. - """ + """Return rels item XML for source with `source_uri` or None if no rels item is + present.""" try: rels_xml = self.blob_for(source_uri.rels_uri) except KeyError: @@ -135,24 +102,18 @@ def rels_xml_for(self, source_uri): class _ZipPkgWriter(PhysPkgWriter): - """ - Implements |PhysPkgWriter| interface for a zip file OPC package. - """ + """Implements |PhysPkgWriter| interface for a zip file OPC package.""" def __init__(self, pkg_file): super(_ZipPkgWriter, self).__init__() self._zipf = ZipFile(pkg_file, "w", compression=ZIP_DEFLATED) def close(self): - """ - Close the zip archive, flushing any pending physical writes and - releasing any resources it's using. - """ + """Close the zip archive, flushing any pending physical writes and releasing any + resources it's using.""" self._zipf.close() def write(self, pack_uri, blob): - """ - Write *blob* to this zip package with the membername corresponding to - *pack_uri*. - """ + """Write `blob` to this zip package with the membername corresponding to + `pack_uri`.""" self._zipf.writestr(pack_uri.membername, blob) diff --git a/docx/opc/pkgreader.py b/src/docx/opc/pkgreader.py similarity index 59% rename from docx/opc/pkgreader.py rename to src/docx/opc/pkgreader.py index b5180192..15207e51 100644 --- a/docx/opc/pkgreader.py +++ b/src/docx/opc/pkgreader.py @@ -1,24 +1,15 @@ -# encoding: utf-8 +"""Low-level, read-only API to a serialized Open Packaging Convention (OPC) package.""" -""" -Provides a low-level, read-only API to a serialized Open Packaging Convention -(OPC) package. -""" +from docx.opc.constants import RELATIONSHIP_TARGET_MODE as RTM +from docx.opc.oxml import parse_xml +from docx.opc.packuri import PACKAGE_URI, PackURI +from docx.opc.phys_pkg import PhysPkgReader +from docx.opc.shared import CaseInsensitiveDict -from __future__ import absolute_import -from .constants import RELATIONSHIP_TARGET_MODE as RTM -from .oxml import parse_xml -from .packuri import PACKAGE_URI, PackURI -from .phys_pkg import PhysPkgReader -from .shared import CaseInsensitiveDict - - -class PackageReader(object): - """ - Provides access to the contents of a zip-format OPC package via its - :attr:`serialized_parts` and :attr:`pkg_srels` attributes. - """ +class PackageReader: + """Provides access to the contents of a zip-format OPC package via its + :attr:`serialized_parts` and :attr:`pkg_srels` attributes.""" def __init__(self, content_types, pkg_srels, sparts): super(PackageReader, self).__init__() @@ -27,31 +18,23 @@ def __init__(self, content_types, pkg_srels, sparts): @staticmethod def from_file(pkg_file): - """ - Return a |PackageReader| instance loaded with contents of *pkg_file*. - """ + """Return a |PackageReader| instance loaded with contents of `pkg_file`.""" phys_reader = PhysPkgReader(pkg_file) content_types = _ContentTypeMap.from_xml(phys_reader.content_types_xml) pkg_srels = PackageReader._srels_for(phys_reader, PACKAGE_URI) - sparts = PackageReader._load_serialized_parts( - phys_reader, pkg_srels, content_types - ) + sparts = PackageReader._load_serialized_parts(phys_reader, pkg_srels, content_types) phys_reader.close() return PackageReader(content_types, pkg_srels, sparts) def iter_sparts(self): - """ - Generate a 4-tuple `(partname, content_type, reltype, blob)` for each - of the serialized parts in the package. - """ + """Generate a 4-tuple `(partname, content_type, reltype, blob)` for each of the + serialized parts in the package.""" for s in self._sparts: yield (s.partname, s.content_type, s.reltype, s.blob) def iter_srels(self): - """ - Generate a 2-tuple `(source_uri, srel)` for each of the relationships - in the package. - """ + """Generate a 2-tuple `(source_uri, srel)` for each of the relationships in the + package.""" for srel in self._pkg_srels: yield (PACKAGE_URI, srel) for spart in self._sparts: @@ -60,11 +43,9 @@ def iter_srels(self): @staticmethod def _load_serialized_parts(phys_reader, pkg_srels, content_types): - """ - Return a list of |_SerializedPart| instances corresponding to the - parts in *phys_reader* accessible by walking the relationship graph - starting with *pkg_srels*. - """ + """Return a list of |_SerializedPart| instances corresponding to the parts in + `phys_reader` accessible by walking the relationship graph starting with + `pkg_srels`.""" sparts = [] part_walker = PackageReader._walk_phys_parts(phys_reader, pkg_srels) for partname, blob, reltype, srels in part_walker: @@ -75,20 +56,15 @@ def _load_serialized_parts(phys_reader, pkg_srels, content_types): @staticmethod def _srels_for(phys_reader, source_uri): - """ - Return |_SerializedRelationships| instance populated with - relationships for source identified by *source_uri*. - """ + """Return |_SerializedRelationships| instance populated with relationships for + source identified by `source_uri`.""" rels_xml = phys_reader.rels_xml_for(source_uri) return _SerializedRelationships.load_from_xml(source_uri.baseURI, rels_xml) @staticmethod def _walk_phys_parts(phys_reader, srels, visited_partnames=None): - """ - Generate a 4-tuple `(partname, blob, reltype, srels)` for each of the - parts in *phys_reader* by walking the relationship graph rooted at - srels. - """ + """Generate a 4-tuple `(partname, blob, reltype, srels)` for each of the parts + in `phys_reader` by walking the relationship graph rooted at srels.""" if visited_partnames is None: visited_partnames = [] for srel in srels: @@ -102,18 +78,14 @@ def _walk_phys_parts(phys_reader, srels, visited_partnames=None): part_srels = PackageReader._srels_for(phys_reader, partname) blob = phys_reader.blob_for(partname) yield (partname, blob, reltype, part_srels) - next_walker = PackageReader._walk_phys_parts( - phys_reader, part_srels, visited_partnames - ) + next_walker = PackageReader._walk_phys_parts(phys_reader, part_srels, visited_partnames) for partname, blob, reltype, srels in next_walker: yield (partname, blob, reltype, srels) -class _ContentTypeMap(object): - """ - Value type providing dictionary semantics for looking up content type by - part name, e.g. ``content_type = cti['/ppt/presentation.xml']``. - """ +class _ContentTypeMap: + """Value type providing dictionary semantics for looking up content type by part + name, e.g. ``content_type = cti['/ppt/presentation.xml']``.""" def __init__(self): super(_ContentTypeMap, self).__init__() @@ -121,9 +93,7 @@ def __init__(self): self._defaults = CaseInsensitiveDict() def __getitem__(self, partname): - """ - Return content type for part identified by *partname*. - """ + """Return content type for part identified by `partname`.""" if not isinstance(partname, PackURI): tmpl = "_ContentTypeMap key must be , got %s" raise KeyError(tmpl % type(partname)) @@ -136,10 +106,8 @@ def __getitem__(self, partname): @staticmethod def from_xml(content_types_xml): - """ - Return a new |_ContentTypeMap| instance populated with the contents - of *content_types_xml*. - """ + """Return a new |_ContentTypeMap| instance populated with the contents of + `content_types_xml`.""" types_elm = parse_xml(content_types_xml) ct_map = _ContentTypeMap() for o in types_elm.overrides: @@ -149,24 +117,21 @@ def from_xml(content_types_xml): return ct_map def _add_default(self, extension, content_type): - """ - Add the default mapping of *extension* to *content_type* to this - content type mapping. - """ + """Add the default mapping of `extension` to `content_type` to this content type + mapping.""" self._defaults[extension] = content_type def _add_override(self, partname, content_type): - """ - Add the default mapping of *partname* to *content_type* to this - content type mapping. - """ + """Add the default mapping of `partname` to `content_type` to this content type + mapping.""" self._overrides[partname] = content_type -class _SerializedPart(object): - """ - Value object for an OPC package part. Provides access to the partname, - content type, blob, and serialized relationships for the part. +class _SerializedPart: + """Value object for an OPC package part. + + Provides access to the partname, content type, blob, and serialized relationships + for the part. """ def __init__(self, partname, content_type, reltype, blob, srels): @@ -191,9 +156,7 @@ def blob(self): @property def reltype(self): - """ - The referring relationship type of this part. - """ + """The referring relationship type of this part.""" return self._reltype @property @@ -201,11 +164,11 @@ def srels(self): return self._srels -class _SerializedRelationship(object): - """ - Value object representing a serialized relationship in an OPC package. - Serialized, in this case, means any target part is referred to via its - partname rather than a direct link to an in-memory |Part| object. +class _SerializedRelationship: + """Value object representing a serialized relationship in an OPC package. + + Serialized, in this case, means any target part is referred to via its partname + rather than a direct link to an in-memory |Part| object. """ def __init__(self, baseURI, rel_elm): @@ -218,9 +181,7 @@ def __init__(self, baseURI, rel_elm): @property def is_external(self): - """ - True if target_mode is ``RTM.EXTERNAL`` - """ + """True if target_mode is ``RTM.EXTERNAL``""" return self._target_mode == RTM.EXTERNAL @property @@ -230,35 +191,29 @@ def reltype(self): @property def rId(self): - """ - Relationship id, like 'rId9', corresponds to the ``Id`` attribute on - the ``CT_Relationship`` element. - """ + """Relationship id, like 'rId9', corresponds to the ``Id`` attribute on the + ``CT_Relationship`` element.""" return self._rId @property def target_mode(self): - """ - String in ``TargetMode`` attribute of ``CT_Relationship`` element, - one of ``RTM.INTERNAL`` or ``RTM.EXTERNAL``. - """ + """String in ``TargetMode`` attribute of ``CT_Relationship`` element, one of + ``RTM.INTERNAL`` or ``RTM.EXTERNAL``.""" return self._target_mode @property def target_ref(self): - """ - String in ``Target`` attribute of ``CT_Relationship`` element, a - relative part reference for internal target mode or an arbitrary URI, - e.g. an HTTP URL, for external target mode. - """ + """String in ``Target`` attribute of ``CT_Relationship`` element, a relative + part reference for internal target mode or an arbitrary URI, e.g. an HTTP URL, + for external target mode.""" return self._target_ref @property def target_partname(self): - """ - |PackURI| instance containing partname targeted by this relationship. - Raises ``ValueError`` on reference if target_mode is ``'External'``. - Use :attr:`target_mode` to check before referencing. + """|PackURI| instance containing partname targeted by this relationship. + + Raises ``ValueError`` on reference if target_mode is ``'External'``. Use + :attr:`target_mode` to check before referencing. """ if self.is_external: msg = ( @@ -272,26 +227,24 @@ def target_partname(self): return self._target_partname -class _SerializedRelationships(object): - """ - Read-only sequence of |_SerializedRelationship| instances corresponding - to the relationships item XML passed to constructor. - """ +class _SerializedRelationships: + """Read-only sequence of |_SerializedRelationship| instances corresponding to the + relationships item XML passed to constructor.""" def __init__(self): super(_SerializedRelationships, self).__init__() self._srels = [] def __iter__(self): - """Support iteration, e.g. 'for x in srels:'""" + """Support iteration, e.g. 'for x in srels:'.""" return self._srels.__iter__() @staticmethod def load_from_xml(baseURI, rels_item_xml): - """ - Return |_SerializedRelationships| instance loaded with the - relationships contained in *rels_item_xml*. Returns an empty - collection if *rels_item_xml* is |None|. + """Return |_SerializedRelationships| instance loaded with the relationships + contained in `rels_item_xml`. + + Returns an empty collection if `rels_item_xml` is |None|. """ srels = _SerializedRelationships() if rels_item_xml is not None: diff --git a/src/docx/opc/pkgwriter.py b/src/docx/opc/pkgwriter.py new file mode 100644 index 00000000..e6351697 --- /dev/null +++ b/src/docx/opc/pkgwriter.py @@ -0,0 +1,115 @@ +"""Provides low-level, write-only API to serialized (OPC) package. + +OPC stands for Open Packaging Convention. This is e, essentially an implementation of +OpcPackage.save(). +""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Iterable + +from docx.opc.constants import CONTENT_TYPE as CT +from docx.opc.oxml import CT_Types, serialize_part_xml +from docx.opc.packuri import CONTENT_TYPES_URI, PACKAGE_URI +from docx.opc.phys_pkg import PhysPkgWriter +from docx.opc.shared import CaseInsensitiveDict +from docx.opc.spec import default_content_types + +if TYPE_CHECKING: + from docx.opc.part import Part + + +class PackageWriter: + """Writes a zip-format OPC package to `pkg_file`, where `pkg_file` can be either a + path to a zip file (a string) or a file-like object. + + Its single API method, :meth:`write`, is static, so this class is not intended to be + instantiated. + """ + + @staticmethod + def write(pkg_file, pkg_rels, parts): + """Write a physical package (.pptx file) to `pkg_file` containing `pkg_rels` and + `parts` and a content types stream based on the content types of the parts.""" + phys_writer = PhysPkgWriter(pkg_file) + PackageWriter._write_content_types_stream(phys_writer, parts) + PackageWriter._write_pkg_rels(phys_writer, pkg_rels) + PackageWriter._write_parts(phys_writer, parts) + phys_writer.close() + + @staticmethod + def _write_content_types_stream(phys_writer, parts): + """Write ``[Content_Types].xml`` part to the physical package with an + appropriate content type lookup target for each part in `parts`.""" + cti = _ContentTypesItem.from_parts(parts) + phys_writer.write(CONTENT_TYPES_URI, cti.blob) + + @staticmethod + def _write_parts(phys_writer: PhysPkgWriter, parts: Iterable[Part]): + """Write the blob of each part in `parts` to the package, along with a rels item + for its relationships if and only if it has any.""" + for part in parts: + phys_writer.write(part.partname, part.blob) + if len(part.rels): + phys_writer.write(part.partname.rels_uri, part.rels.xml) + + @staticmethod + def _write_pkg_rels(phys_writer, pkg_rels): + """Write the XML rels item for `pkg_rels` ('/_rels/.rels') to the package.""" + phys_writer.write(PACKAGE_URI.rels_uri, pkg_rels.xml) + + +class _ContentTypesItem: + """Service class that composes a content types item ([Content_Types].xml) based on a + list of parts. + + Not meant to be instantiated directly, its single interface method is xml_for(), + e.g. ``_ContentTypesItem.xml_for(parts)``. + """ + + def __init__(self): + self._defaults = CaseInsensitiveDict() + self._overrides = {} + + @property + def blob(self): + """Return XML form of this content types item, suitable for storage as + ``[Content_Types].xml`` in an OPC package.""" + return serialize_part_xml(self._element) + + @classmethod + def from_parts(cls, parts): + """Return content types XML mapping each part in `parts` to the appropriate + content type and suitable for storage as ``[Content_Types].xml`` in an OPC + package.""" + cti = cls() + cti._defaults["rels"] = CT.OPC_RELATIONSHIPS + cti._defaults["xml"] = CT.XML + for part in parts: + cti._add_content_type(part.partname, part.content_type) + return cti + + def _add_content_type(self, partname, content_type): + """Add a content type for the part with `partname` and `content_type`, using a + default or override as appropriate.""" + ext = partname.ext + if (ext.lower(), content_type) in default_content_types: + self._defaults[ext] = content_type + else: + self._overrides[partname] = content_type + + @property + def _element(self): + """Return XML form of this content types item, suitable for storage as + ``[Content_Types].xml`` in an OPC package. + + Although the sequence of elements is not strictly significant, as an aid to + testing and readability Default elements are sorted by extension and Override + elements are sorted by partname. + """ + _types_elm = CT_Types.new() + for ext in sorted(self._defaults.keys()): + _types_elm.add_default(ext, self._defaults[ext]) + for partname in sorted(self._overrides.keys()): + _types_elm.add_override(partname, self._overrides[partname]) + return _types_elm diff --git a/src/docx/opc/rel.py b/src/docx/opc/rel.py new file mode 100644 index 00000000..3f70fe28 --- /dev/null +++ b/src/docx/opc/rel.py @@ -0,0 +1,169 @@ +"""Relationship-related objects.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Any, Dict, cast + +from docx.opc.oxml import CT_Relationships + +if TYPE_CHECKING: + from docx.opc.part import Part + + +class Relationships(Dict[str, "_Relationship"]): + """Collection object for |_Relationship| instances, having list semantics.""" + + def __init__(self, baseURI: str): + super(Relationships, self).__init__() + self._baseURI = baseURI + self._target_parts_by_rId: dict[str, Any] = {} + + def add_relationship( + self, reltype: str, target: Part | str, rId: str, is_external: bool = False + ) -> "_Relationship": + """Return a newly added |_Relationship| instance.""" + rel = _Relationship(rId, reltype, target, self._baseURI, is_external) + self[rId] = rel + if not is_external: + self._target_parts_by_rId[rId] = target + return rel + + def get_or_add(self, reltype: str, target_part: Part) -> _Relationship: + """Return relationship of `reltype` to `target_part`, newly added if not already + present in collection.""" + rel = self._get_matching(reltype, target_part) + if rel is None: + rId = self._next_rId + rel = self.add_relationship(reltype, target_part, rId) + return rel + + def get_or_add_ext_rel(self, reltype: str, target_ref: str) -> str: + """Return rId of external relationship of `reltype` to `target_ref`, newly added + if not already present in collection.""" + rel = self._get_matching(reltype, target_ref, is_external=True) + if rel is None: + rId = self._next_rId + rel = self.add_relationship(reltype, target_ref, rId, is_external=True) + return rel.rId + + def part_with_reltype(self, reltype: str) -> Part: + """Return target part of rel with matching `reltype`, raising |KeyError| if not + found and |ValueError| if more than one matching relationship is found.""" + rel = self._get_rel_of_type(reltype) + return rel.target_part + + def parts_with_reltype(self, reltype: str) -> list[Part]: + """Return target part of rel with matching *reltype*, raising |KeyError| + if not found and |ValueError| if more than one matching relationship + is found. + """ + rels = self._get_rel_of_type(reltype, multiple=True) + return [rel.target_part for rel in rels] + + @property + def related_parts(self): + """Dict mapping rIds to target parts for all the internal relationships in the + collection.""" + return self._target_parts_by_rId + + @property + def xml(self) -> str: + """Serialize this relationship collection into XML suitable for storage as a + .rels file in an OPC package.""" + rels_elm = CT_Relationships.new() + for rel in self.values(): + rels_elm.add_rel(rel.rId, rel.reltype, rel.target_ref, rel.is_external) + return rels_elm.xml + + def _get_matching( + self, reltype: str, target: Part | str, is_external: bool = False + ) -> _Relationship | None: + """Return relationship of matching `reltype`, `target`, and `is_external` from + collection, or None if not found.""" + + def matches(rel: _Relationship, reltype: str, target: Part | str, is_external: bool): + if rel.reltype != reltype: + return False + if rel.is_external != is_external: + return False + rel_target = rel.target_ref if rel.is_external else rel.target_part + return rel_target == target + + for rel in self.values(): + if matches(rel, reltype, target, is_external): + return rel + return None + + def _get_rel_of_type(self, reltype: str, multiple: bool = False): + """Return single relationship of type `reltype` from the collection. + + Raises |KeyError| if no matching relationship is found. Raises |ValueError| if + more than one matching relationship is found. + """ + matching = [rel for rel in self.values() if rel.reltype == reltype] + if len(matching) == 0: + tmpl = "no relationship of type '%s' in collection" + raise KeyError(tmpl % reltype) + if multiple: + return matching + if len(matching) > 1: + tmpl = "multiple relationships of type '%s' in collection" + raise ValueError(tmpl % reltype) + return matching[0] + + @property + def _next_rId(self) -> str: # pyright: ignore[reportReturnType] + """Next available rId in collection, starting from 'rId1' and making use of any + gaps in numbering, e.g. 'rId2' for rIds ['rId1', 'rId3'].""" + for n in range(1, len(self) + 2): + rId_candidate = "rId%d" % n # like 'rId19' + if rId_candidate not in self: + return rId_candidate + + +class _Relationship: + """Value object for relationship to part.""" + + def __init__( + self, rId: str, reltype: str, target: Part | str, baseURI: str, external: bool = False + ): + super(_Relationship, self).__init__() + self._rId = rId + self._reltype = reltype + self._target = target + self._baseURI = baseURI + self._is_external = bool(external) + + @property + def is_external(self) -> bool: + return self._is_external + + @property + def reltype(self) -> str: + return self._reltype + + @property + def rId(self) -> str: + return self._rId + + @property + def target_part(self) -> Part: + if self._is_external: + raise ValueError( + "target_part property on _Relationship is undefined when target mode is External" + ) + return cast("Part", self._target) + + @property + def target_ref(self) -> str: + if self._is_external: + return cast(str, self._target) + else: + target = cast("Part", self._target) + return target.partname.relative_ref(self._baseURI) + + @target_ref.setter + def target_ref(self, ref: str): + if not self._is_external: + raise ValueError("can not set internal target_ref") + self._target = ref diff --git a/src/docx/opc/shared.py b/src/docx/opc/shared.py new file mode 100644 index 00000000..9d4c0a6d --- /dev/null +++ b/src/docx/opc/shared.py @@ -0,0 +1,31 @@ +"""Objects shared by opc modules.""" + +from __future__ import annotations + +from typing import Any, Dict, TypeVar + +_T = TypeVar("_T") + + +class CaseInsensitiveDict(Dict[str, Any]): + """Mapping type that behaves like dict except that it matches without respect to the + case of the key. + + E.g. cid['A'] == cid['a']. Note this is not general-purpose, just complete enough to + satisfy opc package needs. It assumes str keys, and that it is created empty; keys + passed in constructor are not accounted for + """ + + def __contains__(self, key): + return super(CaseInsensitiveDict, self).__contains__(key.lower()) + + def __getitem__(self, key): + return super(CaseInsensitiveDict, self).__getitem__(key.lower()) + + def __setitem__(self, key, value): + return super(CaseInsensitiveDict, self).__setitem__(key.lower(), value) + + +def cls_method_fn(cls: type, method_name: str): + """Return method of `cls` having `method_name`.""" + return getattr(cls, method_name) diff --git a/docx/opc/spec.py b/src/docx/opc/spec.py similarity index 77% rename from docx/opc/spec.py rename to src/docx/opc/spec.py index 87489fcf..011a4825 100644 --- a/docx/opc/spec.py +++ b/src/docx/opc/spec.py @@ -1,11 +1,6 @@ -# encoding: utf-8 - -""" -Provides mappings that embody aspects of the Open XML spec ISO/IEC 29500. -""" - -from .constants import CONTENT_TYPE as CT +"""Provides mappings that embody aspects of the Open XML spec ISO/IEC 29500.""" +from docx.opc.constants import CONTENT_TYPE as CT default_content_types = ( ("bin", CT.PML_PRINTER_SETTINGS), diff --git a/docx/oxml/__init__.py b/src/docx/oxml/__init__.py similarity index 63% rename from docx/oxml/__init__.py rename to src/docx/oxml/__init__.py index 31de2185..6dec1cfc 100644 --- a/docx/oxml/__init__.py +++ b/src/docx/oxml/__init__.py @@ -1,94 +1,107 @@ +# ruff: noqa: E402, I001 + +"""Initializes oxml sub-package. + +This including registering custom element classes corresponding to Open XML elements. """ -Initializes oxml sub-package, including registering custom element classes -corresponding to Open XML elements. -""" -from lxml import etree - -from .ns import NamespacePrefixedTag, nsmap - -# configure XML parser -element_class_lookup = etree.ElementNamespaceClassLookup() -oxml_parser = etree.XMLParser(remove_blank_text=True, resolve_entities=False) -oxml_parser.set_element_class_lookup(element_class_lookup) - - -def parse_xml(xml): - """ - Return root lxml element obtained by parsing XML character string in - *xml*, which can be either a Python 2.x string or unicode. The custom - parser is used, so custom element classes are produced for elements in - *xml* that have them. - """ - return etree.fromstring(xml, oxml_parser) - - -def register_element_cls(tag, cls): - """ - Register *cls* to be constructed when the oxml parser encounters an - element with matching *tag*. *tag* is a string of the form - ``nspfx:tagroot``, e.g. ``'w:document'``. - """ - nspfx, tagroot = tag.split(":") - namespace = element_class_lookup.get_namespace(nsmap[nspfx]) - namespace[tagroot] = cls - - -def register_element_cls_ns(tag, ns, cls): - """ - Register *cls* to be constructed when the oxml parser encounters an - element with matching *tag*. *tag* is a string of the form - ``nspfx:tagroot``, e.g. ``'w:document'``. - """ - namespace = element_class_lookup.get_namespace(ns) - namespace[tag] = cls - - -def OxmlElement(nsptag_str, attrs=None, nsdecls=None): - """ - Return a 'loose' lxml element having the tag specified by *nsptag_str*. - *nsptag_str* must contain the standard namespace prefix, e.g. 'a:tbl'. - The resulting element is an instance of the custom element class for this - tag name if one is defined. A dictionary of attribute values may be - provided as *attrs*; they are set if present. All namespaces defined in - the dict *nsdecls* are declared in the element using the key as the - prefix and the value as the namespace name. If *nsdecls* is not provided, - a single namespace declaration is added based on the prefix on - *nsptag_str*. - """ - nsptag = NamespacePrefixedTag(nsptag_str) - if nsdecls is None: - nsdecls = nsptag.nsmap - return oxml_parser.makeelement(nsptag.clark_name, attrib=attrs, nsmap=nsdecls) - - -# =========================================================================== -# custom element class mappings -# =========================================================================== - -from .shared import CT_DecimalNumber, CT_OnOff, CT_String # noqa + +from __future__ import annotations + +from docx.oxml.drawing import CT_Drawing +from docx.oxml.parser import OxmlElement, parse_xml, register_element_cls +from docx.oxml.shape import ( + CT_Anchor, + CT_Blip, + CT_BlipFillProperties, + CT_GraphicalObject, + CT_GraphicalObjectData, + CT_Inline, + CT_NonVisualDrawingProps, + CT_Picture, + CT_PictureNonVisual, + CT_Point2D, + CT_PositiveSize2D, + CT_ShapeProperties, + CT_Transform2D, +) +from docx.oxml.shared import CT_DecimalNumber, CT_OnOff, CT_String +from docx.oxml.text.hyperlink import CT_Hyperlink +from docx.oxml.text.pagebreak import CT_LastRenderedPageBreak +from docx.oxml.text.run import ( + CT_R, + CT_Br, + CT_Cr, + CT_NoBreakHyphen, + CT_PTab, + CT_Text, +) + +# -- `OxmlElement` and `parse_xml()` are not used in this module but several downstream +# -- "extension" packages expect to find them here and there's no compelling reason +# -- not to republish them here so those keep working. +__all__ = ["OxmlElement", "parse_xml"] + +# --------------------------------------------------------------------------- +# DrawingML-related elements + +register_element_cls("a:blip", CT_Blip) +register_element_cls("a:ext", CT_PositiveSize2D) +register_element_cls("a:graphic", CT_GraphicalObject) +register_element_cls("a:graphicData", CT_GraphicalObjectData) +register_element_cls("a:off", CT_Point2D) +register_element_cls("a:xfrm", CT_Transform2D) +register_element_cls("pic:blipFill", CT_BlipFillProperties) +register_element_cls("pic:cNvPr", CT_NonVisualDrawingProps) +register_element_cls("pic:nvPicPr", CT_PictureNonVisual) +register_element_cls("pic:pic", CT_Picture) +register_element_cls("pic:spPr", CT_ShapeProperties) +register_element_cls("w:drawing", CT_Drawing) +register_element_cls("wp:anchor", CT_Anchor) +register_element_cls("wp:docPr", CT_NonVisualDrawingProps) +register_element_cls("wp:extent", CT_PositiveSize2D) +register_element_cls("wp:inline", CT_Inline) +register_element_cls("asvg:svgBlip", CT_Transform2D) + +# --------------------------------------------------------------------------- +# hyperlink-related elements + +register_element_cls("w:hyperlink", CT_Hyperlink) + +# --------------------------------------------------------------------------- +# text-related elements + +register_element_cls("w:br", CT_Br) +register_element_cls("w:cr", CT_Cr) +register_element_cls("w:lastRenderedPageBreak", CT_LastRenderedPageBreak) +register_element_cls("w:noBreakHyphen", CT_NoBreakHyphen) +register_element_cls("w:ptab", CT_PTab) +register_element_cls("w:r", CT_R) +register_element_cls("w:t", CT_Text) + +# --------------------------------------------------------------------------- +# header/footer-related mappings register_element_cls("w:evenAndOddHeaders", CT_OnOff) register_element_cls("w:titlePg", CT_OnOff) +# --------------------------------------------------------------------------- +# other custom element class mappings -from .coreprops import CT_CoreProperties # noqa +from .comments import CT_Comments, CT_Comment -register_element_cls("cp:coreProperties", CT_CoreProperties) +register_element_cls("w:comments", CT_Comments) +register_element_cls("w:comment", CT_Comment) -from .customprops import CT_CustomProperties +from .coreprops import CT_CoreProperties -register_element_cls_ns( - "Properties", - "http://schemas.openxmlformats.org/officeDocument/2006/custom-properties", - CT_CustomProperties, -) +register_element_cls("cp:coreProperties", CT_CoreProperties) from .document import CT_Body, CT_Document register_element_cls("w:body", CT_Body) register_element_cls("w:document", CT_Document) -from .numbering import CT_Num, CT_Numbering, CT_NumLvl, CT_NumPr # noqa +from .numbering import CT_Num, CT_Numbering, CT_NumLvl, CT_NumPr register_element_cls("w:abstractNumId", CT_DecimalNumber) register_element_cls("w:ilvl", CT_DecimalNumber) @@ -99,8 +112,14 @@ def OxmlElement(nsptag_str, attrs=None, nsdecls=None): register_element_cls("w:numbering", CT_Numbering) register_element_cls("w:startOverride", CT_DecimalNumber) -from .section import CT_PageSz # noqa -from .section import CT_HdrFtr, CT_HdrFtrRef, CT_PageMar, CT_SectPr, CT_SectType +from .section import ( + CT_HdrFtr, + CT_HdrFtrRef, + CT_PageMar, + CT_PageSz, + CT_SectPr, + CT_SectType, +) register_element_cls("w:footerReference", CT_HdrFtrRef) register_element_cls("w:ftr", CT_HdrFtr) @@ -111,45 +130,11 @@ def OxmlElement(nsptag_str, attrs=None, nsdecls=None): register_element_cls("w:sectPr", CT_SectPr) register_element_cls("w:type", CT_SectType) -from .settings import CT_Settings # noqa +from .settings import CT_Settings register_element_cls("w:settings", CT_Settings) -from .shape import CT_GraphicalObject # noqa -from .shape import ( - CT_Anchor, - CT_Blip, - CT_BlipFillProperties, - CT_GraphicalObjectData, - CT_Inline, - CT_NonVisualDrawingProps, - CT_Picture, - CT_PictureNonVisual, - CT_Point2D, - CT_PositiveSize2D, - CT_ShapeProperties, - CT_Transform2D, -) - -register_element_cls("a:blip", CT_Blip) -register_element_cls("a:ext", CT_PositiveSize2D) -register_element_cls("a:extLst", CT_Transform2D) -register_element_cls("asvg:svgBlip", CT_Transform2D) -register_element_cls("a:graphic", CT_GraphicalObject) -register_element_cls("a:graphicData", CT_GraphicalObjectData) -register_element_cls("a:off", CT_Point2D) -register_element_cls("a:xfrm", CT_Transform2D) -register_element_cls("pic:blipFill", CT_BlipFillProperties) -register_element_cls("pic:cNvPr", CT_NonVisualDrawingProps) -register_element_cls("pic:nvPicPr", CT_PictureNonVisual) -register_element_cls("pic:pic", CT_Picture) -register_element_cls("pic:spPr", CT_ShapeProperties) -register_element_cls("wp:docPr", CT_NonVisualDrawingProps) -register_element_cls("wp:extent", CT_PositiveSize2D) -register_element_cls("wp:inline", CT_Inline) -register_element_cls("wp:anchor", CT_Anchor) - -from .styles import CT_LatentStyles, CT_LsdException, CT_Style, CT_Styles # noqa +from .styles import CT_LatentStyles, CT_LsdException, CT_Style, CT_Styles register_element_cls("w:basedOn", CT_String) register_element_cls("w:latentStyles", CT_LatentStyles) @@ -164,29 +149,33 @@ def OxmlElement(nsptag_str, attrs=None, nsdecls=None): register_element_cls("w:uiPriority", CT_DecimalNumber) register_element_cls("w:unhideWhenUsed", CT_OnOff) -from .table import CT_TblGrid # noqa from .table import ( CT_Height, CT_Row, CT_Tbl, + CT_TblGrid, CT_TblGridCol, CT_TblLayoutType, CT_TblPr, + CT_TblPrEx, CT_TblWidth, CT_Tc, CT_TcPr, CT_TrPr, - CT_VerticalJc, CT_VMerge, + CT_VerticalJc, ) register_element_cls("w:bidiVisual", CT_OnOff) +register_element_cls("w:gridAfter", CT_DecimalNumber) +register_element_cls("w:gridBefore", CT_DecimalNumber) register_element_cls("w:gridCol", CT_TblGridCol) register_element_cls("w:gridSpan", CT_DecimalNumber) register_element_cls("w:tbl", CT_Tbl) register_element_cls("w:tblGrid", CT_TblGrid) register_element_cls("w:tblLayout", CT_TblLayoutType) register_element_cls("w:tblPr", CT_TblPr) +register_element_cls("w:tblPrEx", CT_TblPrEx) register_element_cls("w:tblStyle", CT_String) register_element_cls("w:tc", CT_Tc) register_element_cls("w:tcPr", CT_TcPr) @@ -197,10 +186,10 @@ def OxmlElement(nsptag_str, attrs=None, nsdecls=None): register_element_cls("w:vAlign", CT_VerticalJc) register_element_cls("w:vMerge", CT_VMerge) -from .text.font import CT_Highlight # noqa from .text.font import ( CT_Color, CT_Fonts, + CT_Highlight, CT_HpsMeasure, CT_RPr, CT_Underline, @@ -236,17 +225,24 @@ def OxmlElement(nsptag_str, attrs=None, nsdecls=None): register_element_cls("w:vertAlign", CT_VerticalAlignRun) register_element_cls("w:webHidden", CT_OnOff) -from .text.paragraph import CT_P # noqa +from .text.paragraph import CT_P register_element_cls("w:p", CT_P) -from .text.parfmt import CT_Spacing # noqa -from .text.parfmt import CT_Ind, CT_Jc, CT_PPr, CT_TabStop, CT_TabStops +from .text.parfmt import ( + CT_Ind, + CT_Jc, + CT_PPr, + CT_Spacing, + CT_TabStop, + CT_TabStops, +) register_element_cls("w:ind", CT_Ind) register_element_cls("w:jc", CT_Jc) register_element_cls("w:keepLines", CT_OnOff) register_element_cls("w:keepNext", CT_OnOff) +register_element_cls("w:outlineLvl", CT_DecimalNumber) register_element_cls("w:pageBreakBefore", CT_OnOff) register_element_cls("w:pPr", CT_PPr) register_element_cls("w:pStyle", CT_String) @@ -254,9 +250,3 @@ def OxmlElement(nsptag_str, attrs=None, nsdecls=None): register_element_cls("w:tab", CT_TabStop) register_element_cls("w:tabs", CT_TabStops) register_element_cls("w:widowControl", CT_OnOff) - -from .text.run import CT_R, CT_Br, CT_Text # noqa - -register_element_cls("w:br", CT_Br) -register_element_cls("w:r", CT_R) -register_element_cls("w:t", CT_Text) diff --git a/src/docx/oxml/comments.py b/src/docx/oxml/comments.py new file mode 100644 index 00000000..ad982175 --- /dev/null +++ b/src/docx/oxml/comments.py @@ -0,0 +1,124 @@ +"""Custom element classes related to document comments.""" + +from __future__ import annotations + +import datetime as dt +from typing import TYPE_CHECKING, Callable, cast + +from docx.oxml.ns import nsdecls +from docx.oxml.parser import parse_xml +from docx.oxml.simpletypes import ST_DateTime, ST_DecimalNumber, ST_String +from docx.oxml.xmlchemy import BaseOxmlElement, OptionalAttribute, RequiredAttribute, ZeroOrMore + +if TYPE_CHECKING: + from docx.oxml.table import CT_Tbl + from docx.oxml.text.paragraph import CT_P + + +class CT_Comments(BaseOxmlElement): + """`w:comments` element, the root element for the comments part. + + Simply contains a collection of `w:comment` elements, each representing a single comment. Each + contained comment is identified by a unique `w:id` attribute, used to reference the comment + from the document text. The offset of the comment in this collection is arbitrary; it is + essentially a _set_ implemented as a list. + """ + + # -- type-declarations to fill in the gaps for metaclass-added methods -- + comment_lst: list[CT_Comment] + + comment = ZeroOrMore("w:comment") + + def add_comment(self) -> CT_Comment: + """Return newly added `w:comment` child of this `w:comments`. + + The returned `w:comment` element is the minimum valid value, having a `w:id` value unique + within the existing comments and the required `w:author` attribute present but set to the + empty string. It's content is limited to a single run containing the necessary annotation + reference but no text. Content is added by adding runs to this first paragraph and by + adding additional paragraphs as needed. + """ + next_id = self._next_available_comment_id() + comment = cast( + CT_Comment, + parse_xml( + f'' + f" " + f" " + f' ' + f" " + f" " + f" " + f' ' + f" " + f" " + f" " + f" " + f"" + ), + ) + self.append(comment) + return comment + + def get_comment_by_id(self, comment_id: int) -> CT_Comment | None: + """Return the `w:comment` element identified by `comment_id`, or |None| if not found.""" + comment_elms = self.xpath(f"(./w:comment[@w:id='{comment_id}'])[1]") + return comment_elms[0] if comment_elms else None + + def _next_available_comment_id(self) -> int: + """The next available comment id. + + According to the schema, this can be any positive integer, as big as you like, and the + default mechanism is to use `max() + 1`. However, if that yields a value larger than will + fit in a 32-bit signed integer, we take a more deliberate approach to use the first + ununsed integer starting from 0. + """ + used_ids = [int(x) for x in self.xpath("./w:comment/@w:id")] + + next_id = max(used_ids, default=-1) + 1 + + if next_id <= 2**31 - 1: + return next_id + + # -- fall-back to enumerating all used ids to find the first unused one -- + for expected, actual in enumerate(sorted(used_ids)): + if expected != actual: + return expected + + return len(used_ids) + + +class CT_Comment(BaseOxmlElement): + """`w:comment` element, representing a single comment. + + A comment is a so-called "story" and can contain paragraphs and tables much like a table-cell. + While probably most often used for a single sentence or phrase, a comment can contain rich + content, including multiple rich-text paragraphs, hyperlinks, images, and tables. + """ + + # -- attributes on `w:comment` -- + id: int = RequiredAttribute("w:id", ST_DecimalNumber) # pyright: ignore[reportAssignmentType] + author: str = RequiredAttribute("w:author", ST_String) # pyright: ignore[reportAssignmentType] + initials: str | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:initials", ST_String + ) + date: dt.datetime | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:date", ST_DateTime + ) + + # -- children -- + + p = ZeroOrMore("w:p", successors=()) + tbl = ZeroOrMore("w:tbl", successors=()) + + # -- type-declarations for methods added by metaclass -- + + add_p: Callable[[], CT_P] + p_lst: list[CT_P] + tbl_lst: list[CT_Tbl] + _insert_tbl: Callable[[CT_Tbl], CT_Tbl] + + @property + def inner_content_elements(self) -> list[CT_P | CT_Tbl]: + """Generate all `w:p` and `w:tbl` elements in this comment.""" + return self.xpath("./w:p | ./w:tbl") diff --git a/docx/oxml/coreprops.py b/src/docx/oxml/coreprops.py similarity index 59% rename from docx/oxml/coreprops.py rename to src/docx/oxml/coreprops.py index 0520201b..fcff0c7b 100644 --- a/docx/oxml/coreprops.py +++ b/src/docx/oxml/coreprops.py @@ -1,27 +1,28 @@ -# encoding: utf-8 +"""Custom element classes for core properties-related XML elements.""" -"""Custom element classes for core properties-related XML elements""" - -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import annotations +import datetime as dt import re +from typing import TYPE_CHECKING, Any, Callable, cast -from datetime import datetime, timedelta - -from docx.compat import is_string -from docx.oxml import parse_xml from docx.oxml.ns import nsdecls, qn +from docx.oxml.parser import parse_xml from docx.oxml.xmlchemy import BaseOxmlElement, ZeroOrOne +if TYPE_CHECKING: + from lxml.etree import _Element as etree_Element # pyright: ignore[reportPrivateUsage] + class CT_CoreProperties(BaseOxmlElement): + """`` element, the root element of the Core Properties part. + + Stored as `/docProps/core.xml`. Implements many of the Dublin Core document metadata + elements. String elements resolve to an empty string ("") if the element is not + present in the XML. String elements are limited in length to 255 unicode characters. """ - ```` element, the root element of the Core Properties - part stored as ``/docProps/core.xml``. Implements many of the Dublin Core - document metadata elements. String elements resolve to an empty string - ('') if the element is not present in the XML. String elements are - limited in length to 255 unicode characters. - """ + + get_or_add_revision: Callable[[], etree_Element] category = ZeroOrOne("cp:category", successors=()) contentStatus = ZeroOrOne("cp:contentStatus", successors=()) @@ -34,7 +35,9 @@ class CT_CoreProperties(BaseOxmlElement): lastModifiedBy = ZeroOrOne("cp:lastModifiedBy", successors=()) lastPrinted = ZeroOrOne("cp:lastPrinted", successors=()) modified = ZeroOrOne("dcterms:modified", successors=()) - revision = ZeroOrOne("cp:revision", successors=()) + revision: etree_Element | None = ZeroOrOne( # pyright: ignore[reportAssignmentType] + "cp:revision", successors=() + ) subject = ZeroOrOne("dc:subject", successors=()) title = ZeroOrOne("dc:title", successors=()) version = ZeroOrOne("cp:version", successors=()) @@ -42,114 +45,108 @@ class CT_CoreProperties(BaseOxmlElement): _coreProperties_tmpl = "\n" % nsdecls("cp", "dc", "dcterms") @classmethod - def new(cls): - """ - Return a new ```` element - """ + def new(cls) -> CT_CoreProperties: + """Return a new `` element.""" xml = cls._coreProperties_tmpl - coreProperties = parse_xml(xml) + coreProperties = cast(CT_CoreProperties, parse_xml(xml)) return coreProperties @property - def author_text(self): - """ - The text in the `dc:creator` child element. - """ + def author_text(self) -> str: + """The text in the `dc:creator` child element.""" return self._text_of_element("creator") @author_text.setter - def author_text(self, value): + def author_text(self, value: str): self._set_element_text("creator", value) @property - def category_text(self): + def category_text(self) -> str: return self._text_of_element("category") @category_text.setter - def category_text(self, value): + def category_text(self, value: str): self._set_element_text("category", value) @property - def comments_text(self): + def comments_text(self) -> str: return self._text_of_element("description") @comments_text.setter - def comments_text(self, value): + def comments_text(self, value: str): self._set_element_text("description", value) @property - def contentStatus_text(self): + def contentStatus_text(self) -> str: return self._text_of_element("contentStatus") @contentStatus_text.setter - def contentStatus_text(self, value): + def contentStatus_text(self, value: str): self._set_element_text("contentStatus", value) @property - def created_datetime(self): + def created_datetime(self) -> dt.datetime | None: return self._datetime_of_element("created") @created_datetime.setter - def created_datetime(self, value): + def created_datetime(self, value: dt.datetime): self._set_element_datetime("created", value) @property - def identifier_text(self): + def identifier_text(self) -> str: return self._text_of_element("identifier") @identifier_text.setter - def identifier_text(self, value): + def identifier_text(self, value: str): self._set_element_text("identifier", value) @property - def keywords_text(self): + def keywords_text(self) -> str: return self._text_of_element("keywords") @keywords_text.setter - def keywords_text(self, value): + def keywords_text(self, value: str): self._set_element_text("keywords", value) @property - def language_text(self): + def language_text(self) -> str: return self._text_of_element("language") @language_text.setter - def language_text(self, value): + def language_text(self, value: str): self._set_element_text("language", value) @property - def lastModifiedBy_text(self): + def lastModifiedBy_text(self) -> str: return self._text_of_element("lastModifiedBy") @lastModifiedBy_text.setter - def lastModifiedBy_text(self, value): + def lastModifiedBy_text(self, value: str): self._set_element_text("lastModifiedBy", value) @property - def lastPrinted_datetime(self): + def lastPrinted_datetime(self) -> dt.datetime | None: return self._datetime_of_element("lastPrinted") @lastPrinted_datetime.setter - def lastPrinted_datetime(self, value): + def lastPrinted_datetime(self, value: dt.datetime): self._set_element_datetime("lastPrinted", value) @property - def modified_datetime(self): + def modified_datetime(self) -> dt.datetime | None: return self._datetime_of_element("modified") @modified_datetime.setter - def modified_datetime(self, value): + def modified_datetime(self, value: dt.datetime): self._set_element_datetime("modified", value) @property - def revision_number(self): - """ - Integer value of revision property. - """ + def revision_number(self) -> int: + """Integer value of revision property.""" revision = self.revision if revision is None: return 0 - revision_str = revision.text + revision_str = str(revision.text) try: revision = int(revision_str) except ValueError: @@ -161,41 +158,39 @@ def revision_number(self): return revision @revision_number.setter - def revision_number(self, value): - """ - Set revision property to string value of integer *value*. - """ - if not isinstance(value, int) or value < 1: + def revision_number(self, value: int): + """Set revision property to string value of integer `value`.""" + if not isinstance(value, int) or value < 1: # pyright: ignore[reportUnnecessaryIsInstance] tmpl = "revision property requires positive int, got '%s'" raise ValueError(tmpl % value) revision = self.get_or_add_revision() revision.text = str(value) @property - def subject_text(self): + def subject_text(self) -> str: return self._text_of_element("subject") @subject_text.setter - def subject_text(self, value): + def subject_text(self, value: str): self._set_element_text("subject", value) @property - def title_text(self): + def title_text(self) -> str: return self._text_of_element("title") @title_text.setter - def title_text(self, value): + def title_text(self, value: str): self._set_element_text("title", value) @property - def version_text(self): + def version_text(self) -> str: return self._text_of_element("version") @version_text.setter - def version_text(self, value): + def version_text(self, value: str): self._set_element_text("version", value) - def _datetime_of_element(self, property_name): + def _datetime_of_element(self, property_name: str) -> dt.datetime | None: element = getattr(self, property_name) if element is None: return None @@ -206,20 +201,18 @@ def _datetime_of_element(self, property_name): # invalid datetime strings are ignored return None - def _get_or_add(self, prop_name): - """ - Return element returned by 'get_or_add_' method for *prop_name*. - """ - get_or_add_method_name = f"get_or_add_{prop_name}" + def _get_or_add(self, prop_name: str) -> BaseOxmlElement: + """Return element returned by "get_or_add_" method for `prop_name`.""" + get_or_add_method_name = "get_or_add_%s" % prop_name get_or_add_method = getattr(self, get_or_add_method_name) - return get_or_add_method() + element = get_or_add_method() + return element @classmethod - def _offset_dt(cls, dt, offset_str): - """ - Return a |datetime| instance that is offset from datetime *dt* by - the timezone offset specified in *offset_str*, a string like - ``'-07:00'``. + def _offset_dt(cls, dt_: dt.datetime, offset_str: str) -> dt.datetime: + """A |datetime| instance offset from `dt_` by timezone offset in `offset_str`. + + `offset_str` is like `"-07:00"`. """ match = cls._offset_pattern.match(offset_str) if match is None: @@ -228,19 +221,19 @@ def _offset_dt(cls, dt, offset_str): sign_factor = -1 if sign == "+" else 1 hours = int(hours_str) * sign_factor minutes = int(minutes_str) * sign_factor - td = timedelta(hours=hours, minutes=minutes) - return dt + td + td = dt.timedelta(hours=hours, minutes=minutes) + return dt_ + td _offset_pattern = re.compile(r"([+-])(\d\d):(\d\d)") @classmethod - def _parse_W3CDTF_to_datetime(cls, w3cdtf_str): + def _parse_W3CDTF_to_datetime(cls, w3cdtf_str: str) -> dt.datetime: # valid W3CDTF date cases: - # yyyy e.g. '2003' - # yyyy-mm e.g. '2003-12' - # yyyy-mm-dd e.g. '2003-12-31' - # UTC timezone e.g. '2003-12-31T10:14:55Z' - # numeric timezone e.g. '2003-12-31T10:14:55-08:00' + # yyyy e.g. "2003" + # yyyy-mm e.g. "2003-12" + # yyyy-mm-dd e.g. "2003-12-31" + # UTC timezone e.g. "2003-12-31T10:14:55Z" + # numeric timezone e.g. "2003-12-31T10:14:55-08:00" templates = ( "%Y-%m-%dT%H:%M:%S", "%Y-%m-%d", @@ -248,34 +241,32 @@ def _parse_W3CDTF_to_datetime(cls, w3cdtf_str): "%Y", ) # strptime isn't smart enough to parse literal timezone offsets like - # '-07:30', so we have to do it ourselves + # "-07:30", so we have to do it ourselves parseable_part = w3cdtf_str[:19] offset_str = w3cdtf_str[19:] - dt = None + dt_ = None for tmpl in templates: try: - dt = datetime.strptime(parseable_part, tmpl) + dt_ = dt.datetime.strptime(parseable_part, tmpl) except ValueError: continue - if dt is None: + if dt_ is None: tmpl = "could not parse W3CDTF datetime string '%s'" raise ValueError(tmpl % w3cdtf_str) if len(offset_str) == 6: - return cls._offset_dt(dt, offset_str) - return dt + dt_ = cls._offset_dt(dt_, offset_str) + return dt_.replace(tzinfo=dt.timezone.utc) - def _set_element_datetime(self, prop_name, value): - """ - Set date/time value of child element having *prop_name* to *value*. - """ - if not isinstance(value, datetime): + def _set_element_datetime(self, prop_name: str, value: dt.datetime) -> None: + """Set date/time value of child element having `prop_name` to `value`.""" + if not isinstance(value, dt.datetime): # pyright: ignore[reportUnnecessaryIsInstance] tmpl = "property requires object, got %s" raise ValueError(tmpl % type(value)) element = self._get_or_add(prop_name) dt_str = value.strftime("%Y-%m-%dT%H:%M:%SZ") element.text = dt_str if prop_name in ("created", "modified"): - # These two require an explicit 'xsi:type="dcterms:W3CDTF"' + # These two require an explicit "xsi:type="dcterms:W3CDTF"" # attribute. The first and last line are a hack required to add # the xsi namespace to the root element rather than each child # element in which it is referenced @@ -283,9 +274,9 @@ def _set_element_datetime(self, prop_name, value): element.set(qn("xsi:type"), "dcterms:W3CDTF") del self.attrib[qn("xsi:foo")] - def _set_element_text(self, prop_name, value): - """Set string value of *name* property to *value*.""" - if not is_string(value): + def _set_element_text(self, prop_name: str, value: Any) -> None: + """Set string value of `name` property to `value`.""" + if not isinstance(value, str): value = str(value) if len(value) > 255: @@ -294,10 +285,10 @@ def _set_element_text(self, prop_name, value): element = self._get_or_add(prop_name) element.text = value - def _text_of_element(self, property_name): - """ - Return the text in the element matching *property_name*, or an empty - string if the element is not present or contains no text. + def _text_of_element(self, property_name: str) -> str: + """The text in the element matching `property_name`. + + The empty string if the element is not present or contains no text. """ element = getattr(self, property_name) if element is None: diff --git a/docx/oxml/customprops.py b/src/docx/oxml/customprops.py similarity index 100% rename from docx/oxml/customprops.py rename to src/docx/oxml/customprops.py diff --git a/src/docx/oxml/dml/CT_ExtensionList.py b/src/docx/oxml/dml/CT_ExtensionList.py new file mode 100644 index 00000000..5897765e --- /dev/null +++ b/src/docx/oxml/dml/CT_ExtensionList.py @@ -0,0 +1,48 @@ +# pyright: reportPrivateUsage=false + +"""This module is for elements which has extLst child.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Any, cast + +from docx.oxml.ns import nsdecls, qn +from docx.oxml.parser import parse_xml +from docx.oxml.xmlchemy import BaseOxmlElement, ZeroOrOne + +if TYPE_CHECKING: + from docx.oxml.shape import CT_Extension + + +class CT_ExtensionList(BaseOxmlElement): + """Base class for `extLst` element in DrawingML.""" + + ext: CT_Extension = ZeroOrOne("a:ext") + _add_ext: Any + + @classmethod + def new(cls): + """Return a new `extLst` element.""" + extLst = cast( + CT_ExtensionList, + parse_xml(f""), + ) + extLst._add_ext() + return extLst + + +class CT_Extension(BaseOxmlElement): + """ + `` element in `extLst`, which can hold a `svgBlip` element. + """ + + @property + def svgBlip(self) -> "CT_Transform2D": + from docx.oxml.shape import CT_Transform2D + + return self.xpath("./asvg:svgBlip")[0] + + @classmethod + def new(cls): + """Return a new `ext` element.""" + return cast(CT_Extension, parse_xml(f"")) diff --git a/src/docx/oxml/document.py b/src/docx/oxml/document.py new file mode 100644 index 00000000..36819ef7 --- /dev/null +++ b/src/docx/oxml/document.py @@ -0,0 +1,88 @@ +"""Custom element classes that correspond to the document part, e.g. .""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Callable, List + +from docx.oxml.section import CT_SectPr +from docx.oxml.xmlchemy import BaseOxmlElement, ZeroOrMore, ZeroOrOne + +if TYPE_CHECKING: + from docx.oxml.table import CT_Tbl + from docx.oxml.text.paragraph import CT_P + + +class CT_Document(BaseOxmlElement): + """```` element, the root element of a document.xml file.""" + + body: CT_Body = ZeroOrOne("w:body") # pyright: ignore[reportAssignmentType] + + @property + def sectPr_lst(self) -> List[CT_SectPr]: + """All `w:sectPr` elements directly accessible from document element. + + Note this does not include a `sectPr` child in a paragraphs wrapped in + revision marks or other intervening layer, perhaps `w:sdt` or customXml + elements. + + `w:sectPr` elements appear in document order. The last one is always + `w:body/w:sectPr`, all preceding are `w:p/w:pPr/w:sectPr`. + """ + xpath = "./w:body/w:p/w:pPr/w:sectPr | ./w:body/w:sectPr" + return self.xpath(xpath) + + +class CT_Body(BaseOxmlElement): + """`w:body`, the container element for the main document story in `document.xml`.""" + + add_p: Callable[[], CT_P] + get_or_add_sectPr: Callable[[], CT_SectPr] + p_lst: List[CT_P] + tbl_lst: List[CT_Tbl] + + _insert_tbl: Callable[[CT_Tbl], CT_Tbl] + + p = ZeroOrMore("w:p", successors=("w:sectPr",)) + tbl = ZeroOrMore("w:tbl", successors=("w:sectPr",)) + sectPr: CT_SectPr | None = ZeroOrOne( # pyright: ignore[reportAssignmentType] + "w:sectPr", successors=() + ) + + def add_section_break(self) -> CT_SectPr: + """Return `w:sectPr` element for new section added at end of document. + + The last `w:sectPr` becomes the second-to-last, with the new `w:sectPr` being an + exact clone of the previous one, except that all header and footer references + are removed (and are therefore now "inherited" from the prior section). + + A copy of the previously-last `w:sectPr` will now appear in a new `w:p` at the + end of the document. The returned `w:sectPr` is the sentinel `w:sectPr` for the + document (and as implemented, `is` the prior sentinel `w:sectPr` with headers + and footers removed). + """ + # ---get the sectPr at file-end, which controls last section (sections[-1])--- + sentinel_sectPr = self.get_or_add_sectPr() + # ---add exact copy to new `w:p` element; that is now second-to last section--- + self.add_p().set_sectPr(sentinel_sectPr.clone()) + # ---remove any header or footer references from "new" last section--- + for hdrftr_ref in sentinel_sectPr.xpath("w:headerReference|w:footerReference"): + sentinel_sectPr.remove(hdrftr_ref) + # ---the sentinel `w:sectPr` now controls the new last section--- + return sentinel_sectPr + + def clear_content(self): + """Remove all content child elements from this element. + + Leave the element if it is present. + """ + for content_elm in self.xpath("./*[not(self::w:sectPr)]"): + self.remove(content_elm) + + @property + def inner_content_elements(self) -> List[CT_P | CT_Tbl]: + """Generate all `w:p` and `w:tbl` elements in this document-body. + + Elements appear in document order. Elements shaded by nesting in a `w:ins` or + other "wrapper" element will not be included. + """ + return self.xpath("./w:p | ./w:tbl") diff --git a/src/docx/oxml/drawing.py b/src/docx/oxml/drawing.py new file mode 100644 index 00000000..5b627f97 --- /dev/null +++ b/src/docx/oxml/drawing.py @@ -0,0 +1,11 @@ +"""Custom element-classes for DrawingML-related elements like ``. + +For legacy reasons, many DrawingML-related elements are in `docx.oxml.shape`. Expect +those to move over here as we have reason to touch them. +""" + +from docx.oxml.xmlchemy import BaseOxmlElement + + +class CT_Drawing(BaseOxmlElement): + """`` element, containing a DrawingML object like a picture or chart.""" diff --git a/src/docx/oxml/exceptions.py b/src/docx/oxml/exceptions.py new file mode 100644 index 00000000..8919239a --- /dev/null +++ b/src/docx/oxml/exceptions.py @@ -0,0 +1,10 @@ +"""Exceptions for oxml sub-package.""" + + +class XmlchemyError(Exception): + """Generic error class.""" + + +class InvalidXmlError(XmlchemyError): + """Raised when invalid XML is encountered, such as on attempt to access a missing + required child element.""" diff --git a/docx/oxml/ns.py b/src/docx/oxml/ns.py similarity index 52% rename from docx/oxml/ns.py rename to src/docx/oxml/ns.py index 4436ccbd..4fe156fe 100644 --- a/docx/oxml/ns.py +++ b/src/docx/oxml/ns.py @@ -1,9 +1,8 @@ -""" -Namespace-related objects. -""" +"""Namespace-related objects.""" -from __future__ import absolute_import, print_function, unicode_literals +from __future__ import annotations +from typing import Dict nsmap = { "a": "http://schemas.openxmlformats.org/drawingml/2006/main", @@ -30,85 +29,82 @@ class NamespacePrefixedTag(str): - """ - Value object that knows the semantics of an XML tag having a namespace - prefix. - """ + """Value object that knows the semantics of an XML tag having a namespace prefix.""" - def __new__(cls, nstag, *args): + def __new__(cls, nstag: str): return super(NamespacePrefixedTag, cls).__new__(cls, nstag) - def __init__(self, nstag): + def __init__(self, nstag: str): self._pfx, self._local_part = nstag.split(":") self._ns_uri = nsmap[self._pfx] @property - def clark_name(self): + def clark_name(self) -> str: return "{%s}%s" % (self._ns_uri, self._local_part) @classmethod - def from_clark_name(cls, clark_name): + def from_clark_name(cls, clark_name: str) -> NamespacePrefixedTag: nsuri, local_name = clark_name[1:].split("}") - nstag = f"{pfxmap[nsuri]}:{local_name}" + nstag = "%s:%s" % (pfxmap[nsuri], local_name) return cls(nstag) @property - def local_part(self): - """ - Return the local part of the tag as a string. E.g. 'foobar' is - returned for tag 'f:foobar'. + def local_part(self) -> str: + """The local part of this tag. + + E.g. "foobar" is returned for tag "f:foobar". """ return self._local_part @property - def nsmap(self): - """ - Return a dict having a single member, mapping the namespace prefix of - this tag to it's namespace name (e.g. {'f': 'http://foo/bar'}). This - is handy for passing to xpath calls and other uses. + def nsmap(self) -> Dict[str, str]: + """Single-member dict mapping prefix of this tag to it's namespace name. + + Example: `{"f": "http://foo/bar"}`. This is handy for passing to xpath calls + and other uses. """ return {self._pfx: self._ns_uri} @property - def nspfx(self): - """ - Return the string namespace prefix for the tag, e.g. 'f' is returned - for tag 'f:foobar'. + def nspfx(self) -> str: + """The namespace-prefix for this tag. + + For example, "f" is returned for tag "f:foobar". """ return self._pfx @property - def nsuri(self): - """ - Return the namespace URI for the tag, e.g. 'http://foo/bar' would be - returned for tag 'f:foobar' if the 'f' prefix maps to - 'http://foo/bar' in nsmap. + def nsuri(self) -> str: + """The namespace URI for this tag. + + For example, "http://foo/bar" would be returned for tag "f:foobar" if the "f" + prefix maps to "http://foo/bar" in nsmap. """ return self._ns_uri -def nsdecls(*prefixes): - """ - Return a string containing a namespace declaration for each of the - namespace prefix strings, e.g. 'p', 'ct', passed as *prefixes*. +def nsdecls(*prefixes: str) -> str: + """Namespace declaration including each namespace-prefix in `prefixes`. + + Handy for adding required namespace declarations to a tree root element. """ - return " ".join([f'xmlns:{pfx}="{nsmap[pfx]}"' for pfx in prefixes]) + return " ".join(['xmlns:%s="%s"' % (pfx, nsmap[pfx]) for pfx in prefixes]) -def nspfxmap(*nspfxs): - """ - Return a dict containing the subset namespace prefix mappings specified by - *nspfxs*. Any number of namespace prefixes can be supplied, e.g. - namespaces('a', 'r', 'p'). +def nspfxmap(*nspfxs: str) -> Dict[str, str]: + """Subset namespace-prefix mappings specified by *nspfxs*. + + Any number of namespace prefixes can be supplied, e.g. namespaces("a", "r", "p"). """ return {pfx: nsmap[pfx] for pfx in nspfxs} -def qn(tag): - """ - Stands for "qualified name", a utility function to turn a namespace - prefixed tag name into a Clark-notation qualified tag name for lxml. For - example, ``qn('p:cSld')`` returns ``'{http://schemas.../main}cSld'``. +def qn(tag: str) -> str: + """Stands for "qualified name". + + This utility function converts a familiar namespace-prefixed tag name like "w:p" + into a Clark-notation qualified tag name for lxml. For example, `qn("w:p")` returns + "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}p". """ prefix, tagroot = tag.split(":") uri = nsmap[prefix] diff --git a/docx/oxml/numbering.py b/src/docx/oxml/numbering.py similarity index 56% rename from docx/oxml/numbering.py rename to src/docx/oxml/numbering.py index d5297b2a..3512de65 100644 --- a/docx/oxml/numbering.py +++ b/src/docx/oxml/numbering.py @@ -1,13 +1,9 @@ -# encoding: utf-8 +"""Custom element classes related to the numbering part.""" -""" -Custom element classes related to the numbering part -""" - -from . import OxmlElement -from .shared import CT_DecimalNumber -from .simpletypes import ST_DecimalNumber -from .xmlchemy import ( +from docx.oxml.parser import OxmlElement +from docx.oxml.shared import CT_DecimalNumber +from docx.oxml.simpletypes import ST_DecimalNumber +from docx.oxml.xmlchemy import ( BaseOxmlElement, OneAndOnlyOne, RequiredAttribute, @@ -17,30 +13,23 @@ class CT_Num(BaseOxmlElement): - """ - ```` element, which represents a concrete list definition - instance, having a required child that references an - abstract numbering definition that defines most of the formatting details. - """ + """```` element, which represents a concrete list definition instance, having + a required child that references an abstract numbering definition + that defines most of the formatting details.""" abstractNumId = OneAndOnlyOne("w:abstractNumId") lvlOverride = ZeroOrMore("w:lvlOverride") numId = RequiredAttribute("w:numId", ST_DecimalNumber) def add_lvlOverride(self, ilvl): - """ - Return a newly added CT_NumLvl () element having its - ``ilvl`` attribute set to *ilvl*. - """ + """Return a newly added CT_NumLvl () element having its ``ilvl`` + attribute set to `ilvl`.""" return self._add_lvlOverride(ilvl=ilvl) @classmethod def new(cls, num_id, abstractNum_id): - """ - Return a new ```` element having numId of *num_id* and having - a ```` child with val attribute set to - *abstractNum_id*. - """ + """Return a new ```` element having numId of `num_id` and having a + ```` child with val attribute set to `abstractNum_id`.""" num = OxmlElement("w:num") num.numId = num_id abstractNumId = CT_DecimalNumber.new("w:abstractNumId", abstractNum_id) @@ -49,27 +38,21 @@ def new(cls, num_id, abstractNum_id): class CT_NumLvl(BaseOxmlElement): - """ - ```` element, which identifies a level in a list - definition to override with settings it contains. - """ + """```` element, which identifies a level in a list definition to + override with settings it contains.""" startOverride = ZeroOrOne("w:startOverride", successors=("w:lvl",)) ilvl = RequiredAttribute("w:ilvl", ST_DecimalNumber) def add_startOverride(self, val): - """ - Return a newly added CT_DecimalNumber element having tagname - ``w:startOverride`` and ``val`` attribute set to *val*. - """ + """Return a newly added CT_DecimalNumber element having tagname + ``w:startOverride`` and ``val`` attribute set to `val`.""" return self._add_startOverride(val=val) class CT_NumPr(BaseOxmlElement): - """ - A ```` element, a container for numbering properties applied to - a paragraph. - """ + """A ```` element, a container for numbering properties applied to a + paragraph.""" ilvl = ZeroOrOne("w:ilvl", successors=("w:numId", "w:numberingChange", "w:ins")) numId = ZeroOrOne("w:numId", successors=("w:numberingChange", "w:ins")) @@ -77,7 +60,7 @@ class CT_NumPr(BaseOxmlElement): # @ilvl.setter # def _set_ilvl(self, val): # """ - # Get or add a child and set its ``w:val`` attribute to *val*. + # Get or add a child and set its ``w:val`` attribute to `val`. # """ # ilvl = self.get_or_add_ilvl() # ilvl.val = val @@ -86,34 +69,28 @@ class CT_NumPr(BaseOxmlElement): # def numId(self, val): # """ # Get or add a child and set its ``w:val`` attribute to - # *val*. + # `val`. # """ # numId = self.get_or_add_numId() # numId.val = val class CT_Numbering(BaseOxmlElement): - """ - ```` element, the root element of a numbering part, i.e. - numbering.xml - """ + """```` element, the root element of a numbering part, i.e. + numbering.xml.""" num = ZeroOrMore("w:num", successors=("w:numIdMacAtCleanup",)) def add_num(self, abstractNum_id): - """ - Return a newly added CT_Num () element referencing the - abstract numbering definition identified by *abstractNum_id*. - """ + """Return a newly added CT_Num () element referencing the abstract + numbering definition identified by `abstractNum_id`.""" next_num_id = self._next_numId num = CT_Num.new(next_num_id, abstractNum_id) return self._insert_num(num) def num_having_numId(self, numId): - """ - Return the ```` child element having ``numId`` attribute - matching *numId*. - """ + """Return the ```` child element having ``numId`` attribute matching + `numId`.""" xpath = './w:num[@w:numId="%d"]' % numId try: return self.xpath(xpath)[0] @@ -122,11 +99,8 @@ def num_having_numId(self, numId): @property def _next_numId(self): - """ - The first ``numId`` unused by a ```` element, starting at - 1 and filling any gaps in numbering between existing ```` - elements. - """ + """The first ``numId`` unused by a ```` element, starting at 1 and + filling any gaps in numbering between existing ```` elements.""" numId_strs = self.xpath("./w:num/@w:numId") num_ids = [int(numId_str) for numId_str in numId_strs] for num in range(1, len(num_ids) + 2): diff --git a/src/docx/oxml/parser.py b/src/docx/oxml/parser.py new file mode 100644 index 00000000..e16ba30b --- /dev/null +++ b/src/docx/oxml/parser.py @@ -0,0 +1,62 @@ +# pyright: reportImportCycles=false + +"""XML parser for python-docx.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Dict, Type, cast + +from lxml import etree + +from docx.oxml.ns import NamespacePrefixedTag, nsmap + +if TYPE_CHECKING: + from docx.oxml.xmlchemy import BaseOxmlElement + + +# -- configure XML parser -- +element_class_lookup = etree.ElementNamespaceClassLookup() +oxml_parser = etree.XMLParser(remove_blank_text=True, resolve_entities=False) +oxml_parser.set_element_class_lookup(element_class_lookup) + + +def parse_xml(xml: str | bytes) -> "BaseOxmlElement": + """Root lxml element obtained by parsing XML character string `xml`. + + The custom parser is used, so custom element classes are produced for elements in + `xml` that have them. + """ + return cast("BaseOxmlElement", etree.fromstring(xml, oxml_parser)) + + +def register_element_cls(tag: str, cls: Type["BaseOxmlElement"]): + """Register an lxml custom element-class to use for `tag`. + + A instance of `cls` to be constructed when the oxml parser encounters an element + with matching `tag`. `tag` is a string of the form `nspfx:tagroot`, e.g. + `'w:document'`. + """ + nspfx, tagroot = tag.split(":") + namespace = element_class_lookup.get_namespace(nsmap[nspfx]) + namespace[tagroot] = cls + + +def OxmlElement( + nsptag_str: str, + attrs: Dict[str, str] | None = None, + nsdecls: Dict[str, str] | None = None, +) -> BaseOxmlElement | etree._Element: # pyright: ignore[reportPrivateUsage] + """Return a 'loose' lxml element having the tag specified by `nsptag_str`. + + The tag in `nsptag_str` must contain the standard namespace prefix, e.g. `a:tbl`. + The resulting element is an instance of the custom element class for this tag name + if one is defined. A dictionary of attribute values may be provided as `attrs`; they + are set if present. All namespaces defined in the dict `nsdecls` are declared in the + element using the key as the prefix and the value as the namespace name. If + `nsdecls` is not provided, a single namespace declaration is added based on the + prefix on `nsptag_str`. + """ + nsptag = NamespacePrefixedTag(nsptag_str) + if nsdecls is None: + nsdecls = nsptag.nsmap + return oxml_parser.makeelement(nsptag.clark_name, attrib=attrs, nsmap=nsdecls) diff --git a/src/docx/oxml/section.py b/src/docx/oxml/section.py new file mode 100644 index 00000000..71072e2d --- /dev/null +++ b/src/docx/oxml/section.py @@ -0,0 +1,537 @@ +"""Section-related custom element classes.""" + +from __future__ import annotations + +from copy import deepcopy +from typing import Callable, Iterator, List, Sequence, cast + +from lxml import etree +from typing_extensions import TypeAlias + +from docx.enum.section import WD_HEADER_FOOTER, WD_ORIENTATION, WD_SECTION_START +from docx.oxml.ns import nsmap +from docx.oxml.shared import CT_OnOff +from docx.oxml.simpletypes import ST_SignedTwipsMeasure, ST_TwipsMeasure, XsdString +from docx.oxml.table import CT_Tbl +from docx.oxml.text.paragraph import CT_P +from docx.oxml.xmlchemy import ( + BaseOxmlElement, + OptionalAttribute, + RequiredAttribute, + ZeroOrMore, + ZeroOrOne, +) +from docx.shared import Length, lazyproperty + +BlockElement: TypeAlias = "CT_P | CT_Tbl" + + +class CT_HdrFtr(BaseOxmlElement): + """`w:hdr` and `w:ftr`, the root element for header and footer part respectively.""" + + add_p: Callable[[], CT_P] + p_lst: List[CT_P] + tbl_lst: List[CT_Tbl] + + _insert_tbl: Callable[[CT_Tbl], CT_Tbl] + + p = ZeroOrMore("w:p", successors=()) + tbl = ZeroOrMore("w:tbl", successors=()) + + @property + def inner_content_elements(self) -> List[CT_P | CT_Tbl]: + """Generate all `w:p` and `w:tbl` elements in this header or footer. + + Elements appear in document order. Elements shaded by nesting in a `w:ins` or + other "wrapper" element will not be included. + """ + return self.xpath("./w:p | ./w:tbl") + + +class CT_HdrFtrRef(BaseOxmlElement): + """`w:headerReference` and `w:footerReference` elements.""" + + type_: WD_HEADER_FOOTER = RequiredAttribute( # pyright: ignore[reportAssignmentType] + "w:type", WD_HEADER_FOOTER + ) + rId: str = RequiredAttribute("r:id", XsdString) # pyright: ignore[reportAssignmentType] + + +class CT_PageMar(BaseOxmlElement): + """```` element, defining page margins.""" + + top: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:top", ST_SignedTwipsMeasure + ) + right: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:right", ST_TwipsMeasure + ) + bottom: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:bottom", ST_SignedTwipsMeasure + ) + left: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:left", ST_TwipsMeasure + ) + header: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:header", ST_TwipsMeasure + ) + footer: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:footer", ST_TwipsMeasure + ) + gutter: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:gutter", ST_TwipsMeasure + ) + + +class CT_PageSz(BaseOxmlElement): + """```` element, defining page dimensions and orientation.""" + + w: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:w", ST_TwipsMeasure + ) + h: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:h", ST_TwipsMeasure + ) + orient: WD_ORIENTATION = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:orient", WD_ORIENTATION, default=WD_ORIENTATION.PORTRAIT + ) + + +class CT_SectPr(BaseOxmlElement): + """`w:sectPr` element, the container element for section properties.""" + + get_or_add_pgMar: Callable[[], CT_PageMar] + get_or_add_pgSz: Callable[[], CT_PageSz] + get_or_add_titlePg: Callable[[], CT_OnOff] + get_or_add_type: Callable[[], CT_SectType] + _add_footerReference: Callable[[], CT_HdrFtrRef] + _add_headerReference: Callable[[], CT_HdrFtrRef] + _remove_titlePg: Callable[[], None] + _remove_type: Callable[[], None] + + _tag_seq = ( + "w:footnotePr", + "w:endnotePr", + "w:type", + "w:pgSz", + "w:pgMar", + "w:paperSrc", + "w:pgBorders", + "w:lnNumType", + "w:pgNumType", + "w:cols", + "w:formProt", + "w:vAlign", + "w:noEndnote", + "w:titlePg", + "w:textDirection", + "w:bidi", + "w:rtlGutter", + "w:docGrid", + "w:printerSettings", + "w:sectPrChange", + ) + headerReference = ZeroOrMore("w:headerReference", successors=_tag_seq) + footerReference = ZeroOrMore("w:footerReference", successors=_tag_seq) + type: CT_SectType | None = ZeroOrOne( # pyright: ignore[reportAssignmentType] + "w:type", successors=_tag_seq[3:] + ) + pgSz: CT_PageSz | None = ZeroOrOne( # pyright: ignore[reportAssignmentType] + "w:pgSz", successors=_tag_seq[4:] + ) + pgMar: CT_PageMar | None = ZeroOrOne( # pyright: ignore[reportAssignmentType] + "w:pgMar", successors=_tag_seq[5:] + ) + titlePg: CT_OnOff | None = ZeroOrOne( # pyright: ignore[reportAssignmentType] + "w:titlePg", successors=_tag_seq[14:] + ) + del _tag_seq + + def add_footerReference(self, type_: WD_HEADER_FOOTER, rId: str) -> CT_HdrFtrRef: + """Return newly added CT_HdrFtrRef element of `type_` with `rId`. + + The element tag is `w:footerReference`. + """ + footerReference = self._add_footerReference() + footerReference.type_ = type_ + footerReference.rId = rId + return footerReference + + def add_headerReference(self, type_: WD_HEADER_FOOTER, rId: str) -> CT_HdrFtrRef: + """Return newly added CT_HdrFtrRef element of `type_` with `rId`. + + The element tag is `w:headerReference`. + """ + headerReference = self._add_headerReference() + headerReference.type_ = type_ + headerReference.rId = rId + return headerReference + + @property + def bottom_margin(self) -> Length | None: + """Value of the `w:bottom` attr of `` child element, as |Length|. + + |None| when either the element or the attribute is not present. + """ + pgMar = self.pgMar + if pgMar is None: + return None + return pgMar.bottom + + @bottom_margin.setter + def bottom_margin(self, value: int | Length | None): + pgMar = self.get_or_add_pgMar() + pgMar.bottom = value if value is None or isinstance(value, Length) else Length(value) + + def clone(self) -> CT_SectPr: + """Return an exact duplicate of this ```` element tree suitable for + use in adding a section break. + + All rsid* attributes are removed from the root ```` element. + """ + cloned_sectPr = deepcopy(self) + cloned_sectPr.attrib.clear() + return cloned_sectPr + + @property + def footer(self) -> Length | None: + """Distance from bottom edge of page to bottom edge of the footer. + + This is the value of the `w:footer` attribute in the `w:pgMar` child element, + as a |Length| object, or |None| if either the element or the attribute is not + present. + """ + pgMar = self.pgMar + if pgMar is None: + return None + return pgMar.footer + + @footer.setter + def footer(self, value: int | Length | None): + pgMar = self.get_or_add_pgMar() + pgMar.footer = value if value is None or isinstance(value, Length) else Length(value) + + def get_footerReference(self, type_: WD_HEADER_FOOTER) -> CT_HdrFtrRef | None: + """Return footerReference element of `type_` or None if not present.""" + path = "./w:footerReference[@w:type='%s']" % WD_HEADER_FOOTER.to_xml(type_) + footerReferences = self.xpath(path) + if not footerReferences: + return None + return footerReferences[0] + + def get_headerReference(self, type_: WD_HEADER_FOOTER) -> CT_HdrFtrRef | None: + """Return headerReference element of `type_` or None if not present.""" + matching_headerReferences = self.xpath( + "./w:headerReference[@w:type='%s']" % WD_HEADER_FOOTER.to_xml(type_) + ) + if len(matching_headerReferences) == 0: + return None + return matching_headerReferences[0] + + @property + def gutter(self) -> Length | None: + """The value of the ``w:gutter`` attribute in the ```` child element, + as a |Length| object, or |None| if either the element or the attribute is not + present.""" + pgMar = self.pgMar + if pgMar is None: + return None + return pgMar.gutter + + @gutter.setter + def gutter(self, value: int | Length | None): + pgMar = self.get_or_add_pgMar() + pgMar.gutter = value if value is None or isinstance(value, Length) else Length(value) + + @property + def header(self) -> Length | None: + """Distance from top edge of page to top edge of header. + + This value comes from the `w:header` attribute on the `w:pgMar` child element. + |None| if either the element or the attribute is not present. + """ + pgMar = self.pgMar + if pgMar is None: + return None + return pgMar.header + + @header.setter + def header(self, value: int | Length | None): + pgMar = self.get_or_add_pgMar() + pgMar.header = value if value is None or isinstance(value, Length) else Length(value) + + def iter_inner_content(self) -> Iterator[CT_P | CT_Tbl]: + """Generate all `w:p` and `w:tbl` elements in this section. + + Elements appear in document order. Elements shaded by nesting in a `w:ins` or + other "wrapper" element will not be included. + """ + return _SectBlockElementIterator.iter_sect_block_elements(self) + + @property + def left_margin(self) -> Length | None: + """The value of the ``w:left`` attribute in the ```` child element, as + a |Length| object, or |None| if either the element or the attribute is not + present.""" + pgMar = self.pgMar + if pgMar is None: + return None + return pgMar.left + + @left_margin.setter + def left_margin(self, value: int | Length | None): + pgMar = self.get_or_add_pgMar() + pgMar.left = value if value is None or isinstance(value, Length) else Length(value) + + @property + def orientation(self) -> WD_ORIENTATION: + """`WD_ORIENTATION` member indicating page-orientation for this section. + + This is the value of the `orient` attribute on the `w:pgSz` child, or + `WD_ORIENTATION.PORTRAIT` if not present. + """ + pgSz = self.pgSz + if pgSz is None: + return WD_ORIENTATION.PORTRAIT + return pgSz.orient + + @orientation.setter + def orientation(self, value: WD_ORIENTATION | None): + pgSz = self.get_or_add_pgSz() + pgSz.orient = value if value else WD_ORIENTATION.PORTRAIT + + @property + def page_height(self) -> Length | None: + """Value in EMU of the `h` attribute of the `w:pgSz` child element. + + |None| if not present. + """ + pgSz = self.pgSz + if pgSz is None: + return None + return pgSz.h + + @page_height.setter + def page_height(self, value: Length | None): + pgSz = self.get_or_add_pgSz() + pgSz.h = value + + @property + def page_width(self) -> Length | None: + """Value in EMU of the ``w`` attribute of the ```` child element. + + |None| if not present. + """ + pgSz = self.pgSz + if pgSz is None: + return None + return pgSz.w + + @page_width.setter + def page_width(self, value: Length | None): + pgSz = self.get_or_add_pgSz() + pgSz.w = value + + @property + def preceding_sectPr(self) -> CT_SectPr | None: + """SectPr immediately preceding this one or None if this is the first.""" + # -- [1] predicate returns list of zero or one value -- + preceding_sectPrs = self.xpath("./preceding::w:sectPr[1]") + return preceding_sectPrs[0] if len(preceding_sectPrs) > 0 else None + + def remove_footerReference(self, type_: WD_HEADER_FOOTER) -> str: + """Return rId of w:footerReference child of `type_` after removing it.""" + footerReference = self.get_footerReference(type_) + if footerReference is None: + # -- should never happen, but to satisfy type-check and just in case -- + raise ValueError("CT_SectPr has no footer reference") + rId = footerReference.rId + self.remove(footerReference) + return rId + + def remove_headerReference(self, type_: WD_HEADER_FOOTER): + """Return rId of w:headerReference child of `type_` after removing it.""" + headerReference = self.get_headerReference(type_) + if headerReference is None: + # -- should never happen, but to satisfy type-check and just in case -- + raise ValueError("CT_SectPr has no header reference") + rId = headerReference.rId + self.remove(headerReference) + return rId + + @property + def right_margin(self) -> Length | None: + """The value of the ``w:right`` attribute in the ```` child element, as + a |Length| object, or |None| if either the element or the attribute is not + present.""" + pgMar = self.pgMar + if pgMar is None: + return None + return pgMar.right + + @right_margin.setter + def right_margin(self, value: Length | None): + pgMar = self.get_or_add_pgMar() + pgMar.right = value + + @property + def start_type(self) -> WD_SECTION_START: + """The member of the ``WD_SECTION_START`` enumeration corresponding to the value + of the ``val`` attribute of the ```` child element, or + ``WD_SECTION_START.NEW_PAGE`` if not present.""" + type = self.type + if type is None or type.val is None: + return WD_SECTION_START.NEW_PAGE + return type.val + + @start_type.setter + def start_type(self, value: WD_SECTION_START | None): + if value is None or value is WD_SECTION_START.NEW_PAGE: + self._remove_type() + return + type = self.get_or_add_type() + type.val = value + + @property + def titlePg_val(self) -> bool: + """Value of `w:titlePg/@val` or |False| if `./w:titlePg` is not present.""" + titlePg = self.titlePg + if titlePg is None: + return False + return titlePg.val + + @titlePg_val.setter + def titlePg_val(self, value: bool | None): + if value in [None, False]: + self._remove_titlePg() + else: + self.get_or_add_titlePg().val = True + + @property + def top_margin(self) -> Length | None: + """The value of the ``w:top`` attribute in the ```` child element, as a + |Length| object, or |None| if either the element or the attribute is not + present.""" + pgMar = self.pgMar + if pgMar is None: + return None + return pgMar.top + + @top_margin.setter + def top_margin(self, value: Length | None): + pgMar = self.get_or_add_pgMar() + pgMar.top = value + + +class CT_SectType(BaseOxmlElement): + """```` element, defining the section start type.""" + + val: WD_SECTION_START | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:val", WD_SECTION_START + ) + + +# == HELPERS ========================================================================= + + +class _SectBlockElementIterator: + """Generates the block-item XML elements in a section. + + A block-item element is a `CT_P` (paragraph) or a `CT_Tbl` (table). + """ + + _compiled_blocks_xpath: etree.XPath | None = None + _compiled_count_xpath: etree.XPath | None = None + + def __init__(self, sectPr: CT_SectPr): + self._sectPr = sectPr + + @classmethod + def iter_sect_block_elements(cls, sectPr: CT_SectPr) -> Iterator[BlockElement]: + """Generate each CT_P or CT_Tbl element within extents governed by `sectPr`.""" + return cls(sectPr)._iter_sect_block_elements() + + def _iter_sect_block_elements(self) -> Iterator[BlockElement]: + """Generate each CT_P or CT_Tbl element in section.""" + # -- General strategy is to get all block ( and ) elements from + # -- start of doc to and including this section, then compute the count of those + # -- elements that came from prior sections and skip that many to leave only the + # -- ones in this section. It's possible to express this "between here and + # -- there" (end of prior section and end of this one) concept in XPath, but it + # -- would be harder to follow because there are special cases (e.g. no prior + # -- section) and the boundary expressions are fairly hairy. I also believe it + # -- would be computationally more expensive than doing it this straighforward + # -- albeit (theoretically) slightly wasteful way. + + sectPr, sectPrs = self._sectPr, self._sectPrs + sectPr_idx = sectPrs.index(sectPr) + + # -- count block items belonging to prior sections -- + n_blks_to_skip = ( + 0 + if sectPr_idx == 0 + else self._count_of_blocks_in_and_above_section(sectPrs[sectPr_idx - 1]) + ) + + # -- and skip those in set of all blks from doc start to end of this section -- + for element in self._blocks_in_and_above_section(sectPr)[n_blks_to_skip:]: + yield element + + def _blocks_in_and_above_section(self, sectPr: CT_SectPr) -> Sequence[BlockElement]: + """All ps and tbls in section defined by `sectPr` and all prior sections.""" + if self._compiled_blocks_xpath is None: + self._compiled_blocks_xpath = etree.XPath( + self._blocks_in_and_above_section_xpath, + namespaces=nsmap, + regexp=False, + ) + xpath = self._compiled_blocks_xpath + # -- XPath callable results are Any (basically), so need a cast. -- + return cast(Sequence[BlockElement], xpath(sectPr)) + + @lazyproperty + def _blocks_in_and_above_section_xpath(self) -> str: + """XPath expr for ps and tbls in context of a sectPr and all prior sectPrs.""" + # -- "p_sect" is a section with sectPr located at w:p/w:pPr/w:sectPr. + # -- "body_sect" is a section with sectPr located at w:body/w:sectPr. The last + # -- section in the document is a "body_sect". All others are of the "p_sect" + # -- variety. "term" means "terminal", like the last p or tbl in the section. + # -- "pred" means "predecessor", like a preceding p or tbl in the section. + + # -- the terminal block in a p-based sect is the p the sectPr appears in -- + p_sect_term_block = "./parent::w:pPr/parent::w:p" + # -- the terminus of a body-based sect is the sectPr itself (not a block) -- + body_sect_term = "self::w:sectPr[parent::w:body]" + # -- all the ps and tbls preceding (but not including) the context node -- + pred_ps_and_tbls = "preceding-sibling::*[self::w:p | self::w:tbl]" + + # -- p_sect_term_block and body_sect_term(inus) are mutually exclusive. So the + # -- result is either the union of nodes found by the first two selectors or the + # -- nodes found by the last selector, never both. + return ( + # -- include the p containing a sectPr -- + f"{p_sect_term_block}" + # -- along with all the blocks that precede it -- + f" | {p_sect_term_block}/{pred_ps_and_tbls}" + # -- or all the preceding blocks if sectPr is body-based (last sectPr) -- + f" | {body_sect_term}/{pred_ps_and_tbls}" + ) + + def _count_of_blocks_in_and_above_section(self, sectPr: CT_SectPr) -> int: + """All ps and tbls in section defined by `sectPr` and all prior sections.""" + if self._compiled_count_xpath is None: + self._compiled_count_xpath = etree.XPath( + f"count({self._blocks_in_and_above_section_xpath})", + namespaces=nsmap, + regexp=False, + ) + xpath = self._compiled_count_xpath + # -- numeric XPath results are always float, so need an int() conversion -- + return int(cast(float, xpath(sectPr))) + + @lazyproperty + def _sectPrs(self) -> Sequence[CT_SectPr]: + """All w:sectPr elements in document, in document-order.""" + return self._sectPr.xpath( + "/w:document/w:body/w:p/w:pPr/w:sectPr | /w:document/w:body/w:sectPr", + ) diff --git a/docx/oxml/settings.py b/src/docx/oxml/settings.py similarity index 80% rename from docx/oxml/settings.py rename to src/docx/oxml/settings.py index 3fc72e27..d5bb41a6 100644 --- a/docx/oxml/settings.py +++ b/src/docx/oxml/settings.py @@ -1,14 +1,20 @@ -# encoding: utf-8 +"""Custom element classes related to document settings.""" -"""Custom element classes related to document settings""" +from __future__ import annotations -from __future__ import absolute_import, division, print_function, unicode_literals +from typing import TYPE_CHECKING, Callable from docx.oxml.xmlchemy import BaseOxmlElement, ZeroOrOne +if TYPE_CHECKING: + from docx.oxml.shared import CT_OnOff + class CT_Settings(BaseOxmlElement): - """`w:settings` element, root element for the settings part""" + """`w:settings` element, root element for the settings part.""" + + get_or_add_evenAndOddHeaders: Callable[[], CT_OnOff] + _remove_evenAndOddHeaders: Callable[[], None] _tag_seq = ( "w:writeProtection", @@ -110,20 +116,23 @@ class CT_Settings(BaseOxmlElement): "w:decimalSymbol", "w:listSeparator", ) - evenAndOddHeaders = ZeroOrOne("w:evenAndOddHeaders", successors=_tag_seq[48:]) + evenAndOddHeaders: CT_OnOff | None = ZeroOrOne( # pyright: ignore[reportAssignmentType] + "w:evenAndOddHeaders", successors=_tag_seq[48:] + ) del _tag_seq @property - def evenAndOddHeaders_val(self): - """value of `w:evenAndOddHeaders/@w:val` or |None| if not present.""" + def evenAndOddHeaders_val(self) -> bool: + """Value of `w:evenAndOddHeaders/@w:val` or |None| if not present.""" evenAndOddHeaders = self.evenAndOddHeaders if evenAndOddHeaders is None: return False return evenAndOddHeaders.val @evenAndOddHeaders_val.setter - def evenAndOddHeaders_val(self, value): - if value in [None, False]: + def evenAndOddHeaders_val(self, value: bool | None): + if value is None or value is False: self._remove_evenAndOddHeaders() - else: - self.get_or_add_evenAndOddHeaders().val = value + return + + self.get_or_add_evenAndOddHeaders().val = value diff --git a/docx/oxml/shape.py b/src/docx/oxml/shape.py similarity index 53% rename from docx/oxml/shape.py rename to src/docx/oxml/shape.py index 556ee782..863d32a7 100644 --- a/docx/oxml/shape.py +++ b/src/docx/oxml/shape.py @@ -1,13 +1,12 @@ -""" -Custom element classes for shape-related elements like ```` -""" +"""Custom element classes for shape-related elements like ``.""" -from docx.oxml import parse_xml -from docx.oxml.ns import nsdecls -from docx.oxml.xmlchemy import BaseOxmlElement, OneAndOnlyOne +from __future__ import annotations + +from typing import TYPE_CHECKING, Any, cast -from .ns import nsdecls -from .simpletypes import ( +from docx.oxml.ns import nsdecls +from docx.oxml.parser import parse_xml +from docx.oxml.simpletypes import ( ST_Coordinate, ST_DrawingElementId, ST_PositiveCoordinate, @@ -15,7 +14,7 @@ XsdString, XsdToken, ) -from .xmlchemy import ( +from docx.oxml.xmlchemy import ( BaseOxmlElement, OneAndOnlyOne, OptionalAttribute, @@ -23,79 +22,162 @@ ZeroOrOne, ) +if TYPE_CHECKING: + from docx.shared import Length + from docx.oxml.dml.CT_ExtensionList import CT_ExtensionList + + +class CT_Anchor(BaseOxmlElement): + """`` element, container for a floating image.""" + + extent: CT_PositiveSize2D = OneAndOnlyOne("wp:extent") # pyright: ignore[reportAssignmentType] + docPr: CT_NonVisualDrawingProps = OneAndOnlyOne( # pyright: ignore[reportAssignmentType] + "wp:docPr" + ) + graphic: CT_GraphicalObject = OneAndOnlyOne( # pyright: ignore[reportAssignmentType] + "a:graphic" + ) + + @classmethod + def new( + cls, + cx: Length, + cy: Length, + shape_id: int, + pic: CT_Picture, + pos_x: int | Length, + pos_y: int | Length, + ) -> CT_Anchor: + """Return a new ```` element populated with the values passed + as parameters. + """ + anchor = cast(CT_Anchor, parse_xml(cls._anchor_xml(pos_x, pos_y))) + anchor.extent.cx = cx + anchor.extent.cy = cy + anchor.docPr.id = shape_id + anchor.docPr.name = "Picture %d" % shape_id + anchor.graphic.graphicData.uri = ( + "http://schemas.openxmlformats.org/drawingml/2006/picture" + ) + anchor.graphic.graphicData._insert_pic(pic) + return anchor + + @classmethod + def new_pic_anchor( + cls, + shape_id: int, + rId: str, + filename: str, + cx: Length, + cy: Length, + pos_x: int | Length, + pos_y: int | Length, + ) -> CT_Anchor: + """Return a new `wp:anchor` element containing the `pic:pic` element + specified by the argument values. + """ + pic_id = 0 # Word doesn't seem to use this, but does not omit it + pic = CT_Picture.new(pic_id, filename, rId, cx, cy) + anchor = cls.new(cx, cy, shape_id, pic, pos_x, pos_y) + return anchor + + @classmethod + def _anchor_xml(cls, pos_x: int | Length, pos_y: int | Length): + return ( + '\n" + ' \n' + ' \n' + " %d\n" + " \n" + ' \n' + " %d\n" + " \n" + ' \n' + " \n" + ' \n' + " \n" + ' \n' + " \n" + " \n" + ' \n' + " \n" + "" % (nsdecls("wp", "a", "pic", "r"), int(pos_x), int(pos_y)) + ) + class CT_Blip(BaseOxmlElement): - """ - ```` element, specifies image source and adjustments such as - alpha and tint. - """ + """```` element, specifies image source and adjustments such as alpha and + tint.""" - embed = OptionalAttribute("r:embed", ST_RelationshipId) - link = OptionalAttribute("r:link", ST_RelationshipId) - extLst = ZeroOrOne("a:extLst") + embed: str | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "r:embed", ST_RelationshipId + ) + link: str | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "r:link", ST_RelationshipId + ) + extLst: CT_ExtensionList | None = ZeroOrOne("a:extLst") class CT_BlipFillProperties(BaseOxmlElement): - """ - ```` element, specifies picture properties - """ + """```` element, specifies picture properties.""" - blip = ZeroOrOne("a:blip", successors=("a:srcRect", "a:tile", "a:stretch")) + blip: CT_Blip = ZeroOrOne( # pyright: ignore[reportAssignmentType] + "a:blip", successors=("a:srcRect", "a:tile", "a:stretch") + ) class CT_GraphicalObject(BaseOxmlElement): - """ - ```` element, container for a DrawingML object - """ + """```` element, container for a DrawingML object.""" - graphicData = OneAndOnlyOne("a:graphicData") + graphicData: CT_GraphicalObjectData = OneAndOnlyOne( # pyright: ignore[reportAssignmentType] + "a:graphicData" + ) class CT_GraphicalObjectData(BaseOxmlElement): - """ - ```` element, container for the XML of a DrawingML object - """ + """```` element, container for the XML of a DrawingML object.""" - pic = ZeroOrOne("pic:pic") - uri = RequiredAttribute("uri", XsdToken) + pic: CT_Picture = ZeroOrOne("pic:pic") # pyright: ignore[reportAssignmentType] + uri: str = RequiredAttribute("uri", XsdToken) # pyright: ignore[reportAssignmentType] class CT_Inline(BaseOxmlElement): - """ - ```` element, container for an inline shape. - """ + """`` element, container for an inline shape.""" - extent = OneAndOnlyOne("wp:extent") - docPr = OneAndOnlyOne("wp:docPr") - graphic = OneAndOnlyOne("a:graphic") + extent: CT_PositiveSize2D = OneAndOnlyOne("wp:extent") # pyright: ignore[reportAssignmentType] + docPr: CT_NonVisualDrawingProps = OneAndOnlyOne( # pyright: ignore[reportAssignmentType] + "wp:docPr" + ) + graphic: CT_GraphicalObject = OneAndOnlyOne( # pyright: ignore[reportAssignmentType] + "a:graphic" + ) @classmethod - def new(cls, cx, cy, shape_id, pic): - """ - Return a new ```` element populated with the values passed - as parameters. - """ - inline = parse_xml(cls._inline_xml()) + def new(cls, cx: Length, cy: Length, shape_id: int, pic: CT_Picture) -> CT_Inline: + """Return a new ```` element populated with the values passed as + parameters.""" + inline = cast(CT_Inline, parse_xml(cls._inline_xml())) inline.extent.cx = cx inline.extent.cy = cy inline.docPr.id = shape_id inline.docPr.name = "Picture %d" % shape_id - inline.graphic.graphicData.uri = ( - "http://schemas.openxmlformats.org/drawingml/2006/picture" - ) + inline.graphic.graphicData.uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" inline.graphic.graphicData._insert_pic(pic) return inline @classmethod - def new_pic_inline(cls, shape_id, rId, filename, cx, cy): - """ - Return a new `wp:inline` element containing the `pic:pic` element - specified by the argument values. + def new_pic_inline( + cls, shape_id: int, rId: str, filename: str, cx: Length, cy: Length + ) -> CT_Inline: + """Create `wp:inline` element containing a `pic:pic` element. + + The contents of the `pic:pic` element is taken from the argument values. """ pic_id = 0 # Word doesn't seem to use this, but does not omit it pic = CT_Picture.new(pic_id, filename, rId, cx, cy) inline = cls.new(cx, cy, shape_id, pic) - inline.graphic.graphicData._insert_pic(pic) return inline @classmethod @@ -110,14 +192,22 @@ def _inline_xml(cls): " \n" ' \n' " \n" - "" % nsdecls("wp", "a", "pic", "r", "asvg") + "" % nsdecls("wp", "a", "pic", "r") ) -class CT_NonVisualDrawingProps(BaseOxmlElement): +class CT_Extension(BaseOxmlElement): """ - Used for ```` element, and perhaps others. Specifies the id and - name of a DrawingML drawing. + `` element in `extLst`, which can hold a `svgBlip` element. + """ + + svgBlip = ZeroOrOne("asvg:svgBlip") + + +class CT_NonVisualDrawingProps(BaseOxmlElement): + """Used for ```` element, and perhaps others. + + Specifies the id and name of a DrawingML drawing. """ id = RequiredAttribute("id", ST_DrawingElementId) @@ -125,34 +215,33 @@ class CT_NonVisualDrawingProps(BaseOxmlElement): class CT_NonVisualPictureProperties(BaseOxmlElement): - """ - ```` element, specifies picture locking and resize - behaviors. - """ + """```` element, specifies picture locking and resize behaviors.""" class CT_Picture(BaseOxmlElement): - """ - ```` element, a DrawingML picture - """ + """```` element, a DrawingML picture.""" - nvPicPr = OneAndOnlyOne("pic:nvPicPr") - blipFill = OneAndOnlyOne("pic:blipFill") - spPr = OneAndOnlyOne("pic:spPr") + nvPicPr: CT_PictureNonVisual = OneAndOnlyOne( # pyright: ignore[reportAssignmentType] + "pic:nvPicPr" + ) + blipFill: CT_BlipFillProperties = OneAndOnlyOne( # pyright: ignore[reportAssignmentType] + "pic:blipFill" + ) + spPr: CT_ShapeProperties = OneAndOnlyOne("pic:spPr") # pyright: ignore[reportAssignmentType] @classmethod - def new(cls, pic_id, filename, rId, cx, cy): - """ - Return a new ```` element populated with the minimal - contents required to define a viable picture element, based on the - values passed as parameters. - """ + def new(cls, pic_id: int, filename: str, rId: str, cx: Length, cy: Length) -> CT_Picture: + """A new minimum viable `` (picture) element.""" if filename.endswith(".svg"): - pic = parse_xml(cls._pic_xml_svg()) - pic.blipFill.blip.extLst.ext.svgBlip.embed = rId + pic = cast(CT_Picture, parse_xml(cls._pic_xml_svg())) + blip = pic.blipFill.blip + assert blip is not None + blip.extLst.ext.svgBlip.embed = rId else: - pic = parse_xml(cls._pic_xml()) - pic.blipFill.blip.embed = rId + pic = cast(CT_Picture, parse_xml(cls._pic_xml())) + blip = pic.blipFill.blip + assert blip is not None + blip.embed = rId pic.nvPicPr.cNvPr.id = pic_id pic.nvPicPr.cNvPr.name = filename pic.spPr.cx = cx @@ -215,17 +304,15 @@ def _pic_xml(cls): class CT_PictureNonVisual(BaseOxmlElement): - """ - ```` element, non-visual picture properties - """ + """```` element, non-visual picture properties.""" cNvPr = OneAndOnlyOne("pic:cNvPr") class CT_Point2D(BaseOxmlElement): - """ - Used for ```` element, and perhaps others. Specifies an x, y - coordinate (point). + """Used for ```` element, and perhaps others. + + Specifies an x, y coordinate (point). """ x = RequiredAttribute("x", ST_Coordinate) @@ -233,34 +320,31 @@ class CT_Point2D(BaseOxmlElement): class CT_PositiveSize2D(BaseOxmlElement): - """ - Used for ```` element, and perhaps others later. Specifies the - size of a DrawingML drawing. + """Used for ```` element, and perhaps others later. + + Specifies the size of a DrawingML drawing. """ - cx = RequiredAttribute("cx", ST_PositiveCoordinate) - cy = RequiredAttribute("cy", ST_PositiveCoordinate) - svgBlip = ZeroOrOne("asvg:svgBlip") + cx: Length = RequiredAttribute( # pyright: ignore[reportAssignmentType] + "cx", ST_PositiveCoordinate + ) + cy: Length = RequiredAttribute( # pyright: ignore[reportAssignmentType] + "cy", ST_PositiveCoordinate + ) class CT_PresetGeometry2D(BaseOxmlElement): - """ - ```` element, specifies an preset autoshape geometry, such - as ``rect``. - """ + """```` element, specifies an preset autoshape geometry, such as + ``rect``.""" class CT_RelativeRect(BaseOxmlElement): - """ - ```` element, specifying picture should fill containing - rectangle shape. - """ + """```` element, specifying picture should fill containing rectangle + shape.""" class CT_ShapeProperties(BaseOxmlElement): - """ - ```` element, specifies size and shape of picture container. - """ + """```` element, specifies size and shape of picture container.""" xfrm = ZeroOrOne( "a:xfrm", @@ -278,9 +362,7 @@ class CT_ShapeProperties(BaseOxmlElement): @property def cx(self): - """ - Shape width as an instance of Emu, or None if not present. - """ + """Shape width as an instance of Emu, or None if not present.""" xfrm = self.xfrm if xfrm is None: return None @@ -293,11 +375,11 @@ def cx(self, value): @property def cy(self): - """ - Shape height as an instance of Emu, or None if not present. - """ + """Shape height as an instance of Emu, or None if not present.""" xfrm = self.xfrm - return None if xfrm is None else xfrm.cy + if xfrm is None: + return None + return xfrm.cy @cy.setter def cy(self, value): @@ -306,25 +388,25 @@ def cy(self, value): class CT_StretchInfoProperties(BaseOxmlElement): - """ - ```` element, specifies how picture should fill its containing - shape. - """ + """```` element, specifies how picture should fill its containing + shape.""" class CT_Transform2D(BaseOxmlElement): - """ - ```` element, specifies size and shape of picture container. - """ + """```` element, specifies size and shape of picture container.""" off = ZeroOrOne("a:off", successors=("a:ext",)) ext = ZeroOrOne("a:ext", successors=()) - embed = OptionalAttribute("r:embed", ST_RelationshipId) + embed: str | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "r:embed", ST_RelationshipId + ) @property def cx(self): ext = self.ext - return None if ext is None else ext.cx + if ext is None: + return None + return ext.cx @cx.setter def cx(self, value): @@ -334,73 +416,11 @@ def cx(self, value): @property def cy(self): ext = self.ext - return None if ext is None else ext.cy + if ext is None: + return None + return ext.cy @cy.setter def cy(self, value): ext = self.get_or_add_ext() ext.cy = value - - -class CT_Anchor(BaseOxmlElement): - """ - ```` element, container for a floating image. - """ - - extent = OneAndOnlyOne("wp:extent") - docPr = OneAndOnlyOne("wp:docPr") - graphic = OneAndOnlyOne("a:graphic") - - @classmethod - def new(cls, cx, cy, shape_id, pic, pos_x, pos_y): - """ - Return a new ```` element populated with the values passed - as parameters. - """ - anchor = parse_xml(cls._anchor_xml(pos_x, pos_y)) - anchor.extent.cx = cx - anchor.extent.cy = cy - anchor.docPr.id = shape_id - anchor.docPr.name = "Picture %d" % shape_id - anchor.graphic.graphicData.uri = ( - "http://schemas.openxmlformats.org/drawingml/2006/picture" - ) - anchor.graphic.graphicData._insert_pic(pic) - return anchor - - @classmethod - def new_pic_anchor(cls, shape_id, rId, filename, cx, cy, pos_x, pos_y): - """ - Return a new `wp:anchor` element containing the `pic:pic` element - specified by the argument values. - """ - pic_id = 0 # Word doesn't seem to use this, but does not omit it - pic = CT_Picture.new(pic_id, filename, rId, cx, cy) - anchor = cls.new(cx, cy, shape_id, pic, pos_x, pos_y) - anchor.graphic.graphicData._insert_pic(pic) - return anchor - - @classmethod - def _anchor_xml(cls, pos_x, pos_y): - return ( - '\n" - ' \n' - ' \n' - " %d\n" - " \n" - ' \n' - " %d\n" - " \n" - ' \n' - " \n" - ' \n' - " \n" - ' \n' - " \n" - " \n" - ' \n' - " \n" - "" % (nsdecls("wp", "a", "pic", "r"), int(pos_x), int(pos_y)) - ) diff --git a/src/docx/oxml/shared.py b/src/docx/oxml/shared.py new file mode 100644 index 00000000..8cfcd2be --- /dev/null +++ b/src/docx/oxml/shared.py @@ -0,0 +1,52 @@ +"""Objects shared by modules in the docx.oxml subpackage.""" + +from __future__ import annotations + +from typing import cast + +from docx.oxml.ns import qn +from docx.oxml.parser import OxmlElement +from docx.oxml.simpletypes import ST_DecimalNumber, ST_OnOff, ST_String +from docx.oxml.xmlchemy import BaseOxmlElement, OptionalAttribute, RequiredAttribute + + +class CT_DecimalNumber(BaseOxmlElement): + """Used for ````, ````, ```` and several others, + containing a text representation of a decimal number (e.g. 42) in its ``val`` + attribute.""" + + val: int = RequiredAttribute("w:val", ST_DecimalNumber) # pyright: ignore[reportAssignmentType] + + @classmethod + def new(cls, nsptagname: str, val: int): + """Return a new ``CT_DecimalNumber`` element having tagname `nsptagname` and + ``val`` attribute set to `val`.""" + return OxmlElement(nsptagname, attrs={qn("w:val"): str(val)}) + + +class CT_OnOff(BaseOxmlElement): + """Used for `w:b`, `w:i` elements and others. + + Contains a bool-ish string in its `val` attribute, xsd:boolean plus "on" and + "off". Defaults to `True`, so `` for example means "bold is turned on". + """ + + val: bool = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:val", ST_OnOff, default=True + ) + + +class CT_String(BaseOxmlElement): + """Used for `w:pStyle` and `w:tblStyle` elements and others. + + In those cases, it containing a style name in its `val` attribute. + """ + + val: str = RequiredAttribute("w:val", ST_String) # pyright: ignore[reportAssignmentType] + + @classmethod + def new(cls, nsptagname: str, val: str): + """A new `CT_String`` element with tagname `nsptagname` and `val` attribute set to `val`.""" + elm = cast(CT_String, OxmlElement(nsptagname)) + elm.val = val + return elm diff --git a/docx/oxml/simpletypes.py b/src/docx/oxml/simpletypes.py similarity index 51% rename from docx/oxml/simpletypes.py rename to src/docx/oxml/simpletypes.py index 8fb6cb89..a0fc87d3 100644 --- a/docx/oxml/simpletypes.py +++ b/src/docx/oxml/simpletypes.py @@ -1,35 +1,54 @@ -# encoding: utf-8 +# pyright: reportImportCycles=false +"""Simple-type classes, corresponding to ST_* schema items. + +These provide validation and format translation for values stored in XML element +attributes. Naming generally corresponds to the simple type in the associated XML +schema. """ -Simple type classes, providing validation and format translation for values -stored in XML element attributes. Naming generally corresponds to the simple -type in the associated XML schema. -""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import annotations + +import datetime as dt +from typing import TYPE_CHECKING, Any, Tuple -from ..exceptions import InvalidXmlError -from ..shared import Emu, Pt, RGBColor, Twips +from docx.exceptions import InvalidXmlError +from docx.shared import Emu, Pt, RGBColor, Twips +if TYPE_CHECKING: + from docx.shared import Length + + +class BaseSimpleType: + """Base class for simple-types.""" -class BaseSimpleType(object): @classmethod - def from_xml(cls, str_value): - return cls.convert_from_xml(str_value) + def from_xml(cls, xml_value: str) -> Any: + return cls.convert_from_xml(xml_value) @classmethod - def to_xml(cls, value): + def to_xml(cls, value: Any) -> str: cls.validate(value) str_value = cls.convert_to_xml(value) return str_value @classmethod - def validate_int(cls, value): + def convert_from_xml(cls, str_value: str) -> Any: + return int(str_value) + + @classmethod + def convert_to_xml(cls, value: Any) -> str: ... + + @classmethod + def validate(cls, value: Any) -> None: ... + + @classmethod + def validate_int(cls, value: object): if not isinstance(value, int): raise TypeError("value must be , got %s" % type(value)) @classmethod - def validate_int_in_range(cls, value, min_inclusive, max_inclusive): + def validate_int_in_range(cls, value: int, min_inclusive: int, max_inclusive: int) -> None: cls.validate_int(value) if value < min_inclusive or value > max_inclusive: raise ValueError( @@ -38,64 +57,61 @@ def validate_int_in_range(cls, value, min_inclusive, max_inclusive): ) @classmethod - def validate_string(cls, value): - if isinstance(value, str): - return value - try: - if isinstance(value, basestring): - return value - except NameError: # means we're on Python 3 - pass - raise TypeError("value must be a string, got %s" % type(value)) + def validate_string(cls, value: Any) -> str: + if not isinstance(value, str): + raise TypeError("value must be a string, got %s" % type(value)) + return value class BaseIntType(BaseSimpleType): @classmethod - def convert_from_xml(cls, str_value): + def convert_from_xml(cls, str_value: str) -> int: return int(str_value) @classmethod - def convert_to_xml(cls, value): + def convert_to_xml(cls, value: int) -> str: return str(value) @classmethod - def validate(cls, value): + def validate(cls, value: Any) -> None: cls.validate_int(value) class BaseStringType(BaseSimpleType): @classmethod - def convert_from_xml(cls, str_value): + def convert_from_xml(cls, str_value: str) -> str: return str_value @classmethod - def convert_to_xml(cls, value): + def convert_to_xml(cls, value: str) -> str: return value @classmethod - def validate(cls, value): + def validate(cls, value: str): cls.validate_string(value) class BaseStringEnumerationType(BaseStringType): + _members: Tuple[str, ...] + @classmethod - def validate(cls, value): + def validate(cls, value: Any) -> None: cls.validate_string(value) if value not in cls._members: raise ValueError("must be one of %s, got '%s'" % (cls._members, value)) class XsdAnyUri(BaseStringType): - """ - There's a regular expression this is supposed to meet but so far thinking - spending cycles on validating wouldn't be worth it for the number of - programming errors it would catch. + """There's a regex in the spec this is supposed to meet... + + but current assessment is that spending cycles on validating wouldn't be worth it + for the number of programming errors it would catch. """ class XsdBoolean(BaseSimpleType): @classmethod - def convert_from_xml(cls, str_value): + def convert_from_xml(cls, str_value: str) -> bool: if str_value not in ("1", "0", "true", "false"): raise InvalidXmlError( "value must be one of '1', '0', 'true' or 'false', got '%s'" % str_value @@ -103,22 +119,21 @@ def convert_from_xml(cls, str_value): return str_value in ("1", "true") @classmethod - def convert_to_xml(cls, value): + def convert_to_xml(cls, value: bool) -> str: return {True: "1", False: "0"}[value] @classmethod - def validate(cls, value): + def validate(cls, value: Any) -> None: if value not in (True, False): raise TypeError( - "only True or False (and possibly None) may be assigned, got" - " '%s'" % value + "only True or False (and possibly None) may be assigned, got '%s'" % value ) class XsdId(BaseStringType): - """ - String that must begin with a letter or underscore and cannot contain any - colons. Not fully validated because not used in external API. + """String that must begin with a letter or underscore and cannot contain any colons. + + Not fully validated because not used in external API. """ pass @@ -126,13 +141,13 @@ class XsdId(BaseStringType): class XsdInt(BaseIntType): @classmethod - def validate(cls, value): + def validate(cls, value: Any) -> None: cls.validate_int_in_range(value, -2147483648, 2147483647) class XsdLong(BaseIntType): @classmethod - def validate(cls, value): + def validate(cls, value: Any) -> None: cls.validate_int_in_range(value, -9223372036854775808, 9223372036854775807) @@ -141,35 +156,31 @@ class XsdString(BaseStringType): class XsdStringEnumeration(BaseStringEnumerationType): - """ - Set of enumerated xsd:string values. - """ + """Set of enumerated xsd:string values.""" class XsdToken(BaseStringType): - """ - xsd:string with whitespace collapsing, e.g. multiple spaces reduced to - one, leading and trailing space stripped. - """ + """Xsd:string with whitespace collapsing, e.g. multiple spaces reduced to one, + leading and trailing space stripped.""" pass class XsdUnsignedInt(BaseIntType): @classmethod - def validate(cls, value): + def validate(cls, value: Any) -> None: cls.validate_int_in_range(value, 0, 4294967295) class XsdUnsignedLong(BaseIntType): @classmethod - def validate(cls, value): + def validate(cls, value: Any) -> None: cls.validate_int_in_range(value, 0, 18446744073709551615) class ST_BrClear(XsdString): @classmethod - def validate(cls, value): + def validate(cls, value: str) -> None: cls.validate_string(value) valid_values = ("none", "left", "right", "all") if value not in valid_values: @@ -178,7 +189,7 @@ def validate(cls, value): class ST_BrType(XsdString): @classmethod - def validate(cls, value): + def validate(cls, value: Any) -> None: cls.validate_string(value) valid_values = ("page", "column", "textWrapping") if value not in valid_values: @@ -187,22 +198,74 @@ def validate(cls, value): class ST_Coordinate(BaseIntType): @classmethod - def convert_from_xml(cls, str_value): + def convert_from_xml(cls, str_value: str) -> Length: if "i" in str_value or "m" in str_value or "p" in str_value: return ST_UniversalMeasure.convert_from_xml(str_value) return Emu(int(str_value)) @classmethod - def validate(cls, value): + def validate(cls, value: Any) -> None: ST_CoordinateUnqualified.validate(value) class ST_CoordinateUnqualified(XsdLong): @classmethod - def validate(cls, value): + def validate(cls, value: Any) -> None: cls.validate_int_in_range(value, -27273042329600, 27273042316900) +class ST_DateTime(BaseSimpleType): + @classmethod + def convert_from_xml(cls, str_value: str) -> dt.datetime: + """Convert an xsd:dateTime string to a datetime object.""" + + def parse_xsd_datetime(dt_str: str) -> dt.datetime: + # -- handle trailing 'Z' (Zulu/UTC), common in Word files -- + if dt_str.endswith("Z"): + try: + # -- optional fractional seconds case -- + return dt.datetime.strptime(dt_str, "%Y-%m-%dT%H:%M:%S.%fZ").replace( + tzinfo=dt.timezone.utc + ) + except ValueError: + return dt.datetime.strptime(dt_str, "%Y-%m-%dT%H:%M:%SZ").replace( + tzinfo=dt.timezone.utc + ) + + # -- handles explicit offsets like +00:00, -05:00, or naive datetimes -- + try: + return dt.datetime.fromisoformat(dt_str) + except ValueError: + # -- fall-back to parsing as naive datetime (with or without fractional seconds) -- + try: + return dt.datetime.strptime(dt_str, "%Y-%m-%dT%H:%M:%S.%f") + except ValueError: + return dt.datetime.strptime(dt_str, "%Y-%m-%dT%H:%M:%S") + + try: + # -- parse anything reasonable, but never raise, just use default epoch time -- + return parse_xsd_datetime(str_value) + except Exception: + return dt.datetime(1970, 1, 1, tzinfo=dt.timezone.utc) + + @classmethod + def convert_to_xml(cls, value: dt.datetime) -> str: + # -- convert naive datetime to timezon-aware assuming local timezone -- + if value.tzinfo is None: + value = value.astimezone() + + # -- convert to UTC if not already -- + value = value.astimezone(dt.timezone.utc) + + # -- format with 'Z' suffix for UTC -- + return value.strftime("%Y-%m-%dT%H:%M:%SZ") + + @classmethod + def validate(cls, value: Any) -> None: + if not isinstance(value, dt.datetime): + raise TypeError("only a datetime.datetime object may be assigned, got '%s'" % value) + + class ST_DecimalNumber(XsdInt): pass @@ -213,33 +276,32 @@ class ST_DrawingElementId(XsdUnsignedInt): class ST_HexColor(BaseStringType): @classmethod - def convert_from_xml(cls, str_value): + def convert_from_xml( # pyright: ignore[reportIncompatibleMethodOverride] + cls, str_value: str + ) -> RGBColor | str: if str_value == "auto": return ST_HexColorAuto.AUTO return RGBColor.from_string(str_value) @classmethod - def convert_to_xml(cls, value): - """ - Keep alpha hex numerals all uppercase just for consistency. - """ + def convert_to_xml( # pyright: ignore[reportIncompatibleMethodOverride] + cls, value: RGBColor + ) -> str: + """Keep alpha hex numerals all uppercase just for consistency.""" # expecting 3-tuple of ints in range 0-255 return "%02X%02X%02X" % value @classmethod - def validate(cls, value): + def validate(cls, value: Any) -> None: # must be an RGBColor object --- if not isinstance(value, RGBColor): raise ValueError( - "rgb color value must be RGBColor object, got %s %s" - % (type(value), value) + "rgb color value must be RGBColor object, got %s %s" % (type(value), value) ) class ST_HexColorAuto(XsdStringEnumeration): - """ - Value for `w:color/[@val="auto"] attribute setting - """ + """Value for `w:color/[@val="auto"] attribute setting.""" AUTO = "auto" @@ -247,27 +309,23 @@ class ST_HexColorAuto(XsdStringEnumeration): class ST_HpsMeasure(XsdUnsignedLong): - """ - Half-point measure, e.g. 24.0 represents 12.0 points. - """ + """Half-point measure, e.g. 24.0 represents 12.0 points.""" @classmethod - def convert_from_xml(cls, str_value): + def convert_from_xml(cls, str_value: str) -> Length: if "m" in str_value or "n" in str_value or "p" in str_value: return ST_UniversalMeasure.convert_from_xml(str_value) return Pt(int(str_value) / 2.0) @classmethod - def convert_to_xml(cls, value): + def convert_to_xml(cls, value: int | Length) -> str: emu = Emu(value) half_points = int(emu.pt * 2) return str(half_points) class ST_Merge(XsdStringEnumeration): - """ - Valid values for attribute - """ + """Valid values for attribute.""" CONTINUE = "continue" RESTART = "restart" @@ -277,7 +335,7 @@ class ST_Merge(XsdStringEnumeration): class ST_OnOff(XsdBoolean): @classmethod - def convert_from_xml(cls, str_value): + def convert_from_xml(cls, str_value: str) -> bool: if str_value not in ("1", "0", "true", "false", "on", "off"): raise InvalidXmlError( "value must be one of '1', '0', 'true', 'false', 'on', or 'o" @@ -288,11 +346,11 @@ def convert_from_xml(cls, str_value): class ST_PositiveCoordinate(XsdLong): @classmethod - def convert_from_xml(cls, str_value): + def convert_from_xml(cls, str_value: str) -> Length: return Emu(int(str_value)) @classmethod - def validate(cls, value): + def validate(cls, value: Any) -> None: cls.validate_int_in_range(value, 0, 27273042316900) @@ -302,13 +360,13 @@ class ST_RelationshipId(XsdString): class ST_SignedTwipsMeasure(XsdInt): @classmethod - def convert_from_xml(cls, str_value): + def convert_from_xml(cls, str_value: str) -> Length: if "i" in str_value or "m" in str_value or "p" in str_value: return ST_UniversalMeasure.convert_from_xml(str_value) - return Twips(int(str_value)) + return Twips(int(round(float(str_value)))) @classmethod - def convert_to_xml(cls, value): + def convert_to_xml(cls, value: int | Length) -> str: emu = Emu(value) twips = emu.twips return str(twips) @@ -320,7 +378,7 @@ class ST_String(XsdString): class ST_TblLayoutType(XsdString): @classmethod - def validate(cls, value): + def validate(cls, value: Any) -> None: cls.validate_string(value) valid_values = ("fixed", "autofit") if value not in valid_values: @@ -329,7 +387,7 @@ def validate(cls, value): class ST_TblWidth(XsdString): @classmethod - def validate(cls, value): + def validate(cls, value: Any) -> None: cls.validate_string(value) valid_values = ("auto", "dxa", "nil", "pct") if value not in valid_values: @@ -338,13 +396,13 @@ def validate(cls, value): class ST_TwipsMeasure(XsdUnsignedLong): @classmethod - def convert_from_xml(cls, str_value): + def convert_from_xml(cls, str_value: str) -> Length: if "i" in str_value or "m" in str_value or "p" in str_value: return ST_UniversalMeasure.convert_from_xml(str_value) return Twips(int(str_value)) @classmethod - def convert_to_xml(cls, value): + def convert_to_xml(cls, value: int | Length) -> str: emu = Emu(value) twips = emu.twips return str(twips) @@ -352,7 +410,7 @@ def convert_to_xml(cls, value): class ST_UniversalMeasure(BaseSimpleType): @classmethod - def convert_from_xml(cls, str_value): + def convert_from_xml(cls, str_value: str) -> Emu: float_part, units_part = str_value[:-2], str_value[-2:] quantity = float(float_part) multiplier = { @@ -363,14 +421,11 @@ def convert_from_xml(cls, str_value): "pc": 152400, "pi": 152400, }[units_part] - emu_value = Emu(int(round(quantity * multiplier))) - return emu_value + return Emu(int(round(quantity * multiplier))) class ST_VerticalAlignRun(XsdStringEnumeration): - """ - Valid values for `w:vertAlign/@val`. - """ + """Valid values for `w:vertAlign/@val`.""" BASELINE = "baseline" SUPERSCRIPT = "superscript" diff --git a/docx/oxml/styles.py b/src/docx/oxml/styles.py similarity index 67% rename from docx/oxml/styles.py rename to src/docx/oxml/styles.py index 96b390ba..fb0e5d0d 100644 --- a/docx/oxml/styles.py +++ b/src/docx/oxml/styles.py @@ -1,12 +1,10 @@ -# encoding: utf-8 +"""Custom element classes related to the styles part.""" -""" -Custom element classes related to the styles part -""" +from __future__ import annotations -from ..enum.style import WD_STYLE_TYPE -from .simpletypes import ST_DecimalNumber, ST_OnOff, ST_String -from .xmlchemy import ( +from docx.enum.style import WD_STYLE_TYPE +from docx.oxml.simpletypes import ST_DecimalNumber, ST_OnOff, ST_String +from docx.oxml.xmlchemy import ( BaseOxmlElement, OptionalAttribute, RequiredAttribute, @@ -16,10 +14,8 @@ def styleId_from_name(name): - """ - Return the style id corresponding to *name*, taking into account - special-case names such as 'Heading 1'. - """ + """Return the style id corresponding to `name`, taking into account special-case + names such as 'Heading 1'.""" return { "caption": "Caption", "heading 1": "Heading1", @@ -35,11 +31,9 @@ def styleId_from_name(name): class CT_LatentStyles(BaseOxmlElement): - """ - `w:latentStyles` element, defining behavior defaults for latent styles - and containing `w:lsdException` child elements that each override those - defaults for a named latent style. - """ + """`w:latentStyles` element, defining behavior defaults for latent styles and + containing `w:lsdException` child elements that each override those defaults for a + named latent style.""" lsdException = ZeroOrMore("w:lsdException", successors=()) @@ -51,37 +45,28 @@ class CT_LatentStyles(BaseOxmlElement): defUnhideWhenUsed = OptionalAttribute("w:defUnhideWhenUsed", ST_OnOff) def bool_prop(self, attr_name): - """ - Return the boolean value of the attribute having *attr_name*, or - |False| if not present. - """ + """Return the boolean value of the attribute having `attr_name`, or |False| if + not present.""" value = getattr(self, attr_name) if value is None: return False return value def get_by_name(self, name): - """ - Return the `w:lsdException` child having *name*, or |None| if not - found. - """ + """Return the `w:lsdException` child having `name`, or |None| if not found.""" found = self.xpath('w:lsdException[@w:name="%s"]' % name) if not found: return None return found[0] def set_bool_prop(self, attr_name, value): - """ - Set the on/off attribute having *attr_name* to *value*. - """ + """Set the on/off attribute having `attr_name` to `value`.""" setattr(self, attr_name, bool(value)) class CT_LsdException(BaseOxmlElement): - """ - ```` element, defining override visibility behaviors for - a named latent style. - """ + """```` element, defining override visibility behaviors for a named + latent style.""" locked = OptionalAttribute("w:locked", ST_OnOff) name = RequiredAttribute("w:name", ST_String) @@ -91,29 +76,21 @@ class CT_LsdException(BaseOxmlElement): unhideWhenUsed = OptionalAttribute("w:unhideWhenUsed", ST_OnOff) def delete(self): - """ - Remove this `w:lsdException` element from the XML document. - """ + """Remove this `w:lsdException` element from the XML document.""" self.getparent().remove(self) def on_off_prop(self, attr_name): - """ - Return the boolean value of the attribute having *attr_name*, or - |None| if not present. - """ + """Return the boolean value of the attribute having `attr_name`, or |None| if + not present.""" return getattr(self, attr_name) def set_on_off_prop(self, attr_name, value): - """ - Set the on/off attribute having *attr_name* to *value*. - """ + """Set the on/off attribute having `attr_name` to `value`.""" setattr(self, attr_name, value) class CT_Style(BaseOxmlElement): - """ - A ```` element, representing a style definition - """ + """A ```` element, representing a style definition.""" _tag_seq = ( "w:name", @@ -151,16 +128,18 @@ class CT_Style(BaseOxmlElement): rPr = ZeroOrOne("w:rPr", successors=_tag_seq[18:]) del _tag_seq - type = OptionalAttribute("w:type", WD_STYLE_TYPE) - styleId = OptionalAttribute("w:styleId", ST_String) + type: WD_STYLE_TYPE | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:type", WD_STYLE_TYPE + ) + styleId: str | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:styleId", ST_String + ) default = OptionalAttribute("w:default", ST_OnOff) customStyle = OptionalAttribute("w:customStyle", ST_OnOff) @property def basedOn_val(self): - """ - Value of `w:basedOn/@w:val` or |None| if not present. - """ + """Value of `w:basedOn/@w:val` or |None| if not present.""" basedOn = self.basedOn if basedOn is None: return None @@ -175,10 +154,8 @@ def basedOn_val(self, value): @property def base_style(self): - """ - Sibling CT_Style element this style is based on or |None| if no base - style or base style not found. - """ + """Sibling CT_Style element this style is based on or |None| if no base style or + base style not found.""" basedOn = self.basedOn if basedOn is None: return None @@ -189,16 +166,12 @@ def base_style(self): return base_style def delete(self): - """ - Remove this `w:style` element from its parent `w:styles` element. - """ + """Remove this `w:style` element from its parent `w:styles` element.""" self.getparent().remove(self) @property def locked_val(self): - """ - Value of `w:locked/@w:val` or |False| if not present. - """ + """Value of `w:locked/@w:val` or |False| if not present.""" locked = self.locked if locked is None: return False @@ -213,9 +186,7 @@ def locked_val(self, value): @property def name_val(self): - """ - Value of ```` child or |None| if not present. - """ + """Value of ```` child or |None| if not present.""" name = self.name if name is None: return None @@ -230,11 +201,8 @@ def name_val(self, value): @property def next_style(self): - """ - Sibling CT_Style element identified by the value of `w:name/@w:val` - or |None| if no value is present or no style with that style id - is found. - """ + """Sibling CT_Style element identified by the value of `w:name/@w:val` or |None| + if no value is present or no style with that style id is found.""" next = self.next if next is None: return None @@ -243,9 +211,7 @@ def next_style(self): @property def qFormat_val(self): - """ - Value of `w:qFormat/@w:val` or |False| if not present. - """ + """Value of `w:qFormat/@w:val` or |False| if not present.""" qFormat = self.qFormat if qFormat is None: return False @@ -259,9 +225,7 @@ def qFormat_val(self, value): @property def semiHidden_val(self): - """ - Value of ```` child or |False| if not present. - """ + """Value of ```` child or |False| if not present.""" semiHidden = self.semiHidden if semiHidden is None: return False @@ -276,9 +240,7 @@ def semiHidden_val(self, value): @property def uiPriority_val(self): - """ - Value of ```` child or |None| if not present. - """ + """Value of ```` child or |None| if not present.""" uiPriority = self.uiPriority if uiPriority is None: return None @@ -293,9 +255,7 @@ def uiPriority_val(self, value): @property def unhideWhenUsed_val(self): - """ - Value of `w:unhideWhenUsed/@w:val` or |False| if not present. - """ + """Value of `w:unhideWhenUsed/@w:val` or |False| if not present.""" unhideWhenUsed = self.unhideWhenUsed if unhideWhenUsed is None: return False @@ -310,10 +270,7 @@ def unhideWhenUsed_val(self, value): class CT_Styles(BaseOxmlElement): - """ - ```` element, the root element of a styles part, i.e. - styles.xml - """ + """```` element, the root element of a styles part, i.e. styles.xml.""" _tag_seq = ("w:docDefaults", "w:latentStyles", "w:style") latentStyles = ZeroOrOne("w:latentStyles", successors=_tag_seq[2:]) @@ -321,10 +278,9 @@ class CT_Styles(BaseOxmlElement): del _tag_seq def add_style_of_type(self, name, style_type, builtin): - """ - Return a newly added `w:style` element having *name* and - *style_type*. `w:style/@customStyle` is set based on the value of - *builtin*. + """Return a newly added `w:style` element having `name` and `style_type`. + + `w:style/@customStyle` is set based on the value of `builtin`. """ style = self.add_style() style.type = style_type @@ -334,9 +290,7 @@ def add_style_of_type(self, name, style_type, builtin): return style def default_for(self, style_type): - """ - Return `w:style[@w:type="*{style_type}*][-1]` or |None| if not found. - """ + """Return `w:style[@w:type="*{style_type}*][-1]` or |None| if not found.""" default_styles_for_type = [ s for s in self._iter_styles() if s.type == style_type and s.default ] @@ -345,30 +299,22 @@ def default_for(self, style_type): # spec calls for last default in document order return default_styles_for_type[-1] - def get_by_id(self, styleId): - """ - Return the ```` child element having ``styleId`` attribute - matching *styleId*, or |None| if not found. - """ - xpath = 'w:style[@w:styleId="%s"]' % styleId - try: - return self.xpath(xpath)[0] - except IndexError: - return None + def get_by_id(self, styleId: str) -> CT_Style | None: + """`w:style` child where @styleId = `styleId`. - def get_by_name(self, name): + |None| if not found. """ - Return the ```` child element having ```` child - element with value *name*, or |None| if not found. + xpath = f'w:style[@w:styleId="{styleId}"]' + return next(iter(self.xpath(xpath)), None) + + def get_by_name(self, name: str) -> CT_Style | None: + """`w:style` child with `w:name` grandchild having value `name`. + + |None| if not found. """ xpath = 'w:style[w:name/@w:val="%s"]' % name - try: - return self.xpath(xpath)[0] - except IndexError: - return None + return next(iter(self.xpath(xpath)), None) def _iter_styles(self): - """ - Generate each of the `w:style` child elements in document order. - """ + """Generate each of the `w:style` child elements in document order.""" return (style for style in self.xpath("w:style")) diff --git a/src/docx/oxml/table.py b/src/docx/oxml/table.py new file mode 100644 index 00000000..9457da20 --- /dev/null +++ b/src/docx/oxml/table.py @@ -0,0 +1,977 @@ +"""Custom element classes for tables.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Callable, cast + +from docx.enum.table import WD_CELL_VERTICAL_ALIGNMENT, WD_ROW_HEIGHT_RULE, WD_TABLE_DIRECTION +from docx.exceptions import InvalidSpanError +from docx.oxml.ns import nsdecls, qn +from docx.oxml.parser import parse_xml +from docx.oxml.shared import CT_DecimalNumber +from docx.oxml.simpletypes import ( + ST_Merge, + ST_TblLayoutType, + ST_TblWidth, + ST_TwipsMeasure, + XsdInt, +) +from docx.oxml.text.paragraph import CT_P +from docx.oxml.xmlchemy import ( + BaseOxmlElement, + OneAndOnlyOne, + OneOrMore, + OptionalAttribute, + RequiredAttribute, + ZeroOrMore, + ZeroOrOne, +) +from docx.shared import Emu, Length, Twips + +if TYPE_CHECKING: + from docx.enum.table import WD_TABLE_ALIGNMENT + from docx.enum.text import WD_ALIGN_PARAGRAPH + from docx.oxml.shared import CT_OnOff, CT_String + from docx.oxml.text.parfmt import CT_Jc + + +class CT_Height(BaseOxmlElement): + """Used for `w:trHeight` to specify a row height and row height rule.""" + + val: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:val", ST_TwipsMeasure + ) + hRule: WD_ROW_HEIGHT_RULE | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:hRule", WD_ROW_HEIGHT_RULE + ) + + +class CT_Row(BaseOxmlElement): + """```` element.""" + + add_tc: Callable[[], CT_Tc] + get_or_add_trPr: Callable[[], CT_TrPr] + _add_trPr: Callable[[], CT_TrPr] + + tc_lst: list[CT_Tc] + # -- custom inserter below -- + tblPrEx: CT_TblPrEx | None = ZeroOrOne("w:tblPrEx") # pyright: ignore[reportAssignmentType] + # -- custom inserter below -- + trPr: CT_TrPr | None = ZeroOrOne("w:trPr") # pyright: ignore[reportAssignmentType] + tc = ZeroOrMore("w:tc") + + @property + def grid_after(self) -> int: + """The number of unpopulated layout-grid cells at the end of this row.""" + trPr = self.trPr + if trPr is None: + return 0 + return trPr.grid_after + + @property + def grid_before(self) -> int: + """The number of unpopulated layout-grid cells at the start of this row.""" + trPr = self.trPr + if trPr is None: + return 0 + return trPr.grid_before + + def tc_at_grid_offset(self, grid_offset: int) -> CT_Tc: + """The `tc` element in this tr at exact `grid offset`. + + Raises ValueError when this `w:tr` contains no `w:tc` with exact starting `grid_offset`. + """ + # -- account for omitted cells at the start of the row -- + remaining_offset = grid_offset - self.grid_before + + for tc in self.tc_lst: + # -- We've gone past grid_offset without finding a tc, no sense searching further. -- + if remaining_offset < 0: + break + # -- We've arrived at grid_offset, this is the `w:tc` we're looking for. -- + if remaining_offset == 0: + return tc + # -- We're not there yet, skip forward the number of layout-grid cells this cell + # -- occupies. + remaining_offset -= tc.grid_span + + raise ValueError(f"no `tc` element at grid_offset={grid_offset}") + + @property + def tr_idx(self) -> int: + """Index of this `w:tr` element within its parent `w:tbl` element.""" + tbl = cast(CT_Tbl, self.getparent()) + return tbl.tr_lst.index(self) + + @property + def trHeight_hRule(self) -> WD_ROW_HEIGHT_RULE | None: + """The value of `./w:trPr/w:trHeight/@w:hRule`, or |None| if not present.""" + trPr = self.trPr + if trPr is None: + return None + return trPr.trHeight_hRule + + @trHeight_hRule.setter + def trHeight_hRule(self, value: WD_ROW_HEIGHT_RULE | None): + trPr = self.get_or_add_trPr() + trPr.trHeight_hRule = value + + @property + def trHeight_val(self): + """Return the value of `w:trPr/w:trHeight@w:val`, or |None| if not present.""" + trPr = self.trPr + if trPr is None: + return None + return trPr.trHeight_val + + @trHeight_val.setter + def trHeight_val(self, value: Length | None): + trPr = self.get_or_add_trPr() + trPr.trHeight_val = value + + def _insert_tblPrEx(self, tblPrEx: CT_TblPrEx): + self.insert(0, tblPrEx) + + def _insert_trPr(self, trPr: CT_TrPr): + tblPrEx = self.tblPrEx + if tblPrEx is not None: + tblPrEx.addnext(trPr) + else: + self.insert(0, trPr) + + def _new_tc(self): + return CT_Tc.new() + + +class CT_Tbl(BaseOxmlElement): + """```` element.""" + + add_tr: Callable[[], CT_Row] + tr_lst: list[CT_Row] + + tblPr: CT_TblPr = OneAndOnlyOne("w:tblPr") # pyright: ignore[reportAssignmentType] + tblGrid: CT_TblGrid = OneAndOnlyOne("w:tblGrid") # pyright: ignore[reportAssignmentType] + tr = ZeroOrMore("w:tr") + + @property + def bidiVisual_val(self) -> bool | None: + """Value of `./w:tblPr/w:bidiVisual/@w:val` or |None| if not present. + + Controls whether table cells are displayed right-to-left or left-to-right. + """ + bidiVisual = self.tblPr.bidiVisual + if bidiVisual is None: + return None + return bidiVisual.val + + @bidiVisual_val.setter + def bidiVisual_val(self, value: WD_TABLE_DIRECTION | None): + tblPr = self.tblPr + if value is None: + tblPr._remove_bidiVisual() # pyright: ignore[reportPrivateUsage] + else: + tblPr.get_or_add_bidiVisual().val = bool(value) + + @property + def col_count(self): + """The number of grid columns in this table.""" + return len(self.tblGrid.gridCol_lst) + + def iter_tcs(self): + """Generate each of the `w:tc` elements in this table, left to right and top to + bottom. + + Each cell in the first row is generated, followed by each cell in the second + row, etc. + """ + for tr in self.tr_lst: + for tc in tr.tc_lst: + yield tc + + @classmethod + def new_tbl(cls, rows: int, cols: int, width: Length) -> CT_Tbl: + """Return a new `w:tbl` element having `rows` rows and `cols` columns. + + `width` is distributed evenly between the columns. + """ + return cast(CT_Tbl, parse_xml(cls._tbl_xml(rows, cols, width))) + + @property + def tblStyle_val(self) -> str | None: + """`w:tblPr/w:tblStyle/@w:val` (a table style id) or |None| if not present.""" + tblStyle = self.tblPr.tblStyle + if tblStyle is None: + return None + return tblStyle.val + + @tblStyle_val.setter + def tblStyle_val(self, styleId: str | None) -> None: + """Set the value of `w:tblPr/w:tblStyle/@w:val` (a table style id) to `styleId`. + + If `styleId` is None, remove the `w:tblStyle` element. + """ + tblPr = self.tblPr + tblPr._remove_tblStyle() # pyright: ignore[reportPrivateUsage] + if styleId is None: + return + tblPr._add_tblStyle().val = styleId # pyright: ignore[reportPrivateUsage] + + @classmethod + def _tbl_xml(cls, rows: int, cols: int, width: Length) -> str: + col_width = Emu(width // cols) if cols > 0 else Emu(0) + return ( + f"\n" + f" \n" + f' \n' + f' \n' + f" \n" + f"{cls._tblGrid_xml(cols, col_width)}" + f"{cls._trs_xml(rows, cols, col_width)}" + f"\n" + ) + + @classmethod + def _tblGrid_xml(cls, col_count: int, col_width: Length) -> str: + xml = " \n" + for _ in range(col_count): + xml += ' \n' % col_width.twips + xml += " \n" + return xml + + @classmethod + def _trs_xml(cls, row_count: int, col_count: int, col_width: Length) -> str: + return f" \n{cls._tcs_xml(col_count, col_width)} \n" * row_count + + @classmethod + def _tcs_xml(cls, col_count: int, col_width: Length) -> str: + return ( + f" \n" + f" \n" + f' \n' + f" \n" + f" \n" + f" \n" + ) * col_count + + +class CT_TblGrid(BaseOxmlElement): + """`w:tblGrid` element. + + Child of `w:tbl`, holds `w:gridCol> elements that define column count, width, etc. + """ + + add_gridCol: Callable[[], CT_TblGridCol] + gridCol_lst: list[CT_TblGridCol] + + gridCol = ZeroOrMore("w:gridCol", successors=("w:tblGridChange",)) + + +class CT_TblGridCol(BaseOxmlElement): + """`w:gridCol` element, child of `w:tblGrid`, defines a table column.""" + + w: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:w", ST_TwipsMeasure + ) + + @property + def gridCol_idx(self) -> int: + """Index of this `w:gridCol` element within its parent `w:tblGrid` element.""" + tblGrid = cast(CT_TblGrid, self.getparent()) + return tblGrid.gridCol_lst.index(self) + + +class CT_TblLayoutType(BaseOxmlElement): + """`w:tblLayout` element. + + Specifies whether column widths are fixed or can be automatically adjusted based on + content. + """ + + type: str | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:type", ST_TblLayoutType + ) + + +class CT_TblPr(BaseOxmlElement): + """```` element, child of ````, holds child elements that define + table properties such as style and borders.""" + + get_or_add_bidiVisual: Callable[[], CT_OnOff] + get_or_add_jc: Callable[[], CT_Jc] + get_or_add_tblLayout: Callable[[], CT_TblLayoutType] + _add_tblStyle: Callable[[], CT_String] + _remove_bidiVisual: Callable[[], None] + _remove_jc: Callable[[], None] + _remove_tblStyle: Callable[[], None] + + _tag_seq = ( + "w:tblStyle", + "w:tblpPr", + "w:tblOverlap", + "w:bidiVisual", + "w:tblStyleRowBandSize", + "w:tblStyleColBandSize", + "w:tblW", + "w:jc", + "w:tblCellSpacing", + "w:tblInd", + "w:tblBorders", + "w:shd", + "w:tblLayout", + "w:tblCellMar", + "w:tblLook", + "w:tblCaption", + "w:tblDescription", + "w:tblPrChange", + ) + tblStyle: CT_String | None = ZeroOrOne( # pyright: ignore[reportAssignmentType] + "w:tblStyle", successors=_tag_seq[1:] + ) + bidiVisual: CT_OnOff | None = ZeroOrOne( # pyright: ignore[reportAssignmentType] + "w:bidiVisual", successors=_tag_seq[4:] + ) + jc: CT_Jc | None = ZeroOrOne( # pyright: ignore[reportAssignmentType] + "w:jc", successors=_tag_seq[8:] + ) + tblLayout: CT_TblLayoutType | None = ZeroOrOne( # pyright: ignore[reportAssignmentType] + "w:tblLayout", successors=_tag_seq[13:] + ) + del _tag_seq + + @property + def alignment(self) -> WD_TABLE_ALIGNMENT | None: + """Horizontal alignment of table, |None| if `./w:jc` is not present.""" + jc = self.jc + if jc is None: + return None + return cast("WD_TABLE_ALIGNMENT | None", jc.val) + + @alignment.setter + def alignment(self, value: WD_TABLE_ALIGNMENT | None): + self._remove_jc() + if value is None: + return + jc = self.get_or_add_jc() + jc.val = cast("WD_ALIGN_PARAGRAPH", value) + + @property + def autofit(self) -> bool: + """|False| when there is a `w:tblLayout` child with `@w:type="fixed"`. + + Otherwise |True|. + """ + tblLayout = self.tblLayout + return True if tblLayout is None else tblLayout.type != "fixed" + + @autofit.setter + def autofit(self, value: bool): + tblLayout = self.get_or_add_tblLayout() + tblLayout.type = "autofit" if value else "fixed" + + @property + def style(self): + """Return the value of the ``val`` attribute of the ```` child or + |None| if not present.""" + tblStyle = self.tblStyle + if tblStyle is None: + return None + return tblStyle.val + + @style.setter + def style(self, value: str | None): + self._remove_tblStyle() + if value is None: + return + self._add_tblStyle().val = value + + +class CT_TblPrEx(BaseOxmlElement): + """`w:tblPrEx` element, exceptions to table-properties. + + Applied at a lower level, like a `w:tr` to modify the appearance. Possibly used when + two tables are merged. For more see: + http://officeopenxml.com/WPtablePropertyExceptions.php + """ + + +class CT_TblWidth(BaseOxmlElement): + """Used for `w:tblW` and `w:tcW` and others, specifies a table-related width.""" + + # the type for `w` attr is actually ST_MeasurementOrPercent, but using + # XsdInt for now because only dxa (twips) values are being used. It's not + # entirely clear what the semantics are for other values like -01.4mm + w: int = RequiredAttribute("w:w", XsdInt) # pyright: ignore[reportAssignmentType] + type = RequiredAttribute("w:type", ST_TblWidth) + + @property + def width(self) -> Length | None: + """EMU length indicated by the combined `w:w` and `w:type` attrs.""" + if self.type != "dxa": + return None + return Twips(self.w) + + @width.setter + def width(self, value: Length): + self.type = "dxa" + self.w = Emu(value).twips + + +class CT_Tc(BaseOxmlElement): + """`w:tc` table cell element.""" + + add_p: Callable[[], CT_P] + get_or_add_tcPr: Callable[[], CT_TcPr] + p_lst: list[CT_P] + tbl_lst: list[CT_Tbl] + _insert_tbl: Callable[[CT_Tbl], CT_Tbl] + _new_p: Callable[[], CT_P] + + # -- tcPr has many successors, `._insert_tcPr()` is overridden below -- + tcPr: CT_TcPr | None = ZeroOrOne("w:tcPr") # pyright: ignore[reportAssignmentType] + p = OneOrMore("w:p") + tbl = OneOrMore("w:tbl") + + @property + def bottom(self) -> int: + """The row index that marks the bottom extent of the vertical span of this cell. + + This is one greater than the index of the bottom-most row of the span, similar + to how a slice of the cell's rows would be specified. + """ + if self.vMerge is not None: + tc_below = self._tc_below + if tc_below is not None and tc_below.vMerge == ST_Merge.CONTINUE: + return tc_below.bottom + return self._tr_idx + 1 + + def clear_content(self): + """Remove all content elements, preserving `w:tcPr` element if present. + + Note that this leaves the `w:tc` element in an invalid state because it doesn't + contain at least one block-level element. It's up to the caller to add a + `w:p`child element as the last content element. + """ + # -- remove all cell inner-content except a `w:tcPr` when present. -- + for e in self.xpath("./*[not(self::w:tcPr)]"): + self.remove(e) + + @property + def grid_offset(self) -> int: + """Starting offset of `tc` in the layout-grid columns of its table. + + A cell in the leftmost grid-column has offset 0. + """ + grid_before = self._tr.grid_before + preceding_tc_grid_spans = sum( + tc.grid_span for tc in self.xpath("./preceding-sibling::w:tc") + ) + return grid_before + preceding_tc_grid_spans + + @property + def grid_span(self) -> int: + """The integer number of columns this cell spans. + + Determined by ./w:tcPr/w:gridSpan/@val, it defaults to 1. + """ + tcPr = self.tcPr + return 1 if tcPr is None else tcPr.grid_span + + @grid_span.setter + def grid_span(self, value: int): + tcPr = self.get_or_add_tcPr() + tcPr.grid_span = value + + @property + def inner_content_elements(self) -> list[CT_P | CT_Tbl]: + """Generate all `w:p` and `w:tbl` elements in this document-body. + + Elements appear in document order. Elements shaded by nesting in a `w:ins` or + other "wrapper" element will not be included. + """ + return self.xpath("./w:p | ./w:tbl") + + def iter_block_items(self): + """Generate a reference to each of the block-level content elements in this + cell, in the order they appear.""" + block_item_tags = (qn("w:p"), qn("w:tbl"), qn("w:sdt")) + for child in self: + if child.tag in block_item_tags: + yield child + + @property + def left(self) -> int: + """The grid column index at which this ```` element appears.""" + return self.grid_offset + + def merge(self, other_tc: CT_Tc) -> CT_Tc: + """Return top-left `w:tc` element of a new span. + + Span is formed by merging the rectangular region defined by using this tc + element and `other_tc` as diagonal corners. + """ + top, left, height, width = self._span_dimensions(other_tc) + top_tc = self._tbl.tr_lst[top].tc_at_grid_offset(left) + top_tc._grow_to(width, height) + return top_tc + + @classmethod + def new(cls) -> CT_Tc: + """A new `w:tc` element, containing an empty paragraph as the required EG_BlockLevelElt.""" + return cast(CT_Tc, parse_xml("" % nsdecls("w"))) + + @property + def right(self) -> int: + """The grid column index that marks the right-side extent of the horizontal span + of this cell. + + This is one greater than the index of the right-most column of the span, similar + to how a slice of the cell's columns would be specified. + """ + return self.grid_offset + self.grid_span + + @property + def top(self) -> int: + """The top-most row index in the vertical span of this cell.""" + if self.vMerge is None or self.vMerge == ST_Merge.RESTART: + return self._tr_idx + return self._tc_above.top + + @property + def vMerge(self) -> str | None: + """Value of ./w:tcPr/w:vMerge/@val, |None| if w:vMerge is not present.""" + tcPr = self.tcPr + if tcPr is None: + return None + return tcPr.vMerge_val + + @vMerge.setter + def vMerge(self, value: str | None): + tcPr = self.get_or_add_tcPr() + tcPr.vMerge_val = value + + @property + def width(self) -> Length | None: + """EMU length represented in `./w:tcPr/w:tcW` or |None| if not present.""" + tcPr = self.tcPr + if tcPr is None: + return None + return tcPr.width + + @width.setter + def width(self, value: Length): + tcPr = self.get_or_add_tcPr() + tcPr.width = value + + def _add_width_of(self, other_tc: CT_Tc): + """Add the width of `other_tc` to this cell. + + Does nothing if either this tc or `other_tc` does not have a specified width. + """ + if self.width and other_tc.width: + self.width = Length(self.width + other_tc.width) + + def _grow_to(self, width: int, height: int, top_tc: CT_Tc | None = None): + """Grow this cell to `width` grid columns and `height` rows. + + This is accomplished by expanding horizontal spans and creating continuation + cells to form vertical spans. + """ + + def vMerge_val(top_tc: CT_Tc): + return ( + ST_Merge.CONTINUE + if top_tc is not self + else None + if height == 1 + else ST_Merge.RESTART + ) + + top_tc = self if top_tc is None else top_tc + self._span_to_width(width, top_tc, vMerge_val(top_tc)) + if height > 1: + tc_below = self._tc_below + assert tc_below is not None + tc_below._grow_to(width, height - 1, top_tc) + + def _insert_tcPr(self, tcPr: CT_TcPr) -> CT_TcPr: + """Override default `._insert_tcPr()`.""" + # -- `tcPr`` has a large number of successors, but always comes first if it appears, + # -- so just using insert(0, ...) rather than spelling out successors. + self.insert(0, tcPr) + return tcPr + + @property + def _is_empty(self) -> bool: + """True if this cell contains only a single empty `w:p` element.""" + block_items = list(self.iter_block_items()) + if len(block_items) > 1: + return False + # -- cell must include at least one block item but can be a `w:tbl`, `w:sdt`, + # -- `w:customXml` or a `w:p` + only_item = block_items[0] + return isinstance(only_item, CT_P) and len(only_item.r_lst) == 0 + + def _move_content_to(self, other_tc: CT_Tc): + """Append the content of this cell to `other_tc`. + + Leaves this cell with a single empty ```` element. + """ + if other_tc is self: + return + if self._is_empty: + return + other_tc._remove_trailing_empty_p() + # -- appending moves each element from self to other_tc -- + for block_element in self.iter_block_items(): + other_tc.append(block_element) + # -- add back the required minimum single empty element -- + self.append(self._new_p()) + + def _new_tbl(self) -> None: + raise NotImplementedError( + "use CT_Tbl.new_tbl() to add a new table, specifying rows and columns" + ) + + @property + def _next_tc(self) -> CT_Tc | None: + """The `w:tc` element immediately following this one in this row, or |None| if + this is the last `w:tc` element in the row.""" + following_tcs = self.xpath("./following-sibling::w:tc") + return following_tcs[0] if following_tcs else None + + def _remove(self): + """Remove this `w:tc` element from the XML tree.""" + parent_element = self.getparent() + assert parent_element is not None + parent_element.remove(self) + + def _remove_trailing_empty_p(self): + """Remove last content element from this cell if it's an empty `w:p` element.""" + block_items = list(self.iter_block_items()) + last_content_elm = block_items[-1] + if not isinstance(last_content_elm, CT_P): + return + p = last_content_elm + if len(p.r_lst) > 0: + return + self.remove(p) + + def _span_dimensions(self, other_tc: CT_Tc) -> tuple[int, int, int, int]: + """Return a (top, left, height, width) 4-tuple specifying the extents of the + merged cell formed by using this tc and `other_tc` as opposite corner + extents.""" + + def raise_on_inverted_L(a: CT_Tc, b: CT_Tc): + if a.top == b.top and a.bottom != b.bottom: + raise InvalidSpanError("requested span not rectangular") + if a.left == b.left and a.right != b.right: + raise InvalidSpanError("requested span not rectangular") + + def raise_on_tee_shaped(a: CT_Tc, b: CT_Tc): + top_most, other = (a, b) if a.top < b.top else (b, a) + if top_most.top < other.top and top_most.bottom > other.bottom: + raise InvalidSpanError("requested span not rectangular") + + left_most, other = (a, b) if a.left < b.left else (b, a) + if left_most.left < other.left and left_most.right > other.right: + raise InvalidSpanError("requested span not rectangular") + + raise_on_inverted_L(self, other_tc) + raise_on_tee_shaped(self, other_tc) + + top = min(self.top, other_tc.top) + left = min(self.left, other_tc.left) + bottom = max(self.bottom, other_tc.bottom) + right = max(self.right, other_tc.right) + + return top, left, bottom - top, right - left + + def _span_to_width(self, grid_width: int, top_tc: CT_Tc, vMerge: str | None): + """Incorporate `w:tc` elements to the right until this cell spans `grid_width`. + + Incorporated `w:tc` elements are removed (replaced by gridSpan value). + + Raises |ValueError| if `grid_width` cannot be exactly achieved, such as when a + merged cell would drive the span width greater than `grid_width` or if not + enough grid columns are available to make this cell that wide. All content from + incorporated cells is appended to `top_tc`. The val attribute of the vMerge + element on the single remaining cell is set to `vMerge`. If `vMerge` is |None|, + the vMerge element is removed if present. + """ + self._move_content_to(top_tc) + while self.grid_span < grid_width: + self._swallow_next_tc(grid_width, top_tc) + self.vMerge = vMerge + + def _swallow_next_tc(self, grid_width: int, top_tc: CT_Tc): + """Extend the horizontal span of this `w:tc` element to incorporate the + following `w:tc` element in the row and then delete that following `w:tc` + element. + + Any content in the following `w:tc` element is appended to the content of + `top_tc`. The width of the following `w:tc` element is added to this one, if + present. Raises |InvalidSpanError| if the width of the resulting cell is greater + than `grid_width` or if there is no next `` element in the row. + """ + + def raise_on_invalid_swallow(next_tc: CT_Tc | None): + if next_tc is None: + raise InvalidSpanError("not enough grid columns") + if self.grid_span + next_tc.grid_span > grid_width: + raise InvalidSpanError("span is not rectangular") + + next_tc = self._next_tc + raise_on_invalid_swallow(next_tc) + assert next_tc is not None + next_tc._move_content_to(top_tc) + self._add_width_of(next_tc) + self.grid_span += next_tc.grid_span + next_tc._remove() + + @property + def _tbl(self) -> CT_Tbl: + """The tbl element this tc element appears in.""" + return cast(CT_Tbl, self.xpath("./ancestor::w:tbl[position()=1]")[0]) + + @property + def _tc_above(self) -> CT_Tc: + """The `w:tc` element immediately above this one in its grid column.""" + return self._tr_above.tc_at_grid_offset(self.grid_offset) + + @property + def _tc_below(self) -> CT_Tc | None: + """The tc element immediately below this one in its grid column.""" + tr_below = self._tr_below + if tr_below is None: + return None + return tr_below.tc_at_grid_offset(self.grid_offset) + + @property + def _tr(self) -> CT_Row: + """The tr element this tc element appears in.""" + return cast(CT_Row, self.xpath("./ancestor::w:tr[position()=1]")[0]) + + @property + def _tr_above(self) -> CT_Row: + """The tr element prior in sequence to the tr this cell appears in. + + Raises |ValueError| if called on a cell in the top-most row. + """ + tr_aboves = self.xpath("./ancestor::w:tr[position()=1]/preceding-sibling::w:tr[1]") + if not tr_aboves: + raise ValueError("no tr above topmost tr in w:tbl") + return tr_aboves[0] + + @property + def _tr_below(self) -> CT_Row | None: + """The tr element next in sequence after the tr this cell appears in, or |None| + if this cell appears in the last row.""" + tr_lst = self._tbl.tr_lst + tr_idx = tr_lst.index(self._tr) + try: + return tr_lst[tr_idx + 1] + except IndexError: + return None + + @property + def _tr_idx(self) -> int: + """The row index of the tr element this tc element appears in.""" + return self._tbl.tr_lst.index(self._tr) + + +class CT_TcPr(BaseOxmlElement): + """```` element, defining table cell properties.""" + + get_or_add_gridSpan: Callable[[], CT_DecimalNumber] + get_or_add_tcW: Callable[[], CT_TblWidth] + get_or_add_vAlign: Callable[[], CT_VerticalJc] + _add_vMerge: Callable[[], CT_VMerge] + _remove_gridSpan: Callable[[], None] + _remove_vAlign: Callable[[], None] + _remove_vMerge: Callable[[], None] + + _tag_seq = ( + "w:cnfStyle", + "w:tcW", + "w:gridSpan", + "w:hMerge", + "w:vMerge", + "w:tcBorders", + "w:shd", + "w:noWrap", + "w:tcMar", + "w:textDirection", + "w:tcFitText", + "w:vAlign", + "w:hideMark", + "w:headers", + "w:cellIns", + "w:cellDel", + "w:cellMerge", + "w:tcPrChange", + ) + tcW: CT_TblWidth | None = ZeroOrOne( # pyright: ignore[reportAssignmentType] + "w:tcW", successors=_tag_seq[2:] + ) + gridSpan: CT_DecimalNumber | None = ZeroOrOne( # pyright: ignore[reportAssignmentType] + "w:gridSpan", successors=_tag_seq[3:] + ) + vMerge: CT_VMerge | None = ZeroOrOne( # pyright: ignore[reportAssignmentType] + "w:vMerge", successors=_tag_seq[5:] + ) + vAlign: CT_VerticalJc | None = ZeroOrOne( # pyright: ignore[reportAssignmentType] + "w:vAlign", successors=_tag_seq[12:] + ) + del _tag_seq + + @property + def grid_span(self) -> int: + """The integer number of columns this cell spans. + + Determined by ./w:gridSpan/@val, it defaults to 1. + """ + gridSpan = self.gridSpan + return 1 if gridSpan is None else gridSpan.val + + @grid_span.setter + def grid_span(self, value: int): + self._remove_gridSpan() + if value > 1: + self.get_or_add_gridSpan().val = value + + @property + def vAlign_val(self): + """Value of `w:val` attribute on `w:vAlign` child. + + Value is |None| if `w:vAlign` child is not present. The `w:val` attribute on + `w:vAlign` is required. + """ + vAlign = self.vAlign + if vAlign is None: + return None + return vAlign.val + + @vAlign_val.setter + def vAlign_val(self, value: WD_CELL_VERTICAL_ALIGNMENT | None): + if value is None: + self._remove_vAlign() + return + self.get_or_add_vAlign().val = value + + @property + def vMerge_val(self): + """The value of the ./w:vMerge/@val attribute, or |None| if the w:vMerge element + is not present.""" + vMerge = self.vMerge + if vMerge is None: + return None + return vMerge.val + + @vMerge_val.setter + def vMerge_val(self, value: str | None): + self._remove_vMerge() + if value is not None: + self._add_vMerge().val = value + + @property + def width(self) -> Length | None: + """EMU length in `./w:tcW` or |None| if not present or its type is not 'dxa'.""" + tcW = self.tcW + if tcW is None: + return None + return tcW.width + + @width.setter + def width(self, value: Length): + tcW = self.get_or_add_tcW() + tcW.width = value + + +class CT_TrPr(BaseOxmlElement): + """```` element, defining table row properties.""" + + get_or_add_trHeight: Callable[[], CT_Height] + + _tag_seq = ( + "w:cnfStyle", + "w:divId", + "w:gridBefore", + "w:gridAfter", + "w:wBefore", + "w:wAfter", + "w:cantSplit", + "w:trHeight", + "w:tblHeader", + "w:tblCellSpacing", + "w:jc", + "w:hidden", + "w:ins", + "w:del", + "w:trPrChange", + ) + gridAfter: CT_DecimalNumber | None = ZeroOrOne( # pyright: ignore[reportAssignmentType] + "w:gridAfter", successors=_tag_seq[4:] + ) + gridBefore: CT_DecimalNumber | None = ZeroOrOne( # pyright: ignore[reportAssignmentType] + "w:gridBefore", successors=_tag_seq[3:] + ) + trHeight: CT_Height | None = ZeroOrOne( # pyright: ignore[reportAssignmentType] + "w:trHeight", successors=_tag_seq[8:] + ) + del _tag_seq + + @property + def grid_after(self) -> int: + """The number of unpopulated layout-grid cells at the end of this row.""" + gridAfter = self.gridAfter + return 0 if gridAfter is None else gridAfter.val + + @property + def grid_before(self) -> int: + """The number of unpopulated layout-grid cells at the start of this row.""" + gridBefore = self.gridBefore + return 0 if gridBefore is None else gridBefore.val + + @property + def trHeight_hRule(self) -> WD_ROW_HEIGHT_RULE | None: + """Return the value of `w:trHeight@w:hRule`, or |None| if not present.""" + trHeight = self.trHeight + return None if trHeight is None else trHeight.hRule + + @trHeight_hRule.setter + def trHeight_hRule(self, value: WD_ROW_HEIGHT_RULE | None): + if value is None and self.trHeight is None: + return + trHeight = self.get_or_add_trHeight() + trHeight.hRule = value + + @property + def trHeight_val(self): + """Return the value of `w:trHeight@w:val`, or |None| if not present.""" + trHeight = self.trHeight + return None if trHeight is None else trHeight.val + + @trHeight_val.setter + def trHeight_val(self, value: Length | None): + if value is None and self.trHeight is None: + return + trHeight = self.get_or_add_trHeight() + trHeight.val = value + + +class CT_VerticalJc(BaseOxmlElement): + """`w:vAlign` element, specifying vertical alignment of cell.""" + + val: WD_CELL_VERTICAL_ALIGNMENT = RequiredAttribute( # pyright: ignore[reportAssignmentType] + "w:val", WD_CELL_VERTICAL_ALIGNMENT + ) + + +class CT_VMerge(BaseOxmlElement): + """```` element, specifying vertical merging behavior of a cell.""" + + val: str | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:val", ST_Merge, default=ST_Merge.CONTINUE + ) diff --git a/docx/parts/__init__.py b/src/docx/oxml/text/__init__.py similarity index 100% rename from docx/parts/__init__.py rename to src/docx/oxml/text/__init__.py diff --git a/src/docx/oxml/text/font.py b/src/docx/oxml/text/font.py new file mode 100644 index 00000000..f7916090 --- /dev/null +++ b/src/docx/oxml/text/font.py @@ -0,0 +1,358 @@ +# pyright: reportAssignmentType=false + +"""Custom element classes related to run properties (font).""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Callable + +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.parser import parse_xml +from docx.oxml.simpletypes import ( + ST_HexColor, + ST_HpsMeasure, + ST_String, + ST_VerticalAlignRun, +) +from docx.oxml.xmlchemy import ( + BaseOxmlElement, + OptionalAttribute, + RequiredAttribute, + ZeroOrOne, +) +from docx.shared import RGBColor + +if TYPE_CHECKING: + from docx.oxml.shared import CT_OnOff, CT_String + from docx.shared import Length + + +class CT_Color(BaseOxmlElement): + """`w:color` element, specifying the color of a font and perhaps other objects.""" + + val: RGBColor | str = RequiredAttribute("w:val", ST_HexColor) + themeColor: MSO_THEME_COLOR | None = OptionalAttribute("w:themeColor", MSO_THEME_COLOR) + + +class CT_Fonts(BaseOxmlElement): + """`` element. + + Specifies typeface name for the various language types. + """ + + ascii: str | None = OptionalAttribute("w:ascii", ST_String) + hAnsi: str | None = OptionalAttribute("w:hAnsi", ST_String) + eastAsia: str | None = OptionalAttribute("w:eastAsia", ST_String) + + +class CT_Highlight(BaseOxmlElement): + """`w:highlight` element, specifying font highlighting/background color.""" + + val: WD_COLOR_INDEX = RequiredAttribute("w:val", WD_COLOR_INDEX) + + +class CT_HpsMeasure(BaseOxmlElement): + """Used for `` element and others, specifying font size in half-points.""" + + val: Length = RequiredAttribute("w:val", ST_HpsMeasure) + + +class CT_RPr(BaseOxmlElement): + """`` element, containing the properties for a run.""" + + get_or_add_color: Callable[[], CT_Color] + get_or_add_highlight: Callable[[], CT_Highlight] + get_or_add_rFonts: Callable[[], CT_Fonts] + get_or_add_sz: Callable[[], CT_HpsMeasure] + get_or_add_vertAlign: Callable[[], CT_VerticalAlignRun] + _add_rStyle: Callable[..., CT_String] + _add_u: Callable[[], CT_Underline] + _remove_color: Callable[[], None] + _remove_highlight: Callable[[], None] + _remove_rFonts: Callable[[], None] + _remove_rStyle: Callable[[], None] + _remove_sz: Callable[[], None] + _remove_u: Callable[[], None] + _remove_vertAlign: Callable[[], None] + + _tag_seq = ( + "w:rStyle", + "w:rFonts", + "w:b", + "w:bCs", + "w:i", + "w:iCs", + "w:caps", + "w:smallCaps", + "w:strike", + "w:dstrike", + "w:outline", + "w:shadow", + "w:emboss", + "w:imprint", + "w:noProof", + "w:snapToGrid", + "w:vanish", + "w:webHidden", + "w:color", + "w:spacing", + "w:w", + "w:kern", + "w:position", + "w:sz", + "w:szCs", + "w:highlight", + "w:u", + "w:effect", + "w:bdr", + "w:shd", + "w:fitText", + "w:vertAlign", + "w:rtl", + "w:cs", + "w:em", + "w:lang", + "w:eastAsianLayout", + "w:specVanish", + "w:oMath", + ) + rStyle: CT_String | None = ZeroOrOne("w:rStyle", successors=_tag_seq[1:]) + rFonts: CT_Fonts | None = ZeroOrOne("w:rFonts", successors=_tag_seq[2:]) + b: CT_OnOff | None = ZeroOrOne("w:b", successors=_tag_seq[3:]) + bCs = ZeroOrOne("w:bCs", successors=_tag_seq[4:]) + i = ZeroOrOne("w:i", successors=_tag_seq[5:]) + iCs = ZeroOrOne("w:iCs", successors=_tag_seq[6:]) + caps = ZeroOrOne("w:caps", successors=_tag_seq[7:]) + smallCaps = ZeroOrOne("w:smallCaps", successors=_tag_seq[8:]) + strike = ZeroOrOne("w:strike", successors=_tag_seq[9:]) + dstrike = ZeroOrOne("w:dstrike", successors=_tag_seq[10:]) + outline = ZeroOrOne("w:outline", successors=_tag_seq[11:]) + shadow = ZeroOrOne("w:shadow", successors=_tag_seq[12:]) + emboss = ZeroOrOne("w:emboss", successors=_tag_seq[13:]) + imprint = ZeroOrOne("w:imprint", successors=_tag_seq[14:]) + noProof = ZeroOrOne("w:noProof", successors=_tag_seq[15:]) + snapToGrid = ZeroOrOne("w:snapToGrid", successors=_tag_seq[16:]) + vanish = ZeroOrOne("w:vanish", successors=_tag_seq[17:]) + webHidden = ZeroOrOne("w:webHidden", successors=_tag_seq[18:]) + color: CT_Color | None = ZeroOrOne("w:color", successors=_tag_seq[19:]) + sz: CT_HpsMeasure | None = ZeroOrOne("w:sz", successors=_tag_seq[24:]) + highlight: CT_Highlight | None = ZeroOrOne("w:highlight", successors=_tag_seq[26:]) + u: CT_Underline | None = ZeroOrOne("w:u", successors=_tag_seq[27:]) + vertAlign: CT_VerticalAlignRun | None = ZeroOrOne("w:vertAlign", successors=_tag_seq[32:]) + rtl = ZeroOrOne("w:rtl", successors=_tag_seq[33:]) + cs = ZeroOrOne("w:cs", successors=_tag_seq[34:]) + eastAsianLayout: CT_OnOff | None = ZeroOrOne("w:eastAsianLayout", successors=_tag_seq[37:]) + specVanish = ZeroOrOne("w:specVanish", successors=_tag_seq[38:]) + oMath = ZeroOrOne("w:oMath", successors=_tag_seq[39:]) + del _tag_seq + + def _new_color(self): + """Override metaclass method to set `w:color/@val` to RGB black on create.""" + return parse_xml('' % nsdecls("w")) + + @property + def highlight_val(self) -> WD_COLOR_INDEX | None: + """Value of `./w:highlight/@val`. + + Specifies font's highlight color, or `None` if the text is not highlighted. + """ + highlight = self.highlight + if highlight is None: + return None + return highlight.val + + @highlight_val.setter + def highlight_val(self, value: WD_COLOR_INDEX | None) -> None: + if value is None: + self._remove_highlight() + return + highlight = self.get_or_add_highlight() + highlight.val = value + + @property + def rFonts_ascii(self) -> str | None: + """The value of `w:rFonts/@w:ascii` or |None| if not present. + + Represents the assigned typeface name. The rFonts element also specifies other + special-case typeface names; this method handles the case where just the common + name is required. + """ + rFonts = self.rFonts + if rFonts is None: + return None + return rFonts.ascii + + @rFonts_ascii.setter + def rFonts_ascii(self, value: str | None) -> None: + if value is None: + if self.rFonts is not None: + self.rFonts.ascii = None + return + rFonts = self.get_or_add_rFonts() + rFonts.ascii = value + + @property + def rFonts_hAnsi(self) -> str | None: + """The value of `w:rFonts/@w:hAnsi` or |None| if not present.""" + rFonts = self.rFonts + if rFonts is None: + return None + return rFonts.hAnsi + + @rFonts_hAnsi.setter + def rFonts_hAnsi(self, value: str | None): + if value is None: + if self.rFonts is not None: + self.rFonts.hAnsi = None + return + rFonts = self.get_or_add_rFonts() + rFonts.hAnsi = value + + @property + def rFonts_eastAsia(self) -> str | None: + """The value of `w:rFonts/@w:eastAsia` or |None| if not present. + + Represents the assigned typeface name. The rFonts element also specifies other + special-case typeface names; this method handles the case where just the common + name is required. + """ + rFonts = self.rFonts + if rFonts is None: + return None + return rFonts.eastAsia + + @rFonts_eastAsia.setter + def rFonts_eastAsia(self, value: str | None) -> None: + if value is None: + if self.rFonts is not None: + self.rFonts.eastAsia = None + return + rFonts = self.get_or_add_rFonts() + rFonts.eastAsia = value + + @property + def style(self) -> str | None: + """String in `./w:rStyle/@val`, or None if `w:rStyle` is not present.""" + rStyle = self.rStyle + if rStyle is None: + return None + return rStyle.val + + @style.setter + def style(self, style: str | None) -> None: + """Set `./w:rStyle/@val` to `style`, adding the `w:rStyle` element if necessary. + + If `style` is |None|, remove `w:rStyle` element if present. + """ + if style is None: + self._remove_rStyle() + elif self.rStyle is None: + self._add_rStyle(val=style) + else: + self.rStyle.val = style + + @property + def subscript(self) -> bool | None: + """|True| if `./w:vertAlign/@w:val` is "subscript". + + |False| if `w:vertAlign/@w:val` contains any other value. |None| if + `w:vertAlign` is not present. + """ + vertAlign = self.vertAlign + if vertAlign is None: + return None + return vertAlign.val == ST_VerticalAlignRun.SUBSCRIPT + + @subscript.setter + def subscript(self, value: bool | None) -> None: + if value is None: + self._remove_vertAlign() + elif bool(value) is True: + self.get_or_add_vertAlign().val = ST_VerticalAlignRun.SUBSCRIPT + # -- assert bool(value) is False -- + elif self.vertAlign is not None and self.vertAlign.val == ST_VerticalAlignRun.SUBSCRIPT: + self._remove_vertAlign() + + @property + def superscript(self) -> bool | None: + """|True| if `w:vertAlign/@w:val` is 'superscript'. + + |False| if `w:vertAlign/@w:val` contains any other value. |None| if + `w:vertAlign` is not present. + """ + vertAlign = self.vertAlign + if vertAlign is None: + return None + return vertAlign.val == ST_VerticalAlignRun.SUPERSCRIPT + + @superscript.setter + def superscript(self, value: bool | None): + if value is None: + self._remove_vertAlign() + elif bool(value) is True: + self.get_or_add_vertAlign().val = ST_VerticalAlignRun.SUPERSCRIPT + # -- assert bool(value) is False -- + elif self.vertAlign is not None and self.vertAlign.val == ST_VerticalAlignRun.SUPERSCRIPT: + self._remove_vertAlign() + + @property + def sz_val(self) -> Length | None: + """The value of `w:sz/@w:val` or |None| if not present.""" + sz = self.sz + if sz is None: + return None + return sz.val + + @sz_val.setter + def sz_val(self, value: Length | None): + if value is None: + self._remove_sz() + return + sz = self.get_or_add_sz() + sz.val = value + + @property + def u_val(self) -> WD_UNDERLINE | None: + """Value of `w:u/@val`, or None if not present. + + Values `WD_UNDERLINE.SINGLE` and `WD_UNDERLINE.NONE` are mapped to `True` and + `False` respectively. + """ + u = self.u + if u is None: + return None + return u.val + + @u_val.setter + def u_val(self, value: WD_UNDERLINE | None): + self._remove_u() + if value is not None: + self._add_u().val = value + + def _get_bool_val(self, name: str) -> bool | None: + """Value of boolean child with `name`, e.g. "w:b", "w:i", and "w:smallCaps".""" + element = getattr(self, name) + if element is None: + return None + return element.val + + def _set_bool_val(self, name: str, value: bool | None): + if value is None: + getattr(self, "_remove_%s" % name)() + return + element = getattr(self, "get_or_add_%s" % name)() + element.val = value + + +class CT_Underline(BaseOxmlElement): + """`` element, specifying the underlining style for a run.""" + + val: WD_UNDERLINE | None = OptionalAttribute("w:val", WD_UNDERLINE) + + +class CT_VerticalAlignRun(BaseOxmlElement): + """`` element, specifying subscript or superscript.""" + + val: str = RequiredAttribute("w:val", ST_VerticalAlignRun) diff --git a/src/docx/oxml/text/hyperlink.py b/src/docx/oxml/text/hyperlink.py new file mode 100644 index 00000000..38a33ff1 --- /dev/null +++ b/src/docx/oxml/text/hyperlink.py @@ -0,0 +1,45 @@ +"""Custom element classes related to hyperlinks (CT_Hyperlink).""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, List + +from docx.oxml.simpletypes import ST_OnOff, ST_String, XsdString +from docx.oxml.text.run import CT_R +from docx.oxml.xmlchemy import ( + BaseOxmlElement, + OptionalAttribute, + ZeroOrMore, +) + +if TYPE_CHECKING: + from docx.oxml.text.pagebreak import CT_LastRenderedPageBreak + + +class CT_Hyperlink(BaseOxmlElement): + """`` element, containing the text and address for a hyperlink.""" + + r_lst: List[CT_R] + + rId: str | None = OptionalAttribute("r:id", XsdString) # pyright: ignore[reportAssignmentType] + anchor: str | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:anchor", ST_String + ) + history: bool = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:history", ST_OnOff, default=True + ) + + r = ZeroOrMore("w:r") + + @property + def lastRenderedPageBreaks(self) -> List[CT_LastRenderedPageBreak]: + """All `w:lastRenderedPageBreak` descendants of this hyperlink.""" + return self.xpath("./w:r/w:lastRenderedPageBreak") + + @property + def text(self) -> str: # pyright: ignore[reportIncompatibleMethodOverride] + """The textual content of this hyperlink. + + `CT_Hyperlink` stores the hyperlink-text as one or more `w:r` children. + """ + return "".join(r.text for r in self.xpath("w:r")) diff --git a/src/docx/oxml/text/pagebreak.py b/src/docx/oxml/text/pagebreak.py new file mode 100644 index 00000000..45a6f51a --- /dev/null +++ b/src/docx/oxml/text/pagebreak.py @@ -0,0 +1,278 @@ +"""Custom element class for rendered page-break (CT_LastRenderedPageBreak).""" + +from __future__ import annotations + +import copy +from typing import TYPE_CHECKING + +from docx.oxml.xmlchemy import BaseOxmlElement +from docx.shared import lazyproperty + +if TYPE_CHECKING: + from docx.oxml.text.hyperlink import CT_Hyperlink + from docx.oxml.text.paragraph import CT_P + + +class CT_LastRenderedPageBreak(BaseOxmlElement): + """`` element, indicating page break inserted by renderer. + + A rendered page-break is one inserted by the renderer when it runs out of room on a + page. It is an empty element (no attrs or children) and is a child of CT_R, peer to + CT_Text. + + NOTE: this complex-type name does not exist in the schema, where + `w:lastRenderedPageBreak` maps to `CT_Empty`. This name was added to give it + distinguished behavior. CT_Empty is used for many elements. + """ + + @property + def following_fragment_p(self) -> CT_P: + """A "loose" `CT_P` containing only the paragraph content before this break. + + Raises `ValueError` if this `w:lastRenderedPageBreak` is not the first rendered + page-break in its paragraph. + + The returned `CT_P` is a "clone" (deepcopy) of the `w:p` ancestor of this + page-break with this `w:lastRenderedPageBreak` element and all content preceding + it removed. + + NOTE: this `w:p` can itself contain one or more `w:renderedPageBreak` elements + (when the paragraph contained more than one). While this is rare, the caller + should treat this paragraph the same as other paragraphs and split it if + necessary in a folloing step or recursion. + """ + if not self == self._first_lrpb_in_p(self._enclosing_p): + raise ValueError("only defined on first rendered page-break in paragraph") + + # -- splitting approach is different when break is inside a hyperlink -- + return ( + self._following_frag_in_hlink if self._is_in_hyperlink else self._following_frag_in_run + ) + + @property + def follows_all_content(self) -> bool: + """True when this page-break element is the last "content" in the paragraph. + + This is very uncommon case and may only occur in contrived or cases where the + XML is edited by hand, but it is not precluded by the spec. + """ + # -- a page-break inside a hyperlink never meets these criteria (for our + # -- purposes at least) because it is considered "atomic" and always associated + # -- with the page it starts on. + if self._is_in_hyperlink: + return False + + return bool( + # -- XPath will match zero-or-one w:lastRenderedPageBreak element -- + self._enclosing_p.xpath( + # -- in first run of paragraph -- + f"(./w:r)[last()]" + # -- all page-breaks -- + f"/w:lastRenderedPageBreak" + # -- that are not preceded by any content-bearing elements -- + f"[not(following-sibling::*[{self._run_inner_content_xpath}])]" + ) + ) + + @property + def precedes_all_content(self) -> bool: + """True when a `w:lastRenderedPageBreak` precedes all paragraph content. + + This is a common case; it occurs whenever the page breaks on an even paragraph + boundary. + """ + # -- a page-break inside a hyperlink never meets these criteria because there + # -- is always part of the hyperlink text before the page-break. + if self._is_in_hyperlink: + return False + + return bool( + # -- XPath will match zero-or-one w:lastRenderedPageBreak element -- + self._enclosing_p.xpath( + # -- in first run of paragraph -- + f"./w:r[1]" + # -- all page-breaks -- + f"/w:lastRenderedPageBreak" + # -- that are not preceded by any content-bearing elements -- + f"[not(preceding-sibling::*[{self._run_inner_content_xpath}])]" + ) + ) + + @property + def preceding_fragment_p(self) -> CT_P: + """A "loose" `CT_P` containing only the paragraph content before this break. + + Raises `ValueError` if this `w:lastRenderedPageBreak` is not the first rendered + paragraph in its paragraph. + + The returned `CT_P` is a "clone" (deepcopy) of the `w:p` ancestor of this + page-break with this `w:lastRenderedPageBreak` element and all its following + siblings removed. + """ + if not self == self._first_lrpb_in_p(self._enclosing_p): + raise ValueError("only defined on first rendered page-break in paragraph") + + # -- splitting approach is different when break is inside a hyperlink -- + return ( + self._preceding_frag_in_hlink if self._is_in_hyperlink else self._preceding_frag_in_run + ) + + def _enclosing_hyperlink(self, lrpb: CT_LastRenderedPageBreak) -> CT_Hyperlink: + """The `w:hyperlink` grandparent of this `w:lastRenderedPageBreak`. + + Raises `IndexError` when this page-break has a `w:p` grandparent, so only call + when `._is_in_hyperlink` is True. + """ + return lrpb.xpath("./parent::w:r/parent::w:hyperlink")[0] + + @property + def _enclosing_p(self) -> CT_P: + """The `w:p` element parent or grandparent of this `w:lastRenderedPageBreak`.""" + return self.xpath("./ancestor::w:p[1]")[0] + + def _first_lrpb_in_p(self, p: CT_P) -> CT_LastRenderedPageBreak: + """The first `w:lastRenderedPageBreak` element in `p`. + + Raises `ValueError` if there are no rendered page-breaks in `p`. + """ + lrpbs = p.xpath("./w:r/w:lastRenderedPageBreak | ./w:hyperlink/w:r/w:lastRenderedPageBreak") + if not lrpbs: + raise ValueError("no rendered page-breaks in paragraph element") + return lrpbs[0] + + @lazyproperty + def _following_frag_in_hlink(self) -> CT_P: + """Following CT_P fragment when break occurs within a hyperlink. + + Note this is a *partial-function* and raises when `lrpb` is not inside a + hyperlink. + """ + if not self._is_in_hyperlink: + raise ValueError("only defined on a rendered page-break in a hyperlink") + + # -- work on a clone `w:p` so our mutations don't persist -- + p = copy.deepcopy(self._enclosing_p) + + # -- get this `w:lastRenderedPageBreak` in the cloned `w:p` (not self) -- + lrpb = self._first_lrpb_in_p(p) + + # -- locate `w:hyperlink` in which this `w:lastRenderedPageBreak` is found -- + hyperlink = lrpb._enclosing_hyperlink(lrpb) + + # -- delete all w:p inner-content preceding the hyperlink -- + for e in hyperlink.xpath("./preceding-sibling::*[not(self::w:pPr)]"): + p.remove(e) + + # -- remove the whole hyperlink, it belongs to the preceding-fragment-p -- + hyperlink.getparent().remove(hyperlink) + + # -- that's it, return the remaining fragment of `w:p` clone -- + return p + + @lazyproperty + def _following_frag_in_run(self) -> CT_P: + """following CT_P fragment when break does not occur in a hyperlink. + + Note this is a *partial-function* and raises when `lrpb` is inside a hyperlink. + """ + if self._is_in_hyperlink: + raise ValueError("only defined on a rendered page-break not in a hyperlink") + + # -- work on a clone `w:p` so our mutations don't persist -- + p = copy.deepcopy(self._enclosing_p) + + # -- get this `w:lastRenderedPageBreak` in the cloned `w:p` (not self) -- + lrpb = self._first_lrpb_in_p(p) + + # -- locate `w:r` in which this `w:lastRenderedPageBreak` is found -- + enclosing_r = lrpb.xpath("./parent::w:r")[0] + + # -- delete all w:p inner-content preceding that run (but not w:pPr) -- + for e in enclosing_r.xpath("./preceding-sibling::*[not(self::w:pPr)]"): + p.remove(e) + + # -- then remove all run inner-content preceding this lrpb in its run (but not + # -- the `w:rPr`) and also remove the page-break itself + for e in lrpb.xpath("./preceding-sibling::*[not(self::w:rPr)]"): + enclosing_r.remove(e) + enclosing_r.remove(lrpb) + + return p + + @lazyproperty + def _is_in_hyperlink(self) -> bool: + """True when this page-break is embedded in a hyperlink run.""" + return bool(self.xpath("./parent::w:r/parent::w:hyperlink")) + + @lazyproperty + def _preceding_frag_in_hlink(self) -> CT_P: + """Preceding CT_P fragment when break occurs within a hyperlink. + + Note this is a *partial-function* and raises when `lrpb` is not inside a + hyperlink. + """ + if not self._is_in_hyperlink: + raise ValueError("only defined on a rendered page-break in a hyperlink") + + # -- work on a clone `w:p` so our mutations don't persist -- + p = copy.deepcopy(self._enclosing_p) + + # -- get this `w:lastRenderedPageBreak` in the cloned `w:p` (not self) -- + lrpb = self._first_lrpb_in_p(p) + + # -- locate `w:hyperlink` in which this `w:lastRenderedPageBreak` is found -- + hyperlink = lrpb._enclosing_hyperlink(lrpb) + + # -- delete all w:p inner-content following the hyperlink -- + for e in hyperlink.xpath("./following-sibling::*"): + p.remove(e) + + # -- remove this page-break from inside the hyperlink -- + lrpb.getparent().remove(lrpb) + + # -- that's it, the entire hyperlink goes into the preceding fragment so + # -- the hyperlink is not "split". + return p + + @lazyproperty + def _preceding_frag_in_run(self) -> CT_P: + """Preceding CT_P fragment when break does not occur in a hyperlink. + + Note this is a *partial-function* and raises when `lrpb` is inside a hyperlink. + """ + if self._is_in_hyperlink: + raise ValueError("only defined on a rendered page-break not in a hyperlink") + + # -- work on a clone `w:p` so our mutations don't persist -- + p = copy.deepcopy(self._enclosing_p) + + # -- get this `w:lastRenderedPageBreak` in the cloned `w:p` (not self) -- + lrpb = self._first_lrpb_in_p(p) + + # -- locate `w:r` in which this `w:lastRenderedPageBreak` is found -- + enclosing_r = lrpb.xpath("./parent::w:r")[0] + + # -- delete all `w:p` inner-content following that run -- + for e in enclosing_r.xpath("./following-sibling::*"): + p.remove(e) + + # -- then delete all `w:r` inner-content following this lrpb in its run and + # -- also remove the page-break itself + for e in lrpb.xpath("./following-sibling::*"): + enclosing_r.remove(e) + enclosing_r.remove(lrpb) + + return p + + @lazyproperty + def _run_inner_content_xpath(self) -> str: + """XPath fragment matching any run inner-content elements.""" + return ( + "self::w:br" + " | self::w:cr" + " | self::w:drawing" + " | self::w:noBreakHyphen" + " | self::w:ptab" + " | self::w:t" + " | self::w:tab" + ) diff --git a/src/docx/oxml/text/paragraph.py b/src/docx/oxml/text/paragraph.py new file mode 100644 index 00000000..63e96f31 --- /dev/null +++ b/src/docx/oxml/text/paragraph.py @@ -0,0 +1,106 @@ +# pyright: reportPrivateUsage=false + +"""Custom element classes related to paragraphs (CT_P).""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Callable, List, cast + +from docx.oxml.parser import OxmlElement +from docx.oxml.xmlchemy import BaseOxmlElement, ZeroOrMore, ZeroOrOne + +if TYPE_CHECKING: + from docx.enum.text import WD_PARAGRAPH_ALIGNMENT + from docx.oxml.section import CT_SectPr + from docx.oxml.text.hyperlink import CT_Hyperlink + from docx.oxml.text.pagebreak import CT_LastRenderedPageBreak + from docx.oxml.text.parfmt import CT_PPr + from docx.oxml.text.run import CT_R + + +class CT_P(BaseOxmlElement): + """`` element, containing the properties and text for a paragraph.""" + + add_r: Callable[[], CT_R] + get_or_add_pPr: Callable[[], CT_PPr] + hyperlink_lst: List[CT_Hyperlink] + r_lst: List[CT_R] + + pPr: CT_PPr | None = ZeroOrOne("w:pPr") # pyright: ignore[reportAssignmentType] + hyperlink = ZeroOrMore("w:hyperlink") + r = ZeroOrMore("w:r") + + def add_p_before(self) -> CT_P: + """Return a new `` element inserted directly prior to this one.""" + new_p = cast(CT_P, OxmlElement("w:p")) + self.addprevious(new_p) + return new_p + + @property + def alignment(self) -> WD_PARAGRAPH_ALIGNMENT | None: + """The value of the `` grandchild element or |None| if not present.""" + pPr = self.pPr + if pPr is None: + return None + return pPr.jc_val + + @alignment.setter + def alignment(self, value: WD_PARAGRAPH_ALIGNMENT): + pPr = self.get_or_add_pPr() + pPr.jc_val = value + + def clear_content(self): + """Remove all child elements, except the `` element if present.""" + for child in self.xpath("./*[not(self::w:pPr)]"): + self.remove(child) + + @property + def inner_content_elements(self) -> List[CT_R | CT_Hyperlink]: + """Run and hyperlink children of the `w:p` element, in document order.""" + return self.xpath("./w:r | ./w:hyperlink") + + @property + def lastRenderedPageBreaks(self) -> List[CT_LastRenderedPageBreak]: + """All `w:lastRenderedPageBreak` descendants of this paragraph. + + Rendered page-breaks commonly occur in a run but can also occur in a run inside + a hyperlink. This returns both. + """ + return self.xpath( + "./w:r/w:lastRenderedPageBreak | ./w:hyperlink/w:r/w:lastRenderedPageBreak" + ) + + def set_sectPr(self, sectPr: CT_SectPr): + """Unconditionally replace or add `sectPr` as grandchild in correct sequence.""" + pPr = self.get_or_add_pPr() + pPr._remove_sectPr() + pPr._insert_sectPr(sectPr) + + @property + def style(self) -> str | None: + """String contained in `w:val` attribute of `./w:pPr/w:pStyle` grandchild. + + |None| if not present. + """ + pPr = self.pPr + if pPr is None: + return None + return pPr.style + + @style.setter + def style(self, style: str | None): + pPr = self.get_or_add_pPr() + pPr.style = style + + @property + def text(self): # pyright: ignore[reportIncompatibleMethodOverride] + """The textual content of this paragraph. + + Inner-content child elements like `w:r` and `w:hyperlink` are translated to + their text equivalent. + """ + return "".join(e.text for e in self.xpath("w:r | w:hyperlink")) + + def _insert_pPr(self, pPr: CT_PPr) -> CT_PPr: + self.insert(0, pPr) + return pPr diff --git a/docx/oxml/text/parfmt.py b/src/docx/oxml/text/parfmt.py similarity index 58% rename from docx/oxml/text/parfmt.py rename to src/docx/oxml/text/parfmt.py index cae729d5..2133686b 100644 --- a/docx/oxml/text/parfmt.py +++ b/src/docx/oxml/text/parfmt.py @@ -1,49 +1,65 @@ -# encoding: utf-8 +"""Custom element classes related to paragraph properties (CT_PPr).""" -""" -Custom element classes related to paragraph properties (CT_PPr). -""" +from __future__ import annotations -from ...enum.text import ( +from typing import TYPE_CHECKING, Callable + +from docx.enum.text import ( WD_ALIGN_PARAGRAPH, WD_LINE_SPACING, WD_TAB_ALIGNMENT, WD_TAB_LEADER, ) -from ...shared import Length -from ..simpletypes import ST_SignedTwipsMeasure, ST_TwipsMeasure -from ..xmlchemy import ( +from docx.oxml.shared import CT_DecimalNumber +from docx.oxml.simpletypes import ST_SignedTwipsMeasure, ST_TwipsMeasure +from docx.oxml.xmlchemy import ( BaseOxmlElement, OneOrMore, OptionalAttribute, RequiredAttribute, ZeroOrOne, ) +from docx.shared import Length + +if TYPE_CHECKING: + from docx.oxml.section import CT_SectPr + from docx.oxml.shared import CT_String class CT_Ind(BaseOxmlElement): - """ - ```` element, specifying paragraph indentation. - """ + """```` element, specifying paragraph indentation.""" - left = OptionalAttribute("w:left", ST_SignedTwipsMeasure) - right = OptionalAttribute("w:right", ST_SignedTwipsMeasure) - firstLine = OptionalAttribute("w:firstLine", ST_TwipsMeasure) - hanging = OptionalAttribute("w:hanging", ST_TwipsMeasure) + left: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:left", ST_SignedTwipsMeasure + ) + right: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:right", ST_SignedTwipsMeasure + ) + firstLine: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:firstLine", ST_TwipsMeasure + ) + hanging: Length | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:hanging", ST_TwipsMeasure + ) class CT_Jc(BaseOxmlElement): - """ - ```` element, specifying paragraph justification. - """ + """```` element, specifying paragraph justification.""" - val = RequiredAttribute("w:val", WD_ALIGN_PARAGRAPH) + val: WD_ALIGN_PARAGRAPH = RequiredAttribute( # pyright: ignore[reportAssignmentType] + "w:val", WD_ALIGN_PARAGRAPH + ) class CT_PPr(BaseOxmlElement): - """ - ```` element, containing the properties for a paragraph. - """ + """```` element, containing the properties for a paragraph.""" + + get_or_add_ind: Callable[[], CT_Ind] + get_or_add_pStyle: Callable[[], CT_String] + get_or_add_sectPr: Callable[[], CT_SectPr] + _insert_sectPr: Callable[[CT_SectPr], None] + _remove_pStyle: Callable[[], None] + _remove_sectPr: Callable[[], None] _tag_seq = ( "w:pStyle", @@ -83,7 +99,9 @@ class CT_PPr(BaseOxmlElement): "w:sectPr", "w:pPrChange", ) - pStyle = ZeroOrOne("w:pStyle", successors=_tag_seq[1:]) + pStyle: CT_String | None = ZeroOrOne( # pyright: ignore[reportAssignmentType] + "w:pStyle", successors=_tag_seq[1:] + ) keepNext = ZeroOrOne("w:keepNext", successors=_tag_seq[2:]) keepLines = ZeroOrOne("w:keepLines", successors=_tag_seq[3:]) pageBreakBefore = ZeroOrOne("w:pageBreakBefore", successors=_tag_seq[4:]) @@ -91,17 +109,22 @@ class CT_PPr(BaseOxmlElement): numPr = ZeroOrOne("w:numPr", successors=_tag_seq[7:]) tabs = ZeroOrOne("w:tabs", successors=_tag_seq[11:]) spacing = ZeroOrOne("w:spacing", successors=_tag_seq[22:]) - ind = ZeroOrOne("w:ind", successors=_tag_seq[23:]) + ind: CT_Ind | None = ZeroOrOne( # pyright: ignore[reportAssignmentType] + "w:ind", successors=_tag_seq[23:] + ) jc = ZeroOrOne("w:jc", successors=_tag_seq[27:]) + outlineLvl: CT_DecimalNumber = ZeroOrOne( # pyright: ignore[reportAssignmentType] + "w:outlineLvl", successors=_tag_seq[31:] + ) sectPr = ZeroOrOne("w:sectPr", successors=_tag_seq[35:]) del _tag_seq @property - def first_line_indent(self): - """ - A |Length| value calculated from the values of `w:ind/@w:firstLine` - and `w:ind/@w:hanging`. Returns |None| if the `w:ind` child is not - present. + def first_line_indent(self) -> Length | None: + """A |Length| value calculated from the values of `w:ind/@w:firstLine` and + `w:ind/@w:hanging`. + + Returns |None| if the `w:ind` child is not present. """ ind = self.ind if ind is None: @@ -115,7 +138,7 @@ def first_line_indent(self): return firstLine @first_line_indent.setter - def first_line_indent(self, value): + def first_line_indent(self, value: Length | None): if self.ind is None and value is None: return ind = self.get_or_add_ind() @@ -128,48 +151,39 @@ def first_line_indent(self, value): ind.firstLine = value @property - def ind_left(self): - """ - The value of `w:ind/@w:left` or |None| if not present. - """ + def ind_left(self) -> Length | None: + """The value of `w:ind/@w:left` or |None| if not present.""" ind = self.ind if ind is None: return None return ind.left @ind_left.setter - def ind_left(self, value): + def ind_left(self, value: Length | None): if value is None and self.ind is None: return ind = self.get_or_add_ind() ind.left = value @property - def ind_right(self): - """ - The value of `w:ind/@w:right` or |None| if not present. - """ + def ind_right(self) -> Length | None: + """The value of `w:ind/@w:right` or |None| if not present.""" ind = self.ind if ind is None: return None return ind.right @ind_right.setter - def ind_right(self, value): + def ind_right(self, value: Length | None): if value is None and self.ind is None: return ind = self.get_or_add_ind() ind.right = value @property - def jc_val(self): - """ - The value of the ```` child element or |None| if not present. - """ - jc = self.jc - if jc is None: - return None - return jc.val + def jc_val(self) -> WD_ALIGN_PARAGRAPH | None: + """Value of the `` child element or |None| if not present.""" + return self.jc.val if self.jc is not None else None @jc_val.setter def jc_val(self, value): @@ -180,9 +194,7 @@ def jc_val(self, value): @property def keepLines_val(self): - """ - The value of `keepLines/@val` or |None| if not present. - """ + """The value of `keepLines/@val` or |None| if not present.""" keepLines = self.keepLines if keepLines is None: return None @@ -197,9 +209,7 @@ def keepLines_val(self, value): @property def keepNext_val(self): - """ - The value of `keepNext/@val` or |None| if not present. - """ + """The value of `keepNext/@val` or |None| if not present.""" keepNext = self.keepNext if keepNext is None: return None @@ -214,9 +224,7 @@ def keepNext_val(self, value): @property def pageBreakBefore_val(self): - """ - The value of `pageBreakBefore/@val` or |None| if not present. - """ + """The value of `pageBreakBefore/@val` or |None| if not present.""" pageBreakBefore = self.pageBreakBefore if pageBreakBefore is None: return None @@ -231,9 +239,7 @@ def pageBreakBefore_val(self, value): @property def spacing_after(self): - """ - The value of `w:spacing/@w:after` or |None| if not present. - """ + """The value of `w:spacing/@w:after` or |None| if not present.""" spacing = self.spacing if spacing is None: return None @@ -247,9 +253,7 @@ def spacing_after(self, value): @property def spacing_before(self): - """ - The value of `w:spacing/@w:before` or |None| if not present. - """ + """The value of `w:spacing/@w:before` or |None| if not present.""" spacing = self.spacing if spacing is None: return None @@ -263,9 +267,7 @@ def spacing_before(self, value): @property def spacing_line(self): - """ - The value of `w:spacing/@w:line` or |None| if not present. - """ + """The value of `w:spacing/@w:line` or |None| if not present.""" spacing = self.spacing if spacing is None: return None @@ -279,12 +281,13 @@ def spacing_line(self, value): @property def spacing_lineRule(self): - """ - The value of `w:spacing/@w:lineRule` as a member of the - :ref:`WdLineSpacing` enumeration. Only the `MULTIPLE`, `EXACTLY`, and - `AT_LEAST` members are used. It is the responsibility of the client - to calculate the use of `SINGLE`, `DOUBLE`, and `MULTIPLE` based on - the value of `w:spacing/@w:line` if that behavior is desired. + """The value of `w:spacing/@w:lineRule` as a member of the :ref:`WdLineSpacing` + enumeration. + + Only the `MULTIPLE`, `EXACTLY`, and `AT_LEAST` members are used. It is the + responsibility of the client to calculate the use of `SINGLE`, `DOUBLE`, and + `MULTIPLE` based on the value of `w:spacing/@w:line` if that behavior is + desired. """ spacing = self.spacing if spacing is None: @@ -301,22 +304,18 @@ def spacing_lineRule(self, value): self.get_or_add_spacing().lineRule = value @property - def style(self): - """ - String contained in child, or None if that element is not - present. - """ + def style(self) -> str | None: + """String contained in `./w:pStyle/@val`, or None if child is not present.""" pStyle = self.pStyle if pStyle is None: return None return pStyle.val @style.setter - def style(self, style): - """ - Set val attribute of child element to *style*, adding a - new element if necessary. If *style* is |None|, remove the - element if present. + def style(self, style: str | None): + """Set `./w:pStyle/@val` `style`, adding a new element if necessary. + + If `style` is |None|, remove `./w:pStyle` when present. """ if style is None: self._remove_pStyle() @@ -326,9 +325,7 @@ def style(self, style): @property def widowControl_val(self): - """ - The value of `widowControl/@val` or |None| if not present. - """ + """The value of `widowControl/@val` or |None| if not present.""" widowControl = self.widowControl if widowControl is None: return None @@ -343,10 +340,8 @@ def widowControl_val(self, value): class CT_Spacing(BaseOxmlElement): - """ - ```` element, specifying paragraph spacing attributes such as - space before and line spacing. - """ + """```` element, specifying paragraph spacing attributes such as space + before and line spacing.""" after = OptionalAttribute("w:after", ST_TwipsMeasure) before = OptionalAttribute("w:before", ST_TwipsMeasure) @@ -355,26 +350,38 @@ class CT_Spacing(BaseOxmlElement): class CT_TabStop(BaseOxmlElement): - """ - ```` element, representing an individual tab stop. + """`` element, representing an individual tab stop. + + Overloaded to use for a tab-character in a run, which also uses the w:tab tag but + only needs a __str__ method. """ - val = RequiredAttribute("w:val", WD_TAB_ALIGNMENT) - leader = OptionalAttribute("w:leader", WD_TAB_LEADER, default=WD_TAB_LEADER.SPACES) - pos = RequiredAttribute("w:pos", ST_SignedTwipsMeasure) + val: WD_TAB_ALIGNMENT = RequiredAttribute( # pyright: ignore[reportAssignmentType] + "w:val", WD_TAB_ALIGNMENT + ) + leader: WD_TAB_LEADER | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:leader", WD_TAB_LEADER, default=WD_TAB_LEADER.SPACES + ) + pos: Length = RequiredAttribute( # pyright: ignore[reportAssignmentType] + "w:pos", ST_SignedTwipsMeasure + ) + + def __str__(self) -> str: + """Text equivalent of a `w:tab` element appearing in a run. + + Allows text of run inner-content to be accessed consistently across all text + inner-content. + """ + return "\t" class CT_TabStops(BaseOxmlElement): - """ - ```` element, container for a sorted sequence of tab stops. - """ + """```` element, container for a sorted sequence of tab stops.""" tab = OneOrMore("w:tab", successors=()) def insert_tab_in_order(self, pos, align, leader): - """ - Insert a newly created `w:tab` child element in *pos* order. - """ + """Insert a newly created `w:tab` child element in `pos` order.""" new_tab = self._new_tab() new_tab.pos, new_tab.val, new_tab.leader = pos, align, leader for tab in self.tab_lst: diff --git a/src/docx/oxml/text/run.py b/src/docx/oxml/text/run.py new file mode 100644 index 00000000..e6de1bc6 --- /dev/null +++ b/src/docx/oxml/text/run.py @@ -0,0 +1,316 @@ +"""Custom element classes related to text runs (CT_R).""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Callable, Iterator, List, cast + +from docx.oxml.drawing import CT_Drawing +from docx.oxml.ns import qn +from docx.oxml.parser import OxmlElement +from docx.oxml.simpletypes import ST_BrClear, ST_BrType +from docx.oxml.text.font import CT_RPr +from docx.oxml.xmlchemy import BaseOxmlElement, OptionalAttribute, ZeroOrMore, ZeroOrOne +from docx.shared import TextAccumulator + +if TYPE_CHECKING: + from docx.oxml.shape import CT_Anchor, CT_Inline + from docx.oxml.text.pagebreak import CT_LastRenderedPageBreak + from docx.oxml.text.parfmt import CT_TabStop + +# ------------------------------------------------------------------------------------ +# Run-level elements + + +class CT_R(BaseOxmlElement): + """`` element, containing the properties and text for a run.""" + + add_br: Callable[[], CT_Br] + add_tab: Callable[[], CT_TabStop] + get_or_add_rPr: Callable[[], CT_RPr] + _add_drawing: Callable[[], CT_Drawing] + _add_t: Callable[..., CT_Text] + + rPr: CT_RPr | None = ZeroOrOne("w:rPr") # pyright: ignore[reportAssignmentType] + br = ZeroOrMore("w:br") + cr = ZeroOrMore("w:cr") + drawing = ZeroOrMore("w:drawing") + t = ZeroOrMore("w:t") + tab = ZeroOrMore("w:tab") + + def add_t(self, text: str) -> CT_Text: + """Return a newly added `` element containing `text`.""" + t = self._add_t(text=text) + if len(text.strip()) < len(text): + t.set(qn("xml:space"), "preserve") + return t + + def add_drawing(self, inline_or_anchor: CT_Inline | CT_Anchor) -> CT_Drawing: + """Return newly appended `CT_Drawing` (`w:drawing`) child element. + + The `w:drawing` element has `inline_or_anchor` as its child. + """ + drawing = self._add_drawing() + drawing.append(inline_or_anchor) + return drawing + + def clear_content(self) -> None: + """Remove all child elements except a `w:rPr` element if present.""" + # -- remove all run inner-content except a `w:rPr` when present. -- + for e in self.xpath("./*[not(self::w:rPr)]"): + self.remove(e) + + @property + def inner_content_items(self) -> List[str | CT_Drawing | CT_LastRenderedPageBreak]: + """Text of run, possibly punctuated by `w:lastRenderedPageBreak` elements.""" + from docx.oxml.text.pagebreak import CT_LastRenderedPageBreak + + accum = TextAccumulator() + + def iter_items() -> Iterator[str | CT_Drawing | CT_LastRenderedPageBreak]: + for e in self.xpath( + "w:br" + " | w:cr" + " | w:drawing" + " | w:lastRenderedPageBreak" + " | w:noBreakHyphen" + " | w:ptab" + " | w:t" + " | w:tab" + ): + if isinstance(e, (CT_Drawing, CT_LastRenderedPageBreak)): + yield from accum.pop() + yield e + else: + accum.push(str(e)) + + # -- don't forget the "tail" string -- + yield from accum.pop() + + return list(iter_items()) + + def insert_comment_range_end_and_reference_below(self, comment_id: int) -> None: + """Insert a `w:commentRangeEnd` and `w:commentReference` element after this run. + + The `w:commentRangeEnd` element is the immediate sibling of this `w:r` and is followed by + a `w:r` containing the `w:commentReference` element. + """ + self.addnext(self._new_comment_reference_run(comment_id)) + self.addnext(OxmlElement("w:commentRangeEnd", attrs={qn("w:id"): str(comment_id)})) + + def insert_comment_range_start_above(self, comment_id: int) -> None: + """Insert a `w:commentRangeStart` element with `comment_id` before this run.""" + self.addprevious(OxmlElement("w:commentRangeStart", attrs={qn("w:id"): str(comment_id)})) + + @property + def lastRenderedPageBreaks(self) -> List[CT_LastRenderedPageBreak]: + """All `w:lastRenderedPageBreaks` descendants of this run.""" + return self.xpath("./w:lastRenderedPageBreak") + + @property + def style(self) -> str | None: + """String contained in `w:val` attribute of `w:rStyle` grandchild. + + |None| if that element is not present. + """ + rPr = self.rPr + if rPr is None: + return None + return rPr.style + + @style.setter + def style(self, style: str | None): + """Set character style of this `w:r` element to `style`. + + If `style` is None, remove the style element. + """ + rPr = self.get_or_add_rPr() + rPr.style = style + + @property + def text(self) -> str: + """The textual content of this run. + + Inner-content child elements like `w:tab` are translated to their text + equivalent. + """ + return "".join( + str(e) for e in self.xpath("w:br | w:cr | w:noBreakHyphen | w:ptab | w:t | w:tab") + ) + + @text.setter + def text(self, text: str): # pyright: ignore[reportIncompatibleMethodOverride] + self.clear_content() + _RunContentAppender.append_to_run_from_text(self, text) + + @property + def texts(self) -> str: + """Alias for `text` property for compatibility with python-docx-oss.""" + return self.text + + @texts.setter + def texts(self, text: str): + self.text = text + + def _insert_rPr(self, rPr: CT_RPr) -> CT_RPr: + self.insert(0, rPr) + return rPr + + def _new_comment_reference_run(self, comment_id: int) -> CT_R: + """Return a new `w:r` element with `w:commentReference` referencing `comment_id`. + + Should look like this: + + + + + + + """ + r = cast(CT_R, OxmlElement("w:r")) + rPr = r.get_or_add_rPr() + rPr.style = "CommentReference" + r.append(OxmlElement("w:commentReference", attrs={qn("w:id"): str(comment_id)})) + return r + + +# ------------------------------------------------------------------------------------ +# Run inner-content elements + + +class CT_Br(BaseOxmlElement): + """`` element, indicating a line, page, or column break in a run.""" + + type: str | None = OptionalAttribute( # pyright: ignore[reportAssignmentType] + "w:type", ST_BrType, default="textWrapping" + ) + clear: str | None = OptionalAttribute("w:clear", ST_BrClear) # pyright: ignore + + def __str__(self) -> str: + """Text equivalent of this element. Actual value depends on break type. + + A line break is translated as "\n". Column and page breaks produce the empty + string (""). + + This allows the text of run inner-content to be accessed in a consistent way + for all run inner-context text elements. + """ + return "\n" if self.type == "textWrapping" else "" + + +class CT_Cr(BaseOxmlElement): + """`` element, representing a carriage-return (0x0D) character within a run. + + In Word, this represents a "soft carriage-return" in the sense that it does not end + the paragraph the way pressing Enter (aka. Return) on the keyboard does. Here the + text equivalent is considered to be newline ("\n") since in plain-text that's the + closest Python equivalent. + + NOTE: this complex-type name does not exist in the schema, where `w:tab` maps to + `CT_Empty`. This name was added to give it distinguished behavior. CT_Empty is used + for many elements. + """ + + def __str__(self) -> str: + """Text equivalent of this element, a single newline ("\n").""" + return "\n" + + +class CT_NoBreakHyphen(BaseOxmlElement): + """`` element, a hyphen ineligible for a line-wrap position. + + This maps to a plain-text dash ("-"). + + NOTE: this complex-type name does not exist in the schema, where `w:noBreakHyphen` + maps to `CT_Empty`. This name was added to give it behavior distinguished from the + many other elements represented in the schema by CT_Empty. + """ + + def __str__(self) -> str: + """Text equivalent of this element, a single dash character ("-").""" + return "-" + + +class CT_PTab(BaseOxmlElement): + """`` element, representing an absolute-position tab character within a run. + + This character advances the rendering position to the specified position regardless + of any tab-stops, perhaps for layout of a table-of-contents (TOC) or similar. + """ + + def __str__(self) -> str: + """Text equivalent of this element, a single tab ("\t") character. + + This allows the text of run inner-content to be accessed in a consistent way + for all run inner-context text elements. + """ + return "\t" + + +# -- CT_Tab functionality is provided by CT_TabStop which also uses `w:tab` tag. That +# -- element class provides the __str__() method for this empty element, unconditionally +# -- returning "\t". + + +class CT_Text(BaseOxmlElement): + """`` element, containing a sequence of characters within a run.""" + + def __str__(self) -> str: + """Text contained in this element, the empty string if it has no content. + + This property allows this run inner-content element to be queried for its text + the same way as other run-content elements are. In particular, this never + returns None, as etree._Element does when there is no content. + """ + return self.text or "" + + +# ------------------------------------------------------------------------------------ +# Utility + + +class _RunContentAppender: + """Translates a Python string into run content elements appended in a `w:r` element. + + Contiguous sequences of regular characters are appended in a single `` element. + Each tab character ('\t') causes a `` element to be appended. Likewise a + newline or carriage return character ('\n', '\r') causes a `` element to be + appended. + """ + + def __init__(self, r: CT_R): + self._r = r + self._bfr: List[str] = [] + + @classmethod + def append_to_run_from_text(cls, r: CT_R, text: str): + """Append inner-content elements for `text` to `r` element.""" + appender = cls(r) + appender.add_text(text) + + def add_text(self, text: str): + """Append inner-content elements for `text` to the `w:r` element.""" + for char in text: + self.add_char(char) + self.flush() + + def add_char(self, char: str): + """Process next character of input through finite state maching (FSM). + + There are two possible states, buffer pending and not pending, but those are + hidden behind the `.flush()` method which must be called at the end of text to + ensure any pending `` element is written. + """ + if char == "\t": + self.flush() + self._r.add_tab() + elif char in "\r\n": + self.flush() + self._r.add_br() + else: + self._bfr.append(char) + + def flush(self): + text = "".join(self._bfr) + if text: + self._r.add_t(text) + self._bfr.clear() diff --git a/docx/oxml/xmlchemy.py b/src/docx/oxml/xmlchemy.py similarity index 53% rename from docx/oxml/xmlchemy.py rename to src/docx/oxml/xmlchemy.py index 72983dc2..54237b12 100644 --- a/docx/oxml/xmlchemy.py +++ b/src/docx/oxml/xmlchemy.py @@ -1,37 +1,36 @@ -# encoding: utf-8 +# pyright: reportImportCycles=false -""" -Provides a wrapper around lxml that enables declarative definition of custom -element classes. -""" +"""Enabling declarative definition of lxml custom element classes.""" -from __future__ import absolute_import +from __future__ import annotations import re +from typing import TYPE_CHECKING, Any, Callable, Sequence, Type, TypeVar from lxml import etree +from lxml.etree import ElementBase, _Element # pyright: ignore[reportPrivateUsage] -from docx.compat import Unicode -from docx.oxml import OxmlElement from docx.oxml.exceptions import InvalidXmlError from docx.oxml.ns import NamespacePrefixedTag, nsmap, qn from docx.shared import lazyproperty +if TYPE_CHECKING: + from docx.enum.base import BaseXmlEnum + from docx.oxml.simpletypes import BaseSimpleType -def serialize_for_reading(element): - """ - Serialize *element* to human-readable XML suitable for tests. No XML - declaration. + +def serialize_for_reading(element: ElementBase): + """Serialize `element` to human-readable XML suitable for tests. + + No XML declaration. """ xml = etree.tostring(element, encoding="unicode", pretty_print=True) return XmlString(xml) -class XmlString(Unicode): - """ - Provides string comparison override suitable for serialized XML that is - useful for tests. - """ +class XmlString(str): + """Provides string comparison override suitable for serialized XML that is useful + for tests.""" # ' text' # | | || | @@ -41,7 +40,9 @@ class XmlString(Unicode): _xml_elm_line_patt = re.compile(r"( *)([^<]*)?$") - def __eq__(self, other): + def __eq__(self, other: object) -> bool: + if not isinstance(other, str): + return False lines = self.splitlines() lines_other = other.splitlines() if len(lines) != len(lines_other): @@ -51,23 +52,21 @@ def __eq__(self, other): return False return True - def __ne__(self, other): + def __ne__(self, other: object) -> bool: return not self.__eq__(other) - def _attr_seq(self, attrs): - """ - Return a sequence of attribute strings parsed from *attrs*. Each - attribute string is stripped of whitespace on both ends. + def _attr_seq(self, attrs: str) -> list[str]: + """Return a sequence of attribute strings parsed from `attrs`. + + Each attribute string is stripped of whitespace on both ends. """ attrs = attrs.strip() attr_lst = attrs.split() return sorted(attr_lst) - def _eq_elm_strs(self, line, line_2): - """ - Return True if the element in *line_2* is XML equivalent to the - element in *line*. - """ + def _eq_elm_strs(self, line: str, line_2: str): + """Return True if the element in `line_2` is XML equivalent to the element in + `line`.""" front, attrs, close, text = self._parse_line(line) front_2, attrs_2, close_2, text_2 = self._parse_line(line_2) if front != front_2: @@ -76,27 +75,25 @@ def _eq_elm_strs(self, line, line_2): return False if close != close_2: return False - if text != text_2: - return False - return True + return text == text_2 @classmethod - def _parse_line(cls, line): - """ - Return front, attrs, close, text 4-tuple result of parsing XML element - string *line*. - """ + def _parse_line(cls, line: str) -> tuple[str, str, str, str]: + """(front, attrs, close, text) 4-tuple result of parsing XML element `line`.""" match = cls._xml_elm_line_patt.match(line) + if match is None: + return "", "", "", "" front, attrs, close, text = [match.group(n) for n in range(1, 5)] return front, attrs, close, text +_T = TypeVar("_T") + + class MetaOxmlElement(type): - """ - Metaclass for BaseOxmlElement - """ + """Metaclass for BaseOxmlElement.""" - def __init__(self, _, __, clsdict): + def __init__(cls, clsname: str, bases: tuple[type, ...], namespace: dict[str, Any]): dispatchable = ( OneAndOnlyOne, OneOrMore, @@ -106,9 +103,9 @@ def __init__(self, _, __, clsdict): ZeroOrOne, ZeroOrOneChoice, ) - for key, value in clsdict.items(): + for key, value in namespace.items(): if isinstance(value, dispatchable): - value.populate_class_members(self, key) + value.populate_class_members(cls, key) @classmethod def create(cls): @@ -120,39 +117,37 @@ def create(cls): will raise the TypeError: descriptor '__dict__' for 'xxx' objects doesn't apply to a 'yyy' object. """ - cls_dict = dict(_OxmlElementBase.__dict__) + cls_dict = dict(cls.__dict__) cls_dict.pop("__dict__", None) return cls("BaseOxmlElement", (etree.ElementBase,), cls_dict) -class BaseAttribute(object): - """ - Base class for OptionalAttribute and RequiredAttribute, providing common - methods. +class BaseAttribute: + """Base class for OptionalAttribute and RequiredAttribute. + + Provides common methods. """ - def __init__(self, attr_name, simple_type): + def __init__(self, attr_name: str, simple_type: Type[BaseXmlEnum] | Type[BaseSimpleType]): super(BaseAttribute, self).__init__() self._attr_name = attr_name self._simple_type = simple_type - def populate_class_members(self, element_cls, prop_name): - """ - Add the appropriate methods to *element_cls*. - """ + def populate_class_members(self, element_cls: MetaOxmlElement, prop_name: str) -> None: + """Add the appropriate methods to `element_cls`.""" self._element_cls = element_cls self._prop_name = prop_name self._add_attr_property() def _add_attr_property(self): - """ - Add a read/write ``{prop_name}`` property to the element class that - returns the interpreted value of this attribute on access and changes - the attribute value to its ST_* counterpart on assignment. + """Add a read/write `.{prop_name}` property to the element class. + + The property returns the interpreted value of this attribute on access and + changes the attribute value to its ST_* counterpart on assignment. """ property_ = property(self._getter, self._setter, None) - # assign unconditionally to overwrite element name definition + # -- assign unconditionally to overwrite element name definition -- setattr(self._element_cls, self._prop_name, property_) @property @@ -161,26 +156,51 @@ def _clark_name(self): return qn(self._attr_name) return self._attr_name + @property + def _getter(self) -> Callable[[BaseOxmlElement], Any | None]: ... + + @property + def _setter( + self, + ) -> Callable[[BaseOxmlElement, Any | None], None]: ... + class OptionalAttribute(BaseAttribute): - """ - Defines an optional attribute on a custom element class. An optional - attribute returns a default value when not present for reading. When - assigned |None|, the attribute is removed. + """Defines an optional attribute on a custom element class. + + An optional attribute returns a default value when not present for reading. When + assigned |None|, the attribute is removed, but still returns the default value when + one is specified. """ - def __init__(self, attr_name, simple_type, default=None): + def __init__( + self, + attr_name: str, + simple_type: Type[BaseXmlEnum] | Type[BaseSimpleType], + default: BaseXmlEnum | BaseSimpleType | str | bool | None = None, + ): super(OptionalAttribute, self).__init__(attr_name, simple_type) self._default = default @property - def _getter(self): - """ - Return a function object suitable for the "get" side of the attribute - property descriptor. - """ + def _docstring(self): + """String to use as `__doc__` attribute of attribute property.""" + return ( + f"{self._simple_type.__name__} type-converted value of" + f" ``{self._attr_name}`` attribute, or |None| (or specified default" + f" value) if not present. Assigning the default value causes the" + f" attribute to be removed from the element." + ) - def get_attr_value(obj): + @property + def _getter( + self, + ) -> Callable[[BaseOxmlElement], Any | None]: + """Function suitable for `__get__()` method on attribute property descriptor.""" + + def get_attr_value( + obj: BaseOxmlElement, + ) -> Any | None: attr_str_value = obj.get(self._clark_name) if attr_str_value is None: return self._default @@ -190,59 +210,52 @@ def get_attr_value(obj): return get_attr_value @property - def _docstring(self): - """ - Return the string to use as the ``__doc__`` attribute of the property - for this attribute. - """ - return ( - "%s type-converted value of ``%s`` attribute, or |None| (or spec" - "ified default value) if not present. Assigning the default valu" - "e causes the attribute to be removed from the element." - % (self._simple_type.__name__, self._attr_name) - ) - - @property - def _setter(self): - """ - Return a function object suitable for the "set" side of the attribute - property descriptor. - """ + def _setter(self) -> Callable[[BaseOxmlElement, Any], None]: + """Function suitable for `__set__()` method on attribute property descriptor.""" - def set_attr_value(obj, value): + def set_attr_value(obj: BaseOxmlElement, value: Any | None): if value is None or value == self._default: if self._clark_name in obj.attrib: del obj.attrib[self._clark_name] return str_value = self._simple_type.to_xml(value) + if str_value is None: + if self._clark_name in obj.attrib: + del obj.attrib[self._clark_name] + return obj.set(self._clark_name, str_value) return set_attr_value class RequiredAttribute(BaseAttribute): - """ - Defines a required attribute on a custom element class. A required - attribute is assumed to be present for reading, so does not have - a default value; its actual value is always used. If missing on read, - an |InvalidXmlError| is raised. It also does not remove the attribute if - |None| is assigned. Assigning |None| raises |TypeError| or |ValueError|, - depending on the simple type of the attribute. + """Defines a required attribute on a custom element class. + + A required attribute is assumed to be present for reading, so does not have a + default value; its actual value is always used. If missing on read, an + |InvalidXmlError| is raised. It also does not remove the attribute if |None| is + assigned. Assigning |None| raises |TypeError| or |ValueError|, depending on the + simple type of the attribute. """ @property - def _getter(self): - """ - Return a function object suitable for the "get" side of the attribute - property descriptor. - """ + def _docstring(self): + """Return the string to use as the ``__doc__`` attribute of the property for + this attribute.""" + return "%s type-converted value of ``%s`` attribute." % ( + self._simple_type.__name__, + self._attr_name, + ) + + @property + def _getter(self) -> Callable[[BaseOxmlElement], Any]: + """function object suitable for "get" side of attr property descriptor.""" - def get_attr_value(obj): + def get_attr_value(obj: BaseOxmlElement) -> Any | None: attr_str_value = obj.get(self._clark_name) if attr_str_value is None: raise InvalidXmlError( - "required '%s' attribute not present on element %s" - % (self._attr_name, obj.tag) + "required '%s' attribute not present on element %s" % (self._attr_name, obj.tag) ) return self._simple_type.from_xml(attr_str_value) @@ -250,56 +263,39 @@ def get_attr_value(obj): return get_attr_value @property - def _docstring(self): - """ - Return the string to use as the ``__doc__`` attribute of the property - for this attribute. - """ - return "%s type-converted value of ``%s`` attribute." % ( - self._simple_type.__name__, - self._attr_name, - ) - - @property - def _setter(self): - """ - Return a function object suitable for the "set" side of the attribute - property descriptor. - """ + def _setter(self) -> Callable[[BaseOxmlElement, Any], None]: + """function object suitable for "set" side of attribute property descriptor.""" - def set_attr_value(obj, value): + def set_attr_value(obj: BaseOxmlElement, value: Any): str_value = self._simple_type.to_xml(value) + if str_value is None: + raise ValueError(f"cannot assign {value} to this required attribute") obj.set(self._clark_name, str_value) return set_attr_value -class _BaseChildElement(object): - """ - Base class for the child element classes corresponding to varying - cardinalities, such as ZeroOrOne and ZeroOrMore. +class _BaseChildElement: + """Base class for the child-element classes. + + The child-element sub-classes correspond to varying cardinalities, such as ZeroOrOne + and ZeroOrMore. """ - def __init__(self, nsptagname, successors=()): + def __init__(self, nsptagname: str, successors: tuple[str, ...] = ()): super(_BaseChildElement, self).__init__() self._nsptagname = nsptagname self._successors = successors - def populate_class_members(self, element_cls, prop_name): - """ - Baseline behavior for adding the appropriate methods to - *element_cls*. - """ + def populate_class_members(self, element_cls: MetaOxmlElement, prop_name: str) -> None: + """Baseline behavior for adding the appropriate methods to `element_cls`.""" self._element_cls = element_cls self._prop_name = prop_name def _add_adder(self): - """ - Add an ``_add_x()`` method to the element class for this child - element. - """ + """Add an ``_add_x()`` method to the element class for this child element.""" - def _add_child(obj, **attrs): + def _add_child(obj: BaseOxmlElement, **attrs: Any): new_method = getattr(obj, self._new_method_name) child = new_method() for key, value in attrs.items(): @@ -315,10 +311,8 @@ def _add_child(obj, **attrs): self._add_to_class(self._add_method_name, _add_child) def _add_creator(self): - """ - Add a ``_new_{prop_name}()`` method to the element class that creates - a new, empty element of the correct type, having no attributes. - """ + """Add a ``_new_{prop_name}()`` method to the element class that creates a new, + empty element of the correct type, having no attributes.""" creator = self._creator creator.__doc__ = ( 'Return a "loose", newly created ``<%s>`` element having no attri' @@ -327,21 +321,16 @@ def _add_creator(self): self._add_to_class(self._new_method_name, creator) def _add_getter(self): - """ - Add a read-only ``{prop_name}`` property to the element class for - this child element. - """ + """Add a read-only ``{prop_name}`` property to the element class for this child + element.""" property_ = property(self._getter, None, None) - # assign unconditionally to overwrite element name definition + # -- assign unconditionally to overwrite element name definition -- setattr(self._element_cls, self._prop_name, property_) def _add_inserter(self): - """ - Add an ``_insert_x()`` method to the element class for this child - element. - """ + """Add an ``_insert_x()`` method to the element class for this child element.""" - def _insert_child(obj, child): + def _insert_child(obj: BaseOxmlElement, child: BaseOxmlElement): obj.insert_element_before(child, *self._successors) return child @@ -352,10 +341,8 @@ def _insert_child(obj, child): self._add_to_class(self._insert_method_name, _insert_child) def _add_list_getter(self): - """ - Add a read-only ``{prop_name}_lst`` property to the element class to - retrieve a list of child elements matching this type. - """ + """Add a read-only ``{prop_name}_lst`` property to the element class to retrieve + a list of child elements matching this type.""" prop_name = "%s_lst" % self._prop_name property_ = property(self._list_getter, None, None) setattr(self._element_cls, prop_name, property_) @@ -365,11 +352,9 @@ def _add_method_name(self): return "_add_%s" % self._prop_name def _add_public_adder(self): - """ - Add a public ``add_x()`` method to the parent element class. - """ + """Add a public ``add_x()`` method to the parent element class.""" - def add_child(obj): + def add_child(obj: BaseOxmlElement): private_add_method = getattr(obj, self._add_method_name) child = private_add_method() return child @@ -380,36 +365,33 @@ def add_child(obj): ) self._add_to_class(self._public_add_method_name, add_child) - def _add_to_class(self, name, method): - """ - Add *method* to the target class as *name*, unless *name* is already - defined on the class. - """ + def _add_to_class(self, name: str, method: Callable[..., Any]): + """Add `method` to the target class as `name`, unless `name` is already defined + on the class.""" if hasattr(self._element_cls, name): return setattr(self._element_cls, name, method) @property - def _creator(self): - """ - Return a function object that creates a new, empty element of the - right type, having no attributes. - """ + def _creator(self) -> Callable[[BaseOxmlElement], BaseOxmlElement]: + """Callable that creates an empty element of the right type, with no attrs.""" + from docx.oxml.parser import OxmlElement - def new_child_element(obj): + def new_child_element(obj: BaseOxmlElement): return OxmlElement(self._nsptagname) return new_child_element @property def _getter(self): - """ - Return a function object suitable for the "get" side of the property - descriptor. This default getter returns the child element with - matching tag name or |None| if not present. + """Return a function object suitable for the "get" side of the property + descriptor. + + This default getter returns the child element with matching tag name or |None| + if not present. """ - def get_child_element(obj): + def get_child_element(obj: BaseOxmlElement): return obj.find(qn(self._nsptagname)) get_child_element.__doc__ = ( @@ -423,12 +405,10 @@ def _insert_method_name(self): @property def _list_getter(self): - """ - Return a function object suitable for the "get" side of a list - property descriptor. - """ + """Return a function object suitable for the "get" side of a list property + descriptor.""" - def get_child_element_list(obj): + def get_child_element_list(obj: BaseOxmlElement): return obj.findall(qn(self._nsptagname)) get_child_element_list.__doc__ = ( @@ -439,11 +419,11 @@ def get_child_element_list(obj): @lazyproperty def _public_add_method_name(self): - """ - add_childElement() is public API for a repeating element, allowing - new elements to be added to the sequence. May be overridden to - provide a friendlier API to clients having domain appropriate - parameter names for required attributes. + """add_childElement() is public API for a repeating element, allowing new + elements to be added to the sequence. + + May be overridden to provide a friendlier API to clients having domain + appropriate parameter names for required attributes. """ return "add_%s" % self._prop_name @@ -457,19 +437,19 @@ def _new_method_name(self): class Choice(_BaseChildElement): - """ - Defines a child element belonging to a group, only one of which may - appear as a child. - """ + """Defines a child element belonging to a group, only one of which may appear as a child.""" @property def nsptagname(self): return self._nsptagname - def populate_class_members(self, element_cls, group_prop_name, successors): - """ - Add the appropriate methods to *element_cls*. - """ + def populate_class_members( # pyright: ignore[reportIncompatibleMethodOverride] + self, + element_cls: MetaOxmlElement, + group_prop_name: str, + successors: tuple[str, ...], + ) -> None: + """Add the appropriate methods to `element_cls`.""" self._element_cls = element_cls self._group_prop_name = group_prop_name self._successors = successors @@ -481,12 +461,10 @@ def populate_class_members(self, element_cls, group_prop_name, successors): self._add_get_or_change_to_method() def _add_get_or_change_to_method(self): - """ - Add a ``get_or_change_to_x()`` method to the element class for this - child element. - """ + """Add a ``get_or_change_to_x()`` method to the element class for this child + element.""" - def get_or_change_to_child(obj): + def get_or_change_to_child(obj: BaseOxmlElement): child = getattr(obj, self._prop_name) if child is not None: return child @@ -497,19 +475,14 @@ def get_or_change_to_child(obj): return child get_or_change_to_child.__doc__ = ( - "Return the ``<%s>`` child, replacing any other group element if" " found." + "Return the ``<%s>`` child, replacing any other group element if found." ) % self._nsptagname self._add_to_class(self._get_or_change_to_method_name, get_or_change_to_child) @property def _prop_name(self): - """ - Calculate property name from tag name, e.g. a:schemeClr -> schemeClr. - """ - if ":" in self._nsptagname: - start = self._nsptagname.index(":") + 1 - else: - start = 0 + """Property name computed from tag name, e.g. a:schemeClr -> schemeClr.""" + start = self._nsptagname.index(":") + 1 if ":" in self._nsptagname else 0 return self._nsptagname[start:] @lazyproperty @@ -522,28 +495,22 @@ def _remove_group_method_name(self): class OneAndOnlyOne(_BaseChildElement): - """ - Defines a required child element for MetaOxmlElement. - """ + """Defines a required child element for MetaOxmlElement.""" - def __init__(self, nsptagname): - super(OneAndOnlyOne, self).__init__(nsptagname, None) + def __init__(self, nsptagname: str): + super(OneAndOnlyOne, self).__init__(nsptagname, ()) - def populate_class_members(self, element_cls, prop_name): - """ - Add the appropriate methods to *element_cls*. - """ + def populate_class_members(self, element_cls: MetaOxmlElement, prop_name: str) -> None: + """Add the appropriate methods to `element_cls`.""" super(OneAndOnlyOne, self).populate_class_members(element_cls, prop_name) self._add_getter() @property def _getter(self): - """ - Return a function object suitable for the "get" side of the property - descriptor. - """ + """Return a function object suitable for the "get" side of the property + descriptor.""" - def get_child_element(obj): + def get_child_element(obj: BaseOxmlElement): child = obj.find(qn(self._nsptagname)) if child is None: raise InvalidXmlError( @@ -551,22 +518,16 @@ def get_child_element(obj): ) return child - get_child_element.__doc__ = ( - "Required ``<%s>`` child element." % self._nsptagname - ) + get_child_element.__doc__ = "Required ``<%s>`` child element." % self._nsptagname return get_child_element class OneOrMore(_BaseChildElement): - """ - Defines a repeating child element for MetaOxmlElement that must appear at - least once. - """ + """Defines a repeating child element for MetaOxmlElement that must appear at least + once.""" - def populate_class_members(self, element_cls, prop_name): - """ - Add the appropriate methods to *element_cls*. - """ + def populate_class_members(self, element_cls: MetaOxmlElement, prop_name: str) -> None: + """Add the appropriate methods to `element_cls`.""" super(OneOrMore, self).populate_class_members(element_cls, prop_name) self._add_list_getter() self._add_creator() @@ -577,14 +538,10 @@ def populate_class_members(self, element_cls, prop_name): class ZeroOrMore(_BaseChildElement): - """ - Defines an optional repeating child element for MetaOxmlElement. - """ + """Defines an optional repeating child element for MetaOxmlElement.""" - def populate_class_members(self, element_cls, prop_name): - """ - Add the appropriate methods to *element_cls*. - """ + def populate_class_members(self, element_cls: MetaOxmlElement, prop_name: str) -> None: + """Add the appropriate methods to `element_cls`.""" super(ZeroOrMore, self).populate_class_members(element_cls, prop_name) self._add_list_getter() self._add_creator() @@ -595,14 +552,10 @@ def populate_class_members(self, element_cls, prop_name): class ZeroOrOne(_BaseChildElement): - """ - Defines an optional child element for MetaOxmlElement. - """ + """Defines an optional child element for MetaOxmlElement.""" - def populate_class_members(self, element_cls, prop_name): - """ - Add the appropriate methods to *element_cls*. - """ + def populate_class_members(self, element_cls: MetaOxmlElement, prop_name: str) -> None: + """Add the appropriate methods to `element_cls`.""" super(ZeroOrOne, self).populate_class_members(element_cls, prop_name) self._add_getter() self._add_creator() @@ -612,12 +565,10 @@ def populate_class_members(self, element_cls, prop_name): self._add_remover() def _add_get_or_adder(self): - """ - Add a ``get_or_add_x()`` method to the element class for this - child element. - """ + """Add a ``get_or_add_x()`` method to the element class for this child + element.""" - def get_or_add_child(obj): + def get_or_add_child(obj: BaseOxmlElement): child = getattr(obj, self._prop_name) if child is None: add_method = getattr(obj, self._add_method_name) @@ -630,17 +581,12 @@ def get_or_add_child(obj): self._add_to_class(self._get_or_add_method_name, get_or_add_child) def _add_remover(self): - """ - Add a ``_remove_x()`` method to the element class for this child - element. - """ + """Add a ``_remove_x()`` method to the element class for this child element.""" - def _remove_child(obj): + def _remove_child(obj: BaseOxmlElement): obj.remove_all(self._nsptagname) - _remove_child.__doc__ = ( - "Remove all ``<%s>`` child elements." - ) % self._nsptagname + _remove_child.__doc__ = ("Remove all ``<%s>`` child elements.") % self._nsptagname self._add_to_class(self._remove_method_name, _remove_child) @lazyproperty @@ -649,60 +595,45 @@ def _get_or_add_method_name(self): class ZeroOrOneChoice(_BaseChildElement): - """ - Correspondes to an ``EG_*`` element group where at most one of its - members may appear as a child. - """ + """Correspondes to an ``EG_*`` element group where at most one of its members may + appear as a child.""" - def __init__(self, choices, successors=()): + def __init__(self, choices: Sequence[Choice], successors: tuple[str, ...] = ()): self._choices = choices self._successors = successors - def populate_class_members(self, element_cls, prop_name): - """ - Add the appropriate methods to *element_cls*. - """ + def populate_class_members(self, element_cls: MetaOxmlElement, prop_name: str) -> None: + """Add the appropriate methods to `element_cls`.""" super(ZeroOrOneChoice, self).populate_class_members(element_cls, prop_name) self._add_choice_getter() for choice in self._choices: - choice.populate_class_members( - element_cls, self._prop_name, self._successors - ) + choice.populate_class_members(element_cls, self._prop_name, self._successors) self._add_group_remover() def _add_choice_getter(self): - """ - Add a read-only ``{prop_name}`` property to the element class that - returns the present member of this group, or |None| if none are - present. - """ + """Add a read-only ``{prop_name}`` property to the element class that returns + the present member of this group, or |None| if none are present.""" property_ = property(self._choice_getter, None, None) # assign unconditionally to overwrite element name definition setattr(self._element_cls, self._prop_name, property_) def _add_group_remover(self): - """ - Add a ``_remove_eg_x()`` method to the element class for this choice - group. - """ + """Add a ``_remove_eg_x()`` method to the element class for this choice + group.""" - def _remove_choice_group(obj): + def _remove_choice_group(obj: BaseOxmlElement): for tagname in self._member_nsptagnames: obj.remove_all(tagname) - _remove_choice_group.__doc__ = ( - "Remove the current choice group child element if present." - ) + _remove_choice_group.__doc__ = "Remove the current choice group child element if present." self._add_to_class(self._remove_choice_group_method_name, _remove_choice_group) @property def _choice_getter(self): - """ - Return a function object suitable for the "get" side of the property - descriptor. - """ + """Return a function object suitable for the "get" side of the property + descriptor.""" - def get_group_member_element(obj): + def get_group_member_element(obj: BaseOxmlElement): return obj.first_child_found_in(*self._member_nsptagnames) get_group_member_element.__doc__ = ( @@ -713,10 +644,8 @@ def get_group_member_element(obj): @lazyproperty def _member_nsptagnames(self): - """ - Sequence of namespace-prefixed tagnames, one for each of the member - elements of this choice group. - """ + """Sequence of namespace-prefixed tagnames, one for each of the member elements + of this choice group.""" return [choice.nsptagname for choice in self._choices] @lazyproperty @@ -724,15 +653,12 @@ def _remove_choice_group_method_name(self): return "_remove_%s" % self._prop_name -class _OxmlElementBase(etree.ElementBase): - """ - Effective base class for all custom element classes, to add standardized - behavior to all classes in one place. Actual inheritance is from - BaseOxmlElement below, needed to manage Python 2-3 metaclass declaration - compatibility. - """ +# -- lxml typing isn't quite right here, just ignore this error on _Element -- +class BaseOxmlElement(etree.ElementBase, metaclass=MetaOxmlElement): + """Effective base class for all custom element classes. - __metaclass__ = MetaOxmlElement + Adds standardized behavior to all classes in one place. + """ def __repr__(self): return "<%s '<%s>' at 0x%0x>" % ( @@ -741,18 +667,15 @@ def __repr__(self): id(self), ) - def first_child_found_in(self, *tagnames): - """ - Return the first child found with tag in *tagnames*, or None if - not found. - """ + def first_child_found_in(self, *tagnames: str) -> _Element | None: + """First child with tag in `tagnames`, or None if not found.""" for tagname in tagnames: child = self.find(qn(tagname)) if child is not None: return child return None - def insert_element_before(self, elm, *tagnames): + def insert_element_before(self, elm: ElementBase, *tagnames: str): successor = self.first_child_found_in(*tagnames) if successor is not None: successor.addprevious(elm) @@ -760,35 +683,29 @@ def insert_element_before(self, elm, *tagnames): self.append(elm) return elm - def remove_all(self, *tagnames): - """ - Remove all child elements whose tagname (e.g. 'a:p') appears in - *tagnames*. - """ + def remove_all(self, *tagnames: str) -> None: + """Remove child elements with tagname (e.g. "a:p") in `tagnames`.""" for tagname in tagnames: matching = self.findall(qn(tagname)) for child in matching: self.remove(child) @property - def xml(self): - """ - Return XML string for this element, suitable for testing purposes. - Pretty printed for readability and without an XML declaration at the - top. + def xml(self) -> str: + """XML string for this element, suitable for testing purposes. + + Pretty printed for readability and without an XML declaration at the top. """ return serialize_for_reading(self) - def xpath(self, xpath_str, namespaces=nsmap): - """ - Override of ``lxml`` _Element.xpath() method to provide standard Open - XML namespace mapping (``nsmap``) in centralized location. + def xpath(self, xpath_str: str, namespaces: dict[str, str] | None = None) -> Any: # pyright: ignore[reportIncompatibleMethodOverride] + """Override of `lxml` _Element.xpath() method. + + Provides standard Open XML namespace mapping (`nsmap`) in centralized location + if `namespaces` is not provided. """ - return super(BaseOxmlElement, self).xpath(xpath_str, namespaces=namespaces) + return super().xpath(xpath_str, namespaces=namespaces or nsmap) @property - def _nsptag(self): + def _nsptag(self) -> str: return NamespacePrefixedTag.from_clark_name(self.tag) - - -BaseOxmlElement = MetaOxmlElement.create() diff --git a/docx/package.py b/src/docx/package.py similarity index 59% rename from docx/package.py rename to src/docx/package.py index 07f0718a..c38446d2 100644 --- a/docx/package.py +++ b/src/docx/package.py @@ -1,8 +1,8 @@ -# encoding: utf-8 +"""WordprocessingML Package class and related objects.""" -"""WordprocessingML Package class and related objects""" +from __future__ import annotations -from __future__ import absolute_import, division, print_function, unicode_literals +from typing import IO, TYPE_CHECKING, cast from docx.image.image import Image from docx.opc.constants import RELATIONSHIP_TYPE as RT @@ -11,9 +11,12 @@ from docx.parts.image import ImagePart from docx.shared import lazyproperty +if TYPE_CHECKING: + from docx.opc.customprops import CustomProperties + class Package(OpcPackage): - """Customizations specific to a WordprocessingML package""" + """Customizations specific to a WordprocessingML package.""" def after_unmarshal(self): """Called by loading code after all parts and relationships have been loaded. @@ -22,8 +25,14 @@ def after_unmarshal(self): """ self._gather_image_parts() - def get_or_add_image_part(self, image_descriptor): - """Return |ImagePart| containing image specified by *image_descriptor*. + @property + def custom_properties(self) -> CustomProperties: + """|CustomProperties| object providing read/write access to the custom + properties for this document.""" + return super().custom_properties + + def get_or_add_image_part(self, image_descriptor: str | IO[bytes]) -> ImagePart: + """Return |ImagePart| containing image specified by `image_descriptor`. The image-part is newly created if a matching one is not already present in the collection. @@ -31,7 +40,7 @@ def get_or_add_image_part(self, image_descriptor): return self.image_parts.get_or_add_image_part(image_descriptor) @lazyproperty - def image_parts(self): + def image_parts(self) -> ImageParts: """|ImageParts| collection object for this package.""" return ImageParts() @@ -44,16 +53,16 @@ def _gather_image_parts(self): continue if rel.target_part in self.image_parts: continue - self.image_parts.append(rel.target_part) + self.image_parts.append(cast("ImagePart", rel.target_part)) -class ImageParts(object): - """Collection of |ImagePart| objects corresponding to images in the package""" +class ImageParts: + """Collection of |ImagePart| objects corresponding to images in the package.""" def __init__(self): - self._image_parts = [] + self._image_parts: list[ImagePart] = [] - def __contains__(self, item): + def __contains__(self, item: object): return self._image_parts.__contains__(item) def __iter__(self): @@ -62,11 +71,11 @@ def __iter__(self): def __len__(self): return self._image_parts.__len__() - def append(self, item): + def append(self, item: ImagePart): self._image_parts.append(item) - def get_or_add_image_part(self, image_descriptor): - """Return |ImagePart| object containing image identified by *image_descriptor*. + def get_or_add_image_part(self, image_descriptor: str | IO[bytes]) -> ImagePart: + """Return |ImagePart| object containing image identified by `image_descriptor`. The image-part is newly created if a matching one is not present in the collection. @@ -77,35 +86,30 @@ def get_or_add_image_part(self, image_descriptor): return matching_image_part return self._add_image_part(image) - def _add_image_part(self, image): - """ - Return an |ImagePart| instance newly created from image and appended - to the collection. - """ + def _add_image_part(self, image: Image): + """Return |ImagePart| instance newly created from `image` and appended to the collection.""" partname = self._next_image_partname(image.ext) image_part = ImagePart.from_image(image, partname) self.append(image_part) return image_part - def _get_by_sha1(self, sha1): - """ - Return the image part in this collection having a SHA1 hash matching - *sha1*, or |None| if not found. - """ + def _get_by_sha1(self, sha1: str) -> ImagePart | None: + """Return the image part in this collection having a SHA1 hash matching `sha1`, + or |None| if not found.""" for image_part in self._image_parts: if image_part.sha1 == sha1: return image_part return None - def _next_image_partname(self, ext): - """ - The next available image partname, starting from - ``/word/media/image1.{ext}`` where unused numbers are reused. The - partname is unique by number, without regard to the extension. *ext* - does not include the leading period. + def _next_image_partname(self, ext: str) -> PackURI: + """The next available image partname, starting from ``/word/media/image1.{ext}`` + where unused numbers are reused. + + The partname is unique by number, without regard to the extension. `ext` does + not include the leading period. """ - def image_partname(n): + def image_partname(n: int) -> PackURI: return PackURI("/word/media/image%d.%s" % (n, ext)) used_numbers = [image_part.partname.idx for image_part in self] diff --git a/docx/text/__init__.py b/src/docx/parts/__init__.py similarity index 100% rename from docx/text/__init__.py rename to src/docx/parts/__init__.py diff --git a/src/docx/parts/comments.py b/src/docx/parts/comments.py new file mode 100644 index 00000000..0e4cc743 --- /dev/null +++ b/src/docx/parts/comments.py @@ -0,0 +1,51 @@ +"""Contains comments added to the document.""" + +from __future__ import annotations + +import os +from typing import TYPE_CHECKING, cast + +from typing_extensions import Self + +from docx.comments import Comments +from docx.opc.constants import CONTENT_TYPE as CT +from docx.opc.packuri import PackURI +from docx.oxml.comments import CT_Comments +from docx.oxml.parser import parse_xml +from docx.package import Package +from docx.parts.story import StoryPart + +if TYPE_CHECKING: + from docx.oxml.comments import CT_Comments + from docx.package import Package + + +class CommentsPart(StoryPart): + """Container part for comments added to the document.""" + + def __init__( + self, partname: PackURI, content_type: str, element: CT_Comments, package: Package + ): + super().__init__(partname, content_type, element, package) + self._comments = element + + @property + def comments(self) -> Comments: + """A |Comments| proxy object for the `w:comments` root element of this part.""" + return Comments(self._comments, self) + + @classmethod + def default(cls, package: Package) -> Self: + """A newly created comments part, containing a default empty `w:comments` element.""" + partname = PackURI("/word/comments.xml") + content_type = CT.WML_COMMENTS + element = cast("CT_Comments", parse_xml(cls._default_comments_xml())) + return cls(partname, content_type, element, package) + + @classmethod + def _default_comments_xml(cls) -> bytes: + """A byte-string containing XML for a default comments part.""" + path = os.path.join(os.path.split(__file__)[0], "..", "templates", "default-comments.xml") + with open(path, "rb") as f: + xml_bytes = f.read() + return xml_bytes diff --git a/docx/parts/customxml.py b/src/docx/parts/customxml.py similarity index 100% rename from docx/parts/customxml.py rename to src/docx/parts/customxml.py diff --git a/src/docx/parts/document.py b/src/docx/parts/document.py new file mode 100644 index 00000000..59124bd9 --- /dev/null +++ b/src/docx/parts/document.py @@ -0,0 +1,193 @@ +"""|DocumentPart| and closely related objects.""" + +from __future__ import annotations + +from typing import IO, TYPE_CHECKING, cast + +from docx.document import Document +from docx.opc.constants import CONTENT_TYPE as CT +from docx.opc.constants import RELATIONSHIP_TYPE as RT +from docx.parts.comments import CommentsPart +from docx.parts.customxml import CustomXmlPart +from docx.parts.hdrftr import FooterPart, HeaderPart +from docx.parts.numbering import NumberingPart +from docx.parts.settings import SettingsPart +from docx.parts.story import StoryPart +from docx.parts.styles import StylesPart +from docx.shape import InlineShapes +from docx.shared import lazyproperty + +if TYPE_CHECKING: + from docx.comments import Comments + from docx.enum.style import WD_STYLE_TYPE + from docx.opc.coreprops import CoreProperties + from docx.opc.customprops import CustomProperties + from docx.settings import Settings + from docx.styles.style import BaseStyle + + +class DocumentPart(StoryPart): + """Main document part of a WordprocessingML (WML) package, aka a .docx file. + + Acts as broker to other parts such as image, core properties, and style parts. It + also acts as a convenient delegate when a mid-document object needs a service + involving a remote ancestor. The `Parented.part` property inherited by many content + objects provides access to this part object for that purpose. + """ + + def add_custom_xml_part( + self, xml: str, file_name: str = "item1", content_type: str = CT.XML + ) -> CustomXmlPart: + """Add a file in /customXml/*file_name*.xml with default content *xml*.""" + part = CustomXmlPart.default(file_name, content_type, xml, self.package) + return self.rels.get_or_add(RT.CUSTOM_XML, part).target_part + + def add_footer_part(self): + """Return (footer_part, rId) pair for newly-created footer part.""" + footer_part = FooterPart.new(self.package) + rId = self.relate_to(footer_part, RT.FOOTER) + return footer_part, rId + + def add_header_part(self): + """Return (header_part, rId) pair for newly-created header part.""" + header_part = HeaderPart.new(self.package) + rId = self.relate_to(header_part, RT.HEADER) + return header_part, rId + + @property + def comments(self) -> Comments: + """|Comments| object providing access to the comments added to this document.""" + return self._comments_part.comments + + @property + def core_properties(self) -> CoreProperties: + """A |CoreProperties| object providing read/write access to the core properties + of this document.""" + return self.package.core_properties + + @property + def custom_properties(self) -> CustomProperties: + """A |CustomProperties| object providing read/write access to the custom + properties of this document.""" + return self.package.custom_properties + + @property + def custom_xml_parts(self) -> list[CustomXmlPart]: + """A list of |CustomXmlPart| objects for this document.""" + try: + return self.rels.parts_with_reltype(RT.CUSTOM_XML) + except KeyError: + return [] + + @property + def document(self): + """A |Document| object providing access to the content of this document.""" + return Document(self._element, self) + + def drop_header_part(self, rId: str) -> None: + """Remove related header part identified by `rId`.""" + self.drop_rel(rId) + + def footer_part(self, rId: str): + """Return |FooterPart| related by `rId`.""" + return self.related_parts[rId] + + def get_style(self, style_id: str | None, style_type: WD_STYLE_TYPE) -> BaseStyle: + """Return the style in this document matching `style_id`. + + Returns the default style for `style_type` if `style_id` is |None| or does not + match a defined style of `style_type`. + """ + return self.styles.get_by_id(style_id, style_type) + + def get_style_id(self, style_or_name, style_type): + """Return the style_id (|str|) of the style of `style_type` matching + `style_or_name`. + + Returns |None| if the style resolves to the default style for `style_type` or if + `style_or_name` is itself |None|. Raises if `style_or_name` is a style of the + wrong type or names a style not present in the document. + """ + return self.styles.get_style_id(style_or_name, style_type) + + def header_part(self, rId: str): + """Return |HeaderPart| related by `rId`.""" + return self.related_parts[rId] + + @lazyproperty + def inline_shapes(self): + """The |InlineShapes| instance containing the inline shapes in the document.""" + return InlineShapes(self._element.body, self) + + @lazyproperty + def numbering_part(self) -> NumberingPart: + """A |NumberingPart| object providing access to the numbering definitions for this document. + + Creates an empty numbering part if one is not present. + """ + try: + return cast(NumberingPart, self.part_related_by(RT.NUMBERING)) + except KeyError: + numbering_part = NumberingPart.default(self.package) + self.relate_to(numbering_part, RT.NUMBERING) + return numbering_part + + def save(self, path_or_stream: str | IO[bytes]): + """Save this document to `path_or_stream`, which can be either a path to a + filesystem location (a string) or a file-like object.""" + self.package.save(path_or_stream) + + @property + def settings(self) -> Settings: + """A |Settings| object providing access to the settings in the settings part of + this document.""" + return self._settings_part.settings + + @property + def styles(self): + """A |Styles| object providing access to the styles in the styles part of this + document.""" + return self._styles_part.styles + + @property + def _comments_part(self) -> CommentsPart: + """A |CommentsPart| object providing access to the comments added to this document. + + Creates a default comments part if one is not present. + """ + try: + return cast(CommentsPart, self.part_related_by(RT.COMMENTS)) + except KeyError: + assert self.package is not None + comments_part = CommentsPart.default(self.package) + self.relate_to(comments_part, RT.COMMENTS) + return comments_part + + @property + def _settings_part(self) -> SettingsPart: + """A |SettingsPart| object providing access to the document-level settings for + this document. + + Creates a default settings part if one is not present. + """ + try: + return cast(SettingsPart, self.part_related_by(RT.SETTINGS)) + except KeyError: + settings_part = SettingsPart.default(self.package) + self.relate_to(settings_part, RT.SETTINGS) + return settings_part + + @property + def _styles_part(self) -> StylesPart: + """Instance of |StylesPart| for this document. + + Creates an empty styles part if one is not present. + """ + try: + return cast(StylesPart, self.part_related_by(RT.STYLES)) + except KeyError: + package = self.package + assert package is not None + styles_part = StylesPart.default(package) + self.relate_to(styles_part, RT.STYLES) + return styles_part diff --git a/docx/parts/hdrftr.py b/src/docx/parts/hdrftr.py similarity index 66% rename from docx/parts/hdrftr.py rename to src/docx/parts/hdrftr.py index 22ea874a..35113801 100644 --- a/docx/parts/hdrftr.py +++ b/src/docx/parts/hdrftr.py @@ -1,21 +1,23 @@ -# encoding: utf-8 +"""Header and footer part objects.""" -"""Header and footer part objects""" - -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import annotations import os +from typing import TYPE_CHECKING from docx.opc.constants import CONTENT_TYPE as CT -from docx.oxml import parse_xml -from docx.parts.story import BaseStoryPart +from docx.oxml.parser import parse_xml +from docx.parts.story import StoryPart + +if TYPE_CHECKING: + from docx.package import Package -class FooterPart(BaseStoryPart): +class FooterPart(StoryPart): """Definition of a section footer.""" @classmethod - def new(cls, package): + def new(cls, package: Package): """Return newly created footer part.""" partname = package.next_partname("/word/footer%d.xml") content_type = CT.WML_FOOTER @@ -25,19 +27,17 @@ def new(cls, package): @classmethod def _default_footer_xml(cls): """Return bytes containing XML for a default footer part.""" - path = os.path.join( - os.path.split(__file__)[0], "..", "templates", "default-footer.xml" - ) + path = os.path.join(os.path.split(__file__)[0], "..", "templates", "default-footer.xml") with open(path, "rb") as f: xml_bytes = f.read() return xml_bytes -class HeaderPart(BaseStoryPart): +class HeaderPart(StoryPart): """Definition of a section header.""" @classmethod - def new(cls, package): + def new(cls, package: Package): """Return newly created header part.""" partname = package.next_partname("/word/header%d.xml") content_type = CT.WML_HEADER @@ -47,9 +47,7 @@ def new(cls, package): @classmethod def _default_header_xml(cls): """Return bytes containing XML for a default header part.""" - path = os.path.join( - os.path.split(__file__)[0], "..", "templates", "default-header.xml" - ) + path = os.path.join(os.path.split(__file__)[0], "..", "templates", "default-header.xml") with open(path, "rb") as f: xml_bytes = f.read() return xml_bytes diff --git a/src/docx/parts/image.py b/src/docx/parts/image.py new file mode 100644 index 00000000..5aec0707 --- /dev/null +++ b/src/docx/parts/image.py @@ -0,0 +1,80 @@ +"""The proxy class for an image part, and related objects.""" + +from __future__ import annotations + +import hashlib +from typing import TYPE_CHECKING + +from docx.image.image import Image +from docx.opc.part import Part +from docx.shared import Emu, Inches + +if TYPE_CHECKING: + from docx.opc.package import OpcPackage + from docx.opc.packuri import PackURI + + +class ImagePart(Part): + """An image part. + + Corresponds to the target part of a relationship with type RELATIONSHIP_TYPE.IMAGE. + """ + + def __init__( + self, partname: PackURI, content_type: str, blob: bytes, image: Image | None = None + ): + super(ImagePart, self).__init__(partname, content_type, blob) + self._image = image + + @property + def default_cx(self): + """Native width of this image, calculated from its width in pixels and + horizontal dots per inch (dpi).""" + px_width = self.image.px_width + horz_dpi = self.image.horz_dpi + width_in_inches = px_width / horz_dpi + return Inches(width_in_inches) + + @property + def default_cy(self): + """Native height of this image, calculated from its height in pixels and + vertical dots per inch (dpi).""" + px_height = self.image.px_height + horz_dpi = self.image.horz_dpi + height_in_emu = int(round(914400 * px_height / horz_dpi)) + return Emu(height_in_emu) + + @property + def filename(self): + """Filename from which this image part was originally created. + + A generic name, e.g. 'image.png', is substituted if no name is available, for + example when the image was loaded from an unnamed stream. In that case a default + extension is applied based on the detected MIME type of the image. + """ + if self._image is not None: + return self._image.filename + return "image.%s" % self.partname.ext + + @classmethod + def from_image(cls, image: Image, partname: PackURI): + """Return an |ImagePart| instance newly created from `image` and assigned + `partname`.""" + return ImagePart(partname, image.content_type, image.blob, image) + + @property + def image(self) -> Image: + if self._image is None: + self._image = Image.from_blob(self.blob) + return self._image + + @classmethod + def load(cls, partname: PackURI, content_type: str, blob: bytes, package: OpcPackage): + """Called by ``docx.opc.package.PartFactory`` to load an image part from a + package being opened by ``Document(...)`` call.""" + return cls(partname, content_type, blob) + + @property + def sha1(self): + """SHA1 hash digest of the blob of this image part.""" + return hashlib.sha1(self.blob).hexdigest() diff --git a/docx/parts/numbering.py b/src/docx/parts/numbering.py similarity index 55% rename from docx/parts/numbering.py rename to src/docx/parts/numbering.py index 890d94d5..9ec50155 100644 --- a/docx/parts/numbering.py +++ b/src/docx/parts/numbering.py @@ -1,9 +1,4 @@ -# encoding: utf-8 - -""" -|NumberingPart| and closely related objects -""" -from __future__ import absolute_import, division, print_function, unicode_literals +"""|NumberingPart| and closely related objects.""" import os @@ -15,17 +10,13 @@ class NumberingPart(XmlPart): - """ - Proxy for the numbering.xml part containing numbering definitions for - a document or glossary. - """ + """Proxy for the numbering.xml part containing numbering definitions for a document + or glossary.""" @classmethod def default(cls, package): - """ - Return newly created empty numbering part, containing only the root - ```` element. - """ + """Return newly created empty numbering part, containing only the root ```` + element.""" partname = PackURI("/word/numbering.xml") content_type = CT.WML_NUMBERING element = parse_xml(cls._default_numbering_xml()) @@ -33,9 +24,7 @@ def default(cls, package): @classmethod def _default_numbering_xml(cls): - """ - Return a bytestream containing XML for a default numbering part. - """ + """Return a bytestream containing XML for a default numbering part.""" path = os.path.join( os.path.split(__file__)[0], "..", "templates", "default-numbering.xml" ) @@ -45,18 +34,14 @@ def _default_numbering_xml(cls): @lazyproperty def numbering_definitions(self): - """ - The |_NumberingDefinitions| instance containing the numbering - definitions ( element proxies) for this numbering part. - """ + """The |_NumberingDefinitions| instance containing the numbering definitions + ( element proxies) for this numbering part.""" return _NumberingDefinitions(self._element) -class _NumberingDefinitions(object): - """ - Collection of |_NumberingDefinition| instances corresponding to the - ```` elements in a numbering part. - """ +class _NumberingDefinitions: + """Collection of |_NumberingDefinition| instances corresponding to the ```` + elements in a numbering part.""" def __init__(self, numbering_elm): super(_NumberingDefinitions, self).__init__() diff --git a/src/docx/parts/settings.py b/src/docx/parts/settings.py new file mode 100644 index 00000000..7fe371f0 --- /dev/null +++ b/src/docx/parts/settings.py @@ -0,0 +1,50 @@ +"""|SettingsPart| and closely related objects.""" + +from __future__ import annotations + +import os +from typing import TYPE_CHECKING, cast + +from docx.opc.constants import CONTENT_TYPE as CT +from docx.opc.packuri import PackURI +from docx.opc.part import XmlPart +from docx.oxml.parser import parse_xml +from docx.settings import Settings + +if TYPE_CHECKING: + from docx.oxml.settings import CT_Settings + from docx.package import Package + + +class SettingsPart(XmlPart): + """Document-level settings part of a WordprocessingML (WML) package.""" + + def __init__( + self, partname: PackURI, content_type: str, element: CT_Settings, package: Package + ): + super().__init__(partname, content_type, element, package) + self._settings = element + + @classmethod + def default(cls, package: Package): + """Return a newly created settings part, containing a default `w:settings` element tree.""" + partname = PackURI("/word/settings.xml") + content_type = CT.WML_SETTINGS + element = cast("CT_Settings", parse_xml(cls._default_settings_xml())) + return cls(partname, content_type, element, package) + + @property + def settings(self) -> Settings: + """A |Settings| proxy object for the `w:settings` element in this part. + + Contains the document-level settings for this document. + """ + return Settings(self._settings) + + @classmethod + def _default_settings_xml(cls): + """Return a bytestream containing XML for a default settings part.""" + path = os.path.join(os.path.split(__file__)[0], "..", "templates", "default-settings.xml") + with open(path, "rb") as f: + xml_bytes = f.read() + return xml_bytes diff --git a/src/docx/parts/story.py b/src/docx/parts/story.py new file mode 100644 index 00000000..6f521ef0 --- /dev/null +++ b/src/docx/parts/story.py @@ -0,0 +1,113 @@ +"""|StoryPart| and related objects.""" + +from __future__ import annotations + +from typing import IO, TYPE_CHECKING, Tuple, cast + +from docx.opc.constants import RELATIONSHIP_TYPE as RT +from docx.opc.part import XmlPart +from docx.oxml.shape import CT_Anchor, CT_Inline +from docx.shared import Length, lazyproperty + +if TYPE_CHECKING: + from docx.enum.style import WD_STYLE_TYPE + from docx.image.image import Image + from docx.parts.document import DocumentPart + from docx.styles.style import BaseStyle + + +class StoryPart(XmlPart): + """Base class for story parts. + + A story part is one that can contain textual content, such as the document-part and + header or footer parts. These all share content behaviors like `.paragraphs`, + `.add_paragraph()`, `.add_table()` etc. + """ + + def get_or_add_image(self, image_descriptor: str | IO[bytes]) -> Tuple[str, Image]: + """Return (rId, image) pair for image identified by `image_descriptor`. + + `rId` is the str key (often like "rId7") for the relationship between this story + part and the image part, reused if already present, newly created if not. + `image` is an |Image| instance providing access to the properties of the image, + such as dimensions and image type. + """ + package = self._package + assert package is not None + image_part = package.get_or_add_image_part(image_descriptor) + rId = self.relate_to(image_part, RT.IMAGE) + return rId, image_part.image + + def get_style(self, style_id: str | None, style_type: WD_STYLE_TYPE) -> BaseStyle: + """Return the style in this document matching `style_id`. + + Returns the default style for `style_type` if `style_id` is |None| or does not + match a defined style of `style_type`. + """ + return self._document_part.get_style(style_id, style_type) + + def get_style_id( + self, style_or_name: BaseStyle | str | None, style_type: WD_STYLE_TYPE + ) -> str | None: + """Return str style_id for `style_or_name` of `style_type`. + + Returns |None| if the style resolves to the default style for `style_type` or if + `style_or_name` is itself |None|. Raises if `style_or_name` is a style of the + wrong type or names a style not present in the document. + """ + return self._document_part.get_style_id(style_or_name, style_type) + + def new_pic_inline( + self, + image_descriptor: str | IO[bytes], + width: int | Length | None = None, + height: int | Length | None = None, + ) -> CT_Inline: + """Return a newly-created `w:inline` element. + + The element contains the image specified by `image_descriptor` and is scaled + based on the values of `width` and `height`. + """ + rId, image = self.get_or_add_image(image_descriptor) + cx, cy = image.scaled_dimensions(width, height) + shape_id, filename = self.next_id, image.filename + return CT_Inline.new_pic_inline(shape_id, rId, filename, cx, cy) + + def new_pic_anchor( + self, + image_descriptor: str | IO[bytes], + width: int | Length | None = None, + height: int | Length | None = None, + pos_x: int | Length = 0, + pos_y: int | Length = 0, + ): + """Return a newly-created `w:anchor` element. + + The element contains the image specified by `image_descriptor` and is scaled + based on the values of `width` and `height`. + """ + rId, image = self.get_or_add_image(image_descriptor) + cx, cy = image.scaled_dimensions(width, height) + shape_id, filename = self.next_id, image.filename + return CT_Anchor.new_pic_anchor(shape_id, rId, filename, cx, cy, pos_x, pos_y) + + @property + def next_id(self) -> int: + """Next available positive integer id value in this story XML document. + + The value is determined by incrementing the maximum existing id value. Gaps in + the existing id sequence are not filled. The id attribute value is unique in the + document, without regard to the element type it appears on. + """ + id_str_lst = self._element.xpath("//@id") + used_ids = [int(id_str) for id_str in id_str_lst if id_str.isdigit()] + if not used_ids: + return 1 + return max(used_ids) + 1 + + @lazyproperty + def _document_part(self) -> DocumentPart: + """|DocumentPart| object for this package.""" + package = self.package + assert package is not None + return cast("DocumentPart", package.main_document_part) diff --git a/src/docx/parts/styles.py b/src/docx/parts/styles.py new file mode 100644 index 00000000..6e065bee --- /dev/null +++ b/src/docx/parts/styles.py @@ -0,0 +1,42 @@ +"""Provides StylesPart and related objects.""" + +from __future__ import annotations + +import os +from typing import TYPE_CHECKING + +from docx.opc.constants import CONTENT_TYPE as CT +from docx.opc.packuri import PackURI +from docx.opc.part import XmlPart +from docx.oxml.parser import parse_xml +from docx.styles.styles import Styles + +if TYPE_CHECKING: + from docx.opc.package import OpcPackage + + +class StylesPart(XmlPart): + """Proxy for the styles.xml part containing style definitions for a document or + glossary.""" + + @classmethod + def default(cls, package: OpcPackage) -> StylesPart: + """Return a newly created styles part, containing a default set of elements.""" + partname = PackURI("/word/styles.xml") + content_type = CT.WML_STYLES + element = parse_xml(cls._default_styles_xml()) + return cls(partname, content_type, element, package) + + @property + def styles(self): + """The |_Styles| instance containing the styles ( element proxies) for + this styles part.""" + return Styles(self.element) + + @classmethod + def _default_styles_xml(cls): + """Return a bytestream containing XML for a default styles part.""" + path = os.path.join(os.path.split(__file__)[0], "..", "templates", "default-styles.xml") + with open(path, "rb") as f: + xml_bytes = f.read() + return xml_bytes diff --git a/src/docx/py.typed b/src/docx/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/docx/section.py b/src/docx/section.py similarity index 65% rename from docx/section.py rename to src/docx/section.py index 32ceec7d..982a1437 100644 --- a/docx/section.py +++ b/src/docx/section.py @@ -1,67 +1,52 @@ -# encoding: utf-8 +"""The |Section| object and related proxy classes.""" -"""The |Section| object and related proxy classes""" +from __future__ import annotations -from __future__ import absolute_import, division, print_function, unicode_literals +from typing import TYPE_CHECKING, Iterator, List, Sequence, overload from docx.blkcntnr import BlockItemContainer -from docx.compat import Sequence from docx.enum.section import WD_HEADER_FOOTER +from docx.oxml.text.paragraph import CT_P +from docx.parts.hdrftr import FooterPart, HeaderPart from docx.shared import lazyproperty +from docx.table import Table +from docx.text.paragraph import Paragraph - -class Sections(Sequence): - """Sequence of |Section| objects corresponding to the sections in the document. - - Supports ``len()``, iteration, and indexed access. - """ - - def __init__(self, document_elm, document_part): - super(Sections, self).__init__() - self._document_elm = document_elm - self._document_part = document_part - - def __getitem__(self, key): - if isinstance(key, slice): - return [ - Section(sectPr, self._document_part) - for sectPr in self._document_elm.sectPr_lst[key] - ] - return Section(self._document_elm.sectPr_lst[key], self._document_part) - - def __iter__(self): - for sectPr in self._document_elm.sectPr_lst: - yield Section(sectPr, self._document_part) - - def __len__(self): - return len(self._document_elm.sectPr_lst) +if TYPE_CHECKING: + from docx.enum.section import WD_ORIENTATION, WD_SECTION_START + from docx.oxml.document import CT_Document + from docx.oxml.section import CT_SectPr + from docx.parts.document import DocumentPart + from docx.parts.story import StoryPart + from docx.shared import Length -class Section(object): +class Section: """Document section, providing access to section and page setup settings. Also provides access to headers and footers. """ - def __init__(self, sectPr, document_part): + def __init__(self, sectPr: CT_SectPr, document_part: DocumentPart): super(Section, self).__init__() self._sectPr = sectPr self._document_part = document_part @property - def bottom_margin(self): - """ - |Length| object representing the bottom margin for all pages in this - section in English Metric Units. + def bottom_margin(self) -> Length | None: + """Read/write. Bottom margin for pages in this section, in EMU. + + `None` when no bottom margin has been specified. Assigning |None| removes any + bottom-margin setting. """ return self._sectPr.bottom_margin @bottom_margin.setter - def bottom_margin(self, value): + def bottom_margin(self, value: int | Length | None): self._sectPr.bottom_margin = value @property - def different_first_page_header_footer(self): + def different_first_page_header_footer(self) -> bool: """True if this section displays a distinct first-page header and footer. Read/write. The definition of the first-page header and footer are accessed @@ -70,11 +55,11 @@ def different_first_page_header_footer(self): return self._sectPr.titlePg_val @different_first_page_header_footer.setter - def different_first_page_header_footer(self, value): + def different_first_page_header_footer(self, value: bool): self._sectPr.titlePg_val = value @property - def even_page_footer(self): + def even_page_footer(self) -> _Footer: """|_Footer| object defining footer content for even pages. The content of this footer definition is ignored unless the document setting @@ -83,7 +68,7 @@ def even_page_footer(self): return _Footer(self._sectPr, self._document_part, WD_HEADER_FOOTER.EVEN_PAGE) @property - def even_page_header(self): + def even_page_header(self) -> _Header: """|_Header| object defining header content for even pages. The content of this header definition is ignored unless the document setting @@ -92,7 +77,7 @@ def even_page_header(self): return _Header(self._sectPr, self._document_part, WD_HEADER_FOOTER.EVEN_PAGE) @property - def first_page_footer(self): + def first_page_footer(self) -> _Footer: """|_Footer| object defining footer content for the first page of this section. The content of this footer definition is ignored unless the property @@ -101,7 +86,7 @@ def first_page_footer(self): return _Footer(self._sectPr, self._document_part, WD_HEADER_FOOTER.FIRST_PAGE) @property - def first_page_header(self): + def first_page_header(self) -> _Header: """|_Header| object defining header content for the first page of this section. The content of this header definition is ignored unless the property @@ -110,7 +95,7 @@ def first_page_header(self): return _Header(self._sectPr, self._document_part, WD_HEADER_FOOTER.FIRST_PAGE) @lazyproperty - def footer(self): + def footer(self) -> _Footer: """|_Footer| object representing default page footer for this section. The default footer is used for odd-numbered pages when separate odd/even footers @@ -119,34 +104,36 @@ def footer(self): return _Footer(self._sectPr, self._document_part, WD_HEADER_FOOTER.PRIMARY) @property - def footer_distance(self): - """ - |Length| object representing the distance from the bottom edge of the - page to the bottom edge of the footer. |None| if no setting is present - in the XML. + def footer_distance(self) -> Length | None: + """Distance from bottom edge of page to bottom edge of the footer. + + Read/write. |None| if no setting is present in the XML. """ return self._sectPr.footer @footer_distance.setter - def footer_distance(self, value): + def footer_distance(self, value: int | Length | None): self._sectPr.footer = value @property - def gutter(self): - """ - |Length| object representing the page gutter size in English Metric - Units for all pages in this section. The page gutter is extra spacing - added to the *inner* margin to ensure even margins after page - binding. + def gutter(self) -> Length | None: + """|Length| object representing page gutter size in English Metric Units. + + Read/write. The page gutter is extra spacing added to the `inner` margin to + ensure even margins after page binding. Generally only used in book-bound + documents with double-sided and facing pages. + + This setting applies to all pages in this section. + """ return self._sectPr.gutter @gutter.setter - def gutter(self, value): + def gutter(self, value: int | Length | None): self._sectPr.gutter = value @lazyproperty - def header(self): + def header(self) -> _Header: """|_Header| object representing default page header for this section. The default header is used for odd-numbered pages when separate odd/even headers @@ -155,120 +142,165 @@ def header(self): return _Header(self._sectPr, self._document_part, WD_HEADER_FOOTER.PRIMARY) @property - def header_distance(self): - """ - |Length| object representing the distance from the top edge of the - page to the top edge of the header. |None| if no setting is present - in the XML. + def header_distance(self) -> Length | None: + """Distance from top edge of page to top edge of header. + + Read/write. |None| if no setting is present in the XML. Assigning |None| causes + default value to be used. """ return self._sectPr.header @header_distance.setter - def header_distance(self, value): + def header_distance(self, value: int | Length | None): self._sectPr.header = value - @property - def left_margin(self): - """ - |Length| object representing the left margin for all pages in this - section in English Metric Units. + def iter_inner_content(self) -> Iterator[Paragraph | Table]: + """Generate each Paragraph or Table object in this `section`. + + Items appear in document order. """ + for element in self._sectPr.iter_inner_content(): + yield (Paragraph(element, self) if isinstance(element, CT_P) else Table(element, self)) + + @property + def left_margin(self) -> Length | None: + """|Length| object representing the left margin for all pages in this section in + English Metric Units.""" return self._sectPr.left_margin @left_margin.setter - def left_margin(self, value): + def left_margin(self, value: int | Length | None): self._sectPr.left_margin = value @property - def orientation(self): - """ - Member of the :ref:`WdOrientation` enumeration specifying the page - orientation for this section, one of ``WD_ORIENT.PORTRAIT`` or - ``WD_ORIENT.LANDSCAPE``. + def orientation(self) -> WD_ORIENTATION: + """:ref:`WdOrientation` member specifying page orientation for this section. + + One of ``WD_ORIENT.PORTRAIT`` or ``WD_ORIENT.LANDSCAPE``. """ return self._sectPr.orientation @orientation.setter - def orientation(self, value): + def orientation(self, value: WD_ORIENTATION | None): self._sectPr.orientation = value @property - def page_height(self): - """ - Total page height used for this section, inclusive of all edge spacing - values such as margins. Page orientation is taken into account, so - for example, its expected value would be ``Inches(8.5)`` for - letter-sized paper when orientation is landscape. + def page_height(self) -> Length | None: + """Total page height used for this section. + + This value is inclusive of all edge spacing values such as margins. + + Page orientation is taken into account, so for example, its expected value + would be ``Inches(8.5)`` for letter-sized paper when orientation is landscape. """ return self._sectPr.page_height @page_height.setter - def page_height(self, value): + def page_height(self, value: Length | None): self._sectPr.page_height = value @property - def page_width(self): - """ - Total page width used for this section, inclusive of all edge spacing - values such as margins. Page orientation is taken into account, so - for example, its expected value would be ``Inches(11)`` for - letter-sized paper when orientation is landscape. + def page_width(self) -> Length | None: + """Total page width used for this section. + + This value is like "paper size" and includes all edge spacing values such as + margins. + + Page orientation is taken into account, so for example, its expected value + would be ``Inches(11)`` for letter-sized paper when orientation is landscape. """ return self._sectPr.page_width @page_width.setter - def page_width(self, value): + def page_width(self, value: Length | None): self._sectPr.page_width = value @property - def right_margin(self): - """ - |Length| object representing the right margin for all pages in this - section in English Metric Units. - """ + def part(self) -> StoryPart: + return self._document_part + + @property + def right_margin(self) -> Length | None: + """|Length| object representing the right margin for all pages in this section + in English Metric Units.""" return self._sectPr.right_margin @right_margin.setter - def right_margin(self, value): + def right_margin(self, value: Length | None): self._sectPr.right_margin = value @property - def start_type(self): - """ - The member of the :ref:`WdSectionStart` enumeration corresponding to - the initial break behavior of this section, e.g. - ``WD_SECTION.ODD_PAGE`` if the section should begin on the next odd - page. + def start_type(self) -> WD_SECTION_START: + """Type of page-break (if any) inserted at the start of this section. + + For exmple, ``WD_SECTION_START.ODD_PAGE`` if the section should begin on the + next odd page, possibly inserting two page-breaks instead of one. """ return self._sectPr.start_type @start_type.setter - def start_type(self, value): + def start_type(self, value: WD_SECTION_START | None): self._sectPr.start_type = value @property - def top_margin(self): - """ - |Length| object representing the top margin for all pages in this - section in English Metric Units. - """ + def top_margin(self) -> Length | None: + """|Length| object representing the top margin for all pages in this section in + English Metric Units.""" return self._sectPr.top_margin @top_margin.setter - def top_margin(self, value): + def top_margin(self, value: Length | None): self._sectPr.top_margin = value -class _BaseHeaderFooter(BlockItemContainer): - """Base class for header and footer classes""" +class Sections(Sequence[Section]): + """Sequence of |Section| objects corresponding to the sections in the document. + + Supports ``len()``, iteration, and indexed access. + """ + + def __init__(self, document_elm: CT_Document, document_part: DocumentPart): + super(Sections, self).__init__() + self._document_elm = document_elm + self._document_part = document_part + + @overload + def __getitem__(self, key: int) -> Section: ... - def __init__(self, sectPr, document_part, header_footer_index): + @overload + def __getitem__(self, key: slice) -> List[Section]: ... + + def __getitem__(self, key: int | slice) -> Section | List[Section]: + if isinstance(key, slice): + return [ + Section(sectPr, self._document_part) + for sectPr in self._document_elm.sectPr_lst[key] + ] + return Section(self._document_elm.sectPr_lst[key], self._document_part) + + def __iter__(self) -> Iterator[Section]: + for sectPr in self._document_elm.sectPr_lst: + yield Section(sectPr, self._document_part) + + def __len__(self) -> int: + return len(self._document_elm.sectPr_lst) + + +class _BaseHeaderFooter(BlockItemContainer): + """Base class for header and footer classes.""" + + def __init__( + self, + sectPr: CT_SectPr, + document_part: DocumentPart, + header_footer_index: WD_HEADER_FOOTER, + ): self._sectPr = sectPr self._document_part = document_part self._hdrftr_index = header_footer_index @property - def is_linked_to_previous(self): + def is_linked_to_previous(self) -> bool: """``True`` if this header/footer uses the definition from the prior section. ``False`` if this header/footer has an explicit definition. @@ -282,7 +314,7 @@ def is_linked_to_previous(self): return not self._has_definition @is_linked_to_previous.setter - def is_linked_to_previous(self, value): + def is_linked_to_previous(self, value: bool) -> None: new_state = bool(value) # ---do nothing when value is not being changed--- if new_state == self.is_linked_to_previous: @@ -293,7 +325,7 @@ def is_linked_to_previous(self, value): self._add_definition() @property - def part(self): + def part(self) -> HeaderPart | FooterPart: """The |HeaderPart| or |FooterPart| for this header/footer. This overrides `BlockItemContainer.part` and is required to support image @@ -303,16 +335,16 @@ def part(self): # ---not an interface property, even though public return self._get_or_add_definition() - def _add_definition(self): + def _add_definition(self) -> HeaderPart | FooterPart: """Return newly-added header/footer part.""" raise NotImplementedError("must be implemented by each subclass") @property - def _definition(self): + def _definition(self) -> HeaderPart | FooterPart: """|HeaderPart| or |FooterPart| object containing header/footer content.""" raise NotImplementedError("must be implemented by each subclass") - def _drop_definition(self): + def _drop_definition(self) -> None: """Remove header/footer part containing the definition of this header/footer.""" raise NotImplementedError("must be implemented by each subclass") @@ -321,7 +353,7 @@ def _element(self): """`w:hdr` or `w:ftr` element, root of header/footer part.""" return self._get_or_add_definition().element - def _get_or_add_definition(self): + def _get_or_add_definition(self) -> HeaderPart | FooterPart: """Return HeaderPart or FooterPart object for this section. If this header/footer inherits its content, the part for the prior header/footer @@ -342,12 +374,12 @@ def _get_or_add_definition(self): return self._add_definition() @property - def _has_definition(self): + def _has_definition(self) -> bool: """True if this header/footer has a related part containing its definition.""" raise NotImplementedError("must be implemented by each subclass") @property - def _prior_headerfooter(self): + def _prior_headerfooter(self) -> _Header | _Footer | None: """|_Header| or |_Footer| proxy on prior sectPr element. Returns None if this is first section. @@ -365,7 +397,7 @@ class _Footer(_BaseHeaderFooter): leave an empty paragraph above the newly added one. """ - def _add_definition(self): + def _add_definition(self) -> FooterPart: """Return newly-added footer part.""" footer_part, rId = self._document_part.add_footer_part() self._sectPr.add_footerReference(self._hdrftr_index, rId) @@ -375,6 +407,8 @@ def _add_definition(self): def _definition(self): """|FooterPart| object containing content of this footer.""" footerReference = self._sectPr.get_footerReference(self._hdrftr_index) + # -- currently this is never called when `._has_definition` evaluates False -- + assert footerReference is not None return self._document_part.footer_part(footerReference.rId) def _drop_definition(self): @@ -383,10 +417,10 @@ def _drop_definition(self): self._document_part.drop_rel(rId) @property - def _has_definition(self): + def _has_definition(self) -> bool: """True if a footer is defined for this section.""" footerReference = self._sectPr.get_footerReference(self._hdrftr_index) - return False if footerReference is None else True + return footerReference is not None @property def _prior_headerfooter(self): @@ -419,6 +453,8 @@ def _add_definition(self): def _definition(self): """|HeaderPart| object containing content of this header.""" headerReference = self._sectPr.get_headerReference(self._hdrftr_index) + # -- currently this is never called when `._has_definition` evaluates False -- + assert headerReference is not None return self._document_part.header_part(headerReference.rId) def _drop_definition(self): @@ -427,10 +463,10 @@ def _drop_definition(self): self._document_part.drop_header_part(rId) @property - def _has_definition(self): + def _has_definition(self) -> bool: """True if a header is explicitly defined for this section.""" headerReference = self._sectPr.get_headerReference(self._hdrftr_index) - return False if headerReference is None else True + return headerReference is not None @property def _prior_headerfooter(self): diff --git a/src/docx/settings.py b/src/docx/settings.py new file mode 100644 index 00000000..0a5aa2f3 --- /dev/null +++ b/src/docx/settings.py @@ -0,0 +1,35 @@ +"""Settings object, providing access to document-level settings.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, cast + +from docx.shared import ElementProxy + +if TYPE_CHECKING: + import docx.types as t + from docx.oxml.settings import CT_Settings + from docx.oxml.xmlchemy import BaseOxmlElement + + +class Settings(ElementProxy): + """Provides access to document-level settings for a document. + + Accessed using the :attr:`.Document.settings` property. + """ + + def __init__(self, element: BaseOxmlElement, parent: t.ProvidesXmlPart | None = None): + super().__init__(element, parent) + self._settings = cast("CT_Settings", element) + + @property + def odd_and_even_pages_header_footer(self) -> bool: + """True if this document has distinct odd and even page headers and footers. + + Read/write. + """ + return self._settings.evenAndOddHeaders_val + + @odd_and_even_pages_header_footer.setter + def odd_and_even_pages_header_footer(self, value: bool): + self._settings.evenAndOddHeaders_val = value diff --git a/docx/shape.py b/src/docx/shape.py similarity index 58% rename from docx/shape.py rename to src/docx/shape.py index 036118d4..cd35deb3 100644 --- a/docx/shape.py +++ b/src/docx/shape.py @@ -1,36 +1,38 @@ -# encoding: utf-8 +"""Objects related to shapes. +A shape is a visual object that appears on the drawing layer of a document. """ -Objects related to shapes, visual objects that appear on the drawing layer of -a document. -""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import annotations + +from typing import TYPE_CHECKING + +from docx.enum.shape import WD_INLINE_SHAPE +from docx.oxml.ns import nsmap +from docx.shared import Parented -from .enum.shape import WD_INLINE_SHAPE -from .oxml.ns import nsmap -from .shared import Parented +if TYPE_CHECKING: + from docx.oxml.document import CT_Body + from docx.oxml.shape import CT_Inline + from docx.parts.story import StoryPart + from docx.shared import Length class InlineShapes(Parented): - """ - Sequence of |InlineShape| instances, supporting len(), iteration, and - indexed access. - """ + """Sequence of |InlineShape| instances, supporting len(), iteration, and indexed access.""" - def __init__(self, body_elm, parent): + def __init__(self, body_elm: CT_Body, parent: StoryPart): super(InlineShapes, self).__init__(parent) self._body = body_elm - def __getitem__(self, idx): - """ - Provide indexed access, e.g. 'inline_shapes[idx]' - """ + def __getitem__(self, idx: int): + """Provide indexed access, e.g. 'inline_shapes[idx]'.""" try: inline = self._inline_lst[idx] except IndexError: msg = "inline shape index [%d] out of range" % idx raise IndexError(msg) + return InlineShape(inline) def __iter__(self): @@ -46,34 +48,32 @@ def _inline_lst(self): return body.xpath(xpath) -class InlineShape(object): - """ - Proxy for an ```` element, representing the container for an - inline graphical object. - """ +class InlineShape: + """Proxy for an ```` element, representing the container for an inline + graphical object.""" - def __init__(self, inline): + def __init__(self, inline: CT_Inline): super(InlineShape, self).__init__() self._inline = inline @property - def height(self): - """ - Read/write. The display height of this inline shape as an |Emu| - instance. + def height(self) -> Length: + """Read/write. + + The display height of this inline shape as an |Emu| instance. """ return self._inline.extent.cy @height.setter - def height(self, cy): + def height(self, cy: Length): self._inline.extent.cy = cy self._inline.graphic.graphicData.pic.spPr.cy = cy @property def type(self): - """ - The type of this inline shape as a member of + """The type of this inline shape as a member of ``docx.enum.shape.WD_INLINE_SHAPE``, e.g. ``LINKED_PICTURE``. + Read-only. """ graphicData = self._inline.graphic.graphicData @@ -91,13 +91,13 @@ def type(self): @property def width(self): - """ - Read/write. The display width of this inline shape as an |Emu| - instance. + """Read/write. + + The display width of this inline shape as an |Emu| instance. """ return self._inline.extent.cx @width.setter - def width(self, cx): + def width(self, cx: Length): self._inline.extent.cx = cx self._inline.graphic.graphicData.pic.spPr.cx = cx diff --git a/src/docx/shared.py b/src/docx/shared.py new file mode 100644 index 00000000..6c12dc91 --- /dev/null +++ b/src/docx/shared.py @@ -0,0 +1,382 @@ +"""Objects shared by docx modules.""" + +from __future__ import annotations + +import functools +from typing import ( + TYPE_CHECKING, + Any, + Callable, + Generic, + Iterator, + List, + Tuple, + TypeVar, + cast, +) + +if TYPE_CHECKING: + import docx.types as t + from docx.opc.part import XmlPart + from docx.oxml.xmlchemy import BaseOxmlElement + from docx.parts.story import StoryPart + + +class Length(int): + """Base class for length constructor classes Inches, Cm, Mm, Px, and Emu. + + Behaves as an int count of English Metric Units, 914,400 to the inch, 36,000 to the + mm. Provides convenience unit conversion methods in the form of read-only + properties. Immutable. + """ + + _EMUS_PER_INCH = 914400 + _EMUS_PER_CM = 360000 + _EMUS_PER_MM = 36000 + _EMUS_PER_PT = 12700 + _EMUS_PER_TWIP = 635 + + def __new__(cls, emu: int): + return int.__new__(cls, emu) + + @property + def cm(self): + """The equivalent length expressed in centimeters (float).""" + return self / float(self._EMUS_PER_CM) + + @property + def emu(self): + """The equivalent length expressed in English Metric Units (int).""" + return self + + @property + def inches(self): + """The equivalent length expressed in inches (float).""" + return self / float(self._EMUS_PER_INCH) + + @property + def mm(self): + """The equivalent length expressed in millimeters (float).""" + return self / float(self._EMUS_PER_MM) + + @property + def pt(self): + """Floating point length in points.""" + return self / float(self._EMUS_PER_PT) + + @property + def twips(self): + """The equivalent length expressed in twips (int).""" + return int(round(self / float(self._EMUS_PER_TWIP))) + + +class Inches(Length): + """Convenience constructor for length in inches, e.g. ``width = Inches(0.5)``.""" + + def __new__(cls, inches: float): + emu = int(inches * Length._EMUS_PER_INCH) + return Length.__new__(cls, emu) + + +class Cm(Length): + """Convenience constructor for length in centimeters, e.g. ``height = Cm(12)``.""" + + def __new__(cls, cm: float): + emu = int(cm * Length._EMUS_PER_CM) + return Length.__new__(cls, emu) + + +class Emu(Length): + """Convenience constructor for length in English Metric Units, e.g. ``width = + Emu(457200)``.""" + + def __new__(cls, emu: int): + return Length.__new__(cls, int(emu)) + + +class Mm(Length): + """Convenience constructor for length in millimeters, e.g. ``width = Mm(240.5)``.""" + + def __new__(cls, mm: float): + emu = int(mm * Length._EMUS_PER_MM) + return Length.__new__(cls, emu) + + +class Pt(Length): + """Convenience value class for specifying a length in points.""" + + def __new__(cls, points: float): + emu = int(points * Length._EMUS_PER_PT) + return Length.__new__(cls, emu) + + +class Twips(Length): + """Convenience constructor for length in twips, e.g. ``width = Twips(42)``. + + A twip is a twentieth of a point, 635 EMU. + """ + + def __new__(cls, twips: float): + emu = int(twips * Length._EMUS_PER_TWIP) + return Length.__new__(cls, emu) + + +class RGBColor(Tuple[int, int, int]): + """Immutable value object defining a particular RGB color.""" + + def __new__(cls, r: int, g: int, b: int): + msg = "RGBColor() takes three integer values 0-255" + for val in (r, g, b): + if not isinstance(val, int): # pyright: ignore[reportUnnecessaryIsInstance] + raise TypeError(msg) + if val < 0 or val > 255: + raise ValueError(msg) + return super(RGBColor, cls).__new__(cls, (r, g, b)) + + def __repr__(self): + return "RGBColor(0x%02x, 0x%02x, 0x%02x)" % self + + def __str__(self): + """Return a hex string rgb value, like '3C2F80'.""" + return "%02X%02X%02X" % self + + @classmethod + def from_string(cls, rgb_hex_str: str) -> RGBColor: + """Return a new instance from an RGB color hex string like ``'3C2F80'``.""" + r = int(rgb_hex_str[:2], 16) + g = int(rgb_hex_str[2:4], 16) + b = int(rgb_hex_str[4:], 16) + return cls(r, g, b) + + +T = TypeVar("T") + + +class lazyproperty(Generic[T]): + """Decorator like @property, but evaluated only on first access. + + Like @property, this can only be used to decorate methods having only a `self` + parameter, and is accessed like an attribute on an instance, i.e. trailing + parentheses are not used. Unlike @property, the decorated method is only evaluated + on first access; the resulting value is cached and that same value returned on + second and later access without re-evaluation of the method. + + Like @property, this class produces a *data descriptor* object, which is stored in + the __dict__ of the *class* under the name of the decorated method ('fget' + nominally). The cached value is stored in the __dict__ of the *instance* under that + same name. + + Because it is a data descriptor (as opposed to a *non-data descriptor*), its + `__get__()` method is executed on each access of the decorated attribute; the + __dict__ item of the same name is "shadowed" by the descriptor. + + While this may represent a performance improvement over a property, its greater + benefit may be its other characteristics. One common use is to construct + collaborator objects, removing that "real work" from the constructor, while still + only executing once. It also de-couples client code from any sequencing + considerations; if it's accessed from more than one location, it's assured it will + be ready whenever needed. + + Loosely based on: https://stackoverflow.com/a/6849299/1902513. + + A lazyproperty is read-only. There is no counterpart to the optional "setter" (or + deleter) behavior of an @property. This is critically important to maintaining its + immutability and idempotence guarantees. Attempting to assign to a lazyproperty + raises AttributeError unconditionally. + + The parameter names in the methods below correspond to this usage example:: + + class Obj(object) + + @lazyproperty + def fget(self): + return 'some result' + + obj = Obj() + + Not suitable for wrapping a function (as opposed to a method) because it is not + callable.""" + + def __init__(self, fget: Callable[..., T]) -> None: + """*fget* is the decorated method (a "getter" function). + + A lazyproperty is read-only, so there is only an *fget* function (a regular + @property can also have an fset and fdel function). This name was chosen for + consistency with Python's `property` class which uses this name for the + corresponding parameter. + """ + # --- maintain a reference to the wrapped getter method + self._fget = fget + # --- and store the name of that decorated method + self._name = fget.__name__ + # --- adopt fget's __name__, __doc__, and other attributes + functools.update_wrapper(self, fget) # pyright: ignore + + def __get__(self, obj: Any, type: Any = None) -> T: + """Called on each access of 'fget' attribute on class or instance. + + *self* is this instance of a lazyproperty descriptor "wrapping" the property + method it decorates (`fget`, nominally). + + *obj* is the "host" object instance when the attribute is accessed from an + object instance, e.g. `obj = Obj(); obj.fget`. *obj* is None when accessed on + the class, e.g. `Obj.fget`. + + *type* is the class hosting the decorated getter method (`fget`) on both class + and instance attribute access. + """ + # --- when accessed on class, e.g. Obj.fget, just return this descriptor + # --- instance (patched above to look like fget). + if obj is None: + return self # type: ignore + + # --- when accessed on instance, start by checking instance __dict__ for + # --- item with key matching the wrapped function's name + value = obj.__dict__.get(self._name) + if value is None: + # --- on first access, the __dict__ item will be absent. Evaluate fget() + # --- and store that value in the (otherwise unused) host-object + # --- __dict__ value of same name ('fget' nominally) + value = self._fget(obj) + obj.__dict__[self._name] = value + return cast(T, value) + + def __set__(self, obj: Any, value: Any) -> None: + """Raises unconditionally, to preserve read-only behavior. + + This decorator is intended to implement immutable (and idempotent) object + attributes. For that reason, assignment to this property must be explicitly + prevented. + + If this __set__ method was not present, this descriptor would become a + *non-data descriptor*. That would be nice because the cached value would be + accessed directly once set (__dict__ attrs have precedence over non-data + descriptors on instance attribute lookup). The problem is, there would be + nothing to stop assignment to the cached value, which would overwrite the result + of `fget()` and break both the immutability and idempotence guarantees of this + decorator. + + The performance with this __set__() method in place was roughly 0.4 usec per + access when measured on a 2.8GHz development machine; so quite snappy and + probably not a rich target for optimization efforts. + """ + raise AttributeError("can't set attribute") + + +def write_only_property(f: Callable[[Any, Any], None]): + """@write_only_property decorator. + + Creates a property (descriptor attribute) that accepts assignment, but not getattr + (use in an expression). + """ + docstring = f.__doc__ + + return property(fset=f, doc=docstring) + + +class ElementProxy: + """Base class for lxml element proxy classes. + + An element proxy class is one whose primary responsibilities are fulfilled by + manipulating the attributes and child elements of an XML element. They are the most + common type of class in python-docx other than custom element (oxml) classes. + """ + + def __init__(self, element: BaseOxmlElement, parent: t.ProvidesXmlPart | None = None): + self._element = element + self._parent = parent + + def __eq__(self, other: object): + """Return |True| if this proxy object refers to the same oxml element as does + `other`. + + ElementProxy objects are value objects and should maintain no mutable local + state. Equality for proxy objects is defined as referring to the same XML + element, whether or not they are the same proxy object instance. + """ + if not isinstance(other, ElementProxy): + return False + return self._element is other._element + + def __ne__(self, other: object): + if not isinstance(other, ElementProxy): + return True + return self._element is not other._element + + @property + def element(self): + """The lxml element proxied by this object.""" + return self._element + + @property + def part(self) -> XmlPart: + """The package part containing this object.""" + if self._parent is None: + raise ValueError("part is not accessible from this element") + return self._parent.part + + +class Parented: + """Provides common services for document elements that occur below a part but may + occasionally require an ancestor object to provide a service, such as add or drop a + relationship. + + Provides ``self._parent`` attribute to subclasses. + """ + + def __init__(self, parent: t.ProvidesXmlPart): + self._parent = parent + + @property + def part(self) -> XmlPart: + """The package part containing this object.""" + return self._parent.part + + +class StoryChild: + """A document element within a story part. + + Story parts include DocumentPart and Header/FooterPart and can contain block items + (paragraphs and tables). Items from the block-item subtree occasionally require an + ancestor object to provide access to part-level or package-level items like styles + or images or to add or drop a relationship. + + Provides `self._parent` attribute to subclasses. + """ + + def __init__(self, parent: t.ProvidesStoryPart): + self._parent = parent + + @property + def part(self) -> StoryPart: + """The package part containing this object.""" + return self._parent.part + + +class TextAccumulator: + """Accepts `str` fragments and joins them together, in order, on `.pop(). + + Handy when text in a stream is broken up arbitrarily and you want to join it back + together within certain bounds. The optional `separator` argument determines how + the text fragments are punctuated, defaulting to the empty string. + """ + + def __init__(self, separator: str = ""): + self._separator = separator + self._texts: List[str] = [] + + def push(self, text: str) -> None: + """Add a text fragment to the accumulator.""" + self._texts.append(text) + + def pop(self) -> Iterator[str]: + """Generate sero-or-one str from those accumulated. + + Using `yield from accum.pop()` in a generator setting avoids producing an empty + string when no text is in the accumulator. + """ + if not self._texts: + return + text = self._separator.join(self._texts) + self._texts.clear() + yield text diff --git a/src/docx/styles/__init__.py b/src/docx/styles/__init__.py new file mode 100644 index 00000000..6358baf3 --- /dev/null +++ b/src/docx/styles/__init__.py @@ -0,0 +1,40 @@ +"""Sub-package module for docx.styles sub-package.""" + +from __future__ import annotations + +from typing import Dict + + +class BabelFish: + """Translates special-case style names from UI name (e.g. Heading 1) to + internal/styles.xml name (e.g. heading 1) and back.""" + + style_aliases = ( + ("Caption", "caption"), + ("Footer", "footer"), + ("Header", "header"), + ("Heading 1", "heading 1"), + ("Heading 2", "heading 2"), + ("Heading 3", "heading 3"), + ("Heading 4", "heading 4"), + ("Heading 5", "heading 5"), + ("Heading 6", "heading 6"), + ("Heading 7", "heading 7"), + ("Heading 8", "heading 8"), + ("Heading 9", "heading 9"), + ) + + internal_style_names: Dict[str, str] = dict(style_aliases) + ui_style_names = {item[1]: item[0] for item in style_aliases} + + @classmethod + def ui2internal(cls, ui_style_name: str) -> str: + """Return the internal style name corresponding to `ui_style_name`, such as + 'heading 1' for 'Heading 1'.""" + return cls.internal_style_names.get(ui_style_name, ui_style_name) + + @classmethod + def internal2ui(cls, internal_style_name: str) -> str: + """Return the user interface style name corresponding to `internal_style_name`, + such as 'Heading 1' for 'heading 1'.""" + return cls.ui_style_names.get(internal_style_name, internal_style_name) diff --git a/src/docx/styles/latent.py b/src/docx/styles/latent.py new file mode 100644 index 00000000..c9db62f8 --- /dev/null +++ b/src/docx/styles/latent.py @@ -0,0 +1,198 @@ +"""Latent style-related objects.""" + +from docx.shared import ElementProxy +from docx.styles import BabelFish + + +class LatentStyles(ElementProxy): + """Provides access to the default behaviors for latent styles in this document and + to the collection of |_LatentStyle| objects that define overrides of those defaults + for a particular named latent style.""" + + def __getitem__(self, key): + """Enables dictionary-style access to a latent style by name.""" + style_name = BabelFish.ui2internal(key) + lsdException = self._element.get_by_name(style_name) + if lsdException is None: + raise KeyError("no latent style with name '%s'" % key) + return _LatentStyle(lsdException) + + def __iter__(self): + return (_LatentStyle(ls) for ls in self._element.lsdException_lst) + + def __len__(self): + return len(self._element.lsdException_lst) + + def add_latent_style(self, name): + """Return a newly added |_LatentStyle| object to override the inherited defaults + defined in this latent styles object for the built-in style having `name`.""" + lsdException = self._element.add_lsdException() + lsdException.name = BabelFish.ui2internal(name) + return _LatentStyle(lsdException) + + @property + def default_priority(self): + """Integer between 0 and 99 inclusive specifying the default sort order for + latent styles in style lists and the style gallery. + + |None| if no value is assigned, which causes Word to use the default value 99. + """ + return self._element.defUIPriority + + @default_priority.setter + def default_priority(self, value): + self._element.defUIPriority = value + + @property + def default_to_hidden(self): + """Boolean specifying whether the default behavior for latent styles is to be + hidden. + + A hidden style does not appear in the recommended list or in the style gallery. + """ + return self._element.bool_prop("defSemiHidden") + + @default_to_hidden.setter + def default_to_hidden(self, value): + self._element.set_bool_prop("defSemiHidden", value) + + @property + def default_to_locked(self): + """Boolean specifying whether the default behavior for latent styles is to be + locked. + + A locked style does not appear in the styles panel or the style gallery and + cannot be applied to document content. This behavior is only active when + formatting protection is turned on for the document (via the Developer menu). + """ + return self._element.bool_prop("defLockedState") + + @default_to_locked.setter + def default_to_locked(self, value): + self._element.set_bool_prop("defLockedState", value) + + @property + def default_to_quick_style(self): + """Boolean specifying whether the default behavior for latent styles is to + appear in the style gallery when not hidden.""" + return self._element.bool_prop("defQFormat") + + @default_to_quick_style.setter + def default_to_quick_style(self, value): + self._element.set_bool_prop("defQFormat", value) + + @property + def default_to_unhide_when_used(self): + """Boolean specifying whether the default behavior for latent styles is to be + unhidden when first applied to content.""" + return self._element.bool_prop("defUnhideWhenUsed") + + @default_to_unhide_when_used.setter + def default_to_unhide_when_used(self, value): + self._element.set_bool_prop("defUnhideWhenUsed", value) + + @property + def load_count(self): + """Integer specifying the number of built-in styles to initialize to the + defaults specified in this |LatentStyles| object. + + |None| if there is no setting in the XML (very uncommon). The default Word 2011 + template sets this value to 276, accounting for the built-in styles in Word + 2010. + """ + return self._element.count + + @load_count.setter + def load_count(self, value): + self._element.count = value + + +class _LatentStyle(ElementProxy): + """Proxy for an `w:lsdException` element, which specifies display behaviors for a + built-in style when no definition for that style is stored yet in the `styles.xml` + part. + + The values in this element override the defaults specified in the parent + `w:latentStyles` element. + """ + + def delete(self): + """Remove this latent style definition such that the defaults defined in the + containing |LatentStyles| object provide the effective value for each of its + attributes. + + Attempting to access any attributes on this object after calling this method + will raise |AttributeError|. + """ + self._element.delete() + self._element = None + + @property + def hidden(self): + """Tri-state value specifying whether this latent style should appear in the + recommended list. + + |None| indicates the effective value is inherited from the parent + ```` element. + """ + return self._element.on_off_prop("semiHidden") + + @hidden.setter + def hidden(self, value): + self._element.set_on_off_prop("semiHidden", value) + + @property + def locked(self): + """Tri-state value specifying whether this latent styles is locked. + + A locked style does not appear in the styles panel or the style gallery and + cannot be applied to document content. This behavior is only active when + formatting protection is turned on for the document (via the Developer menu). + """ + return self._element.on_off_prop("locked") + + @locked.setter + def locked(self, value): + self._element.set_on_off_prop("locked", value) + + @property + def name(self): + """The name of the built-in style this exception applies to.""" + return BabelFish.internal2ui(self._element.name) + + @property + def priority(self): + """The integer sort key for this latent style in the Word UI.""" + return self._element.uiPriority + + @priority.setter + def priority(self, value): + self._element.uiPriority = value + + @property + def quick_style(self): + """Tri-state value specifying whether this latent style should appear in the + Word styles gallery when not hidden. + + |None| indicates the effective value should be inherited from the default values + in its parent |LatentStyles| object. + """ + return self._element.on_off_prop("qFormat") + + @quick_style.setter + def quick_style(self, value): + self._element.set_on_off_prop("qFormat", value) + + @property + def unhide_when_used(self): + """Tri-state value specifying whether this style should have its :attr:`hidden` + attribute set |False| the next time the style is applied to content. + + |None| indicates the effective value should be inherited from the default + specified by its parent |LatentStyles| object. + """ + return self._element.on_off_prop("unhideWhenUsed") + + @unhide_when_used.setter + def unhide_when_used(self, value): + self._element.set_on_off_prop("unhideWhenUsed", value) diff --git a/src/docx/styles/style.py b/src/docx/styles/style.py new file mode 100644 index 00000000..aa175ea8 --- /dev/null +++ b/src/docx/styles/style.py @@ -0,0 +1,254 @@ +"""Style object hierarchy.""" + +from __future__ import annotations + +from typing import Type + +from docx.enum.style import WD_STYLE_TYPE +from docx.oxml.styles import CT_Style +from docx.shared import ElementProxy +from docx.styles import BabelFish +from docx.text.font import Font +from docx.text.parfmt import ParagraphFormat + + +def StyleFactory(style_elm: CT_Style) -> BaseStyle: + """Return `Style` object of appropriate |BaseStyle| subclass for `style_elm`.""" + style_cls: Type[BaseStyle] = { + WD_STYLE_TYPE.PARAGRAPH: ParagraphStyle, + WD_STYLE_TYPE.CHARACTER: CharacterStyle, + WD_STYLE_TYPE.TABLE: _TableStyle, + WD_STYLE_TYPE.LIST: _NumberingStyle, + }[style_elm.type] + + return style_cls(style_elm) + + +class BaseStyle(ElementProxy): + """Base class for the various types of style object, paragraph, character, table, + and numbering. + + These properties and methods are inherited by all style objects. + """ + + def __init__(self, style_elm: CT_Style): + super().__init__(style_elm) + self._style_elm = style_elm + + @property + def builtin(self): + """Read-only. + + |True| if this style is a built-in style. |False| indicates it is a custom + (user-defined) style. Note this value is based on the presence of a + `customStyle` attribute in the XML, not on specific knowledge of which styles + are built into Word. + """ + return not self._element.customStyle + + def delete(self): + """Remove this style definition from the document. + + Note that calling this method does not remove or change the style applied to any + document content. Content items having the deleted style will be rendered using + the default style, as is any content with a style not defined in the document. + """ + self._element.delete() + self._element = None + + @property + def hidden(self): + """|True| if display of this style in the style gallery and list of recommended + styles is suppressed. + + |False| otherwise. In order to be shown in the style gallery, this value must be + |False| and :attr:`.quick_style` must be |True|. + """ + return self._element.semiHidden_val + + @hidden.setter + def hidden(self, value): + self._element.semiHidden_val = value + + @property + def locked(self): + """Read/write Boolean. + + |True| if this style is locked. A locked style does not appear in the styles + panel or the style gallery and cannot be applied to document content. This + behavior is only active when formatting protection is turned on for the document + (via the Developer menu). + """ + return self._element.locked_val + + @locked.setter + def locked(self, value): + self._element.locked_val = value + + @property + def name(self): + """The UI name of this style.""" + name = self._element.name_val + if name is None: + return None + return BabelFish.internal2ui(name) + + @name.setter + def name(self, value): + self._element.name_val = value + + @property + def priority(self): + """The integer sort key governing display sequence of this style in the Word UI. + + |None| indicates no setting is defined, causing Word to use the default value of + 0. Style name is used as a secondary sort key to resolve ordering of styles + having the same priority value. + """ + return self._element.uiPriority_val + + @priority.setter + def priority(self, value): + self._element.uiPriority_val = value + + @property + def quick_style(self): + """|True| if this style should be displayed in the style gallery when + :attr:`.hidden` is |False|. + + Read/write Boolean. + """ + return self._element.qFormat_val + + @quick_style.setter + def quick_style(self, value): + self._element.qFormat_val = value + + @property + def style_id(self) -> str: + """The unique key name (string) for this style. + + This value is subject to rewriting by Word and should generally not be changed + unless you are familiar with the internals involved. + """ + return self._style_elm.styleId + + @style_id.setter + def style_id(self, value): + self._element.styleId = value + + @property + def type(self): + """Member of :ref:`WdStyleType` corresponding to the type of this style, e.g. + ``WD_STYLE_TYPE.PARAGRAPH``.""" + type = self._style_elm.type + if type is None: + return WD_STYLE_TYPE.PARAGRAPH + return type + + @property + def unhide_when_used(self): + """|True| if an application should make this style visible the next time it is + applied to content. + + False otherwise. Note that |docx| does not automatically unhide a style having + |True| for this attribute when it is applied to content. + """ + return self._element.unhideWhenUsed_val + + @unhide_when_used.setter + def unhide_when_used(self, value): + self._element.unhideWhenUsed_val = value + + +class CharacterStyle(BaseStyle): + """A character style. + + A character style is applied to a |Run| object and primarily provides character- + level formatting via the |Font| object in its :attr:`.font` property. + """ + + @property + def base_style(self): + """Style object this style inherits from or |None| if this style is not based on + another style.""" + base_style = self._element.base_style + if base_style is None: + return None + return StyleFactory(base_style) + + @base_style.setter + def base_style(self, style): + style_id = style.style_id if style is not None else None + self._element.basedOn_val = style_id + + @property + def font(self): + """The |Font| object providing access to the character formatting properties for + this style, such as font name and size.""" + return Font(self._element) + + +# -- just in case someone uses the old name in an extension function -- +_CharacterStyle = CharacterStyle + + +class ParagraphStyle(CharacterStyle): + """A paragraph style. + + A paragraph style provides both character formatting and paragraph formatting such + as indentation and line-spacing. + """ + + def __repr__(self): + return "_ParagraphStyle('%s') id: %s" % (self.name, id(self)) + + @property + def next_paragraph_style(self): + """|_ParagraphStyle| object representing the style to be applied automatically + to a new paragraph inserted after a paragraph of this style. + + Returns self if no next paragraph style is defined. Assigning |None| or `self` + removes the setting such that new paragraphs are created using this same style. + """ + next_style_elm = self._element.next_style + if next_style_elm is None: + return self + if next_style_elm.type != WD_STYLE_TYPE.PARAGRAPH: + return self + return StyleFactory(next_style_elm) + + @next_paragraph_style.setter + def next_paragraph_style(self, style): + if style is None or style.style_id == self.style_id: + self._element._remove_next() + else: + self._element.get_or_add_next().val = style.style_id + + @property + def paragraph_format(self): + """The |ParagraphFormat| object providing access to the paragraph formatting + properties for this style such as indentation.""" + return ParagraphFormat(self._element) + + +# -- just in case someone uses the old name in an extension function -- +_ParagraphStyle = ParagraphStyle + + +class _TableStyle(ParagraphStyle): + """A table style. + + A table style provides character and paragraph formatting for its contents as well + as special table formatting properties. + """ + + def __repr__(self): + return "_TableStyle('%s') id: %s" % (self.name, id(self)) + + +class _NumberingStyle(BaseStyle): + """A numbering style. + + Not yet implemented. + """ diff --git a/src/docx/styles/styles.py b/src/docx/styles/styles.py new file mode 100644 index 00000000..b05b3ebb --- /dev/null +++ b/src/docx/styles/styles.py @@ -0,0 +1,136 @@ +"""Styles object, container for all objects in the styles part.""" + +from __future__ import annotations + +from warnings import warn + +from docx.enum.style import WD_STYLE_TYPE +from docx.oxml.styles import CT_Styles +from docx.shared import ElementProxy +from docx.styles import BabelFish +from docx.styles.latent import LatentStyles +from docx.styles.style import BaseStyle, StyleFactory + + +class Styles(ElementProxy): + """Provides access to the styles defined in a document. + + Accessed using the :attr:`.Document.styles` property. Supports ``len()``, iteration, + and dictionary-style access by style name. + """ + + def __init__(self, styles: CT_Styles): + super().__init__(styles) + self._element = styles + + def __contains__(self, name): + """Enables `in` operator on style name.""" + internal_name = BabelFish.ui2internal(name) + return any(style.name_val == internal_name for style in self._element.style_lst) + + def __getitem__(self, key: str): + """Enables dictionary-style access by UI name. + + Lookup by style id is deprecated, triggers a warning, and will be removed in a + near-future release. + """ + style_elm = self._element.get_by_name(BabelFish.ui2internal(key)) + if style_elm is not None: + return StyleFactory(style_elm) + + style_elm = self._element.get_by_id(key) + if style_elm is not None: + msg = "style lookup by style_id is deprecated. Use style name as key instead." + warn(msg, UserWarning, stacklevel=2) + return StyleFactory(style_elm) + + raise KeyError("no style with name '%s'" % key) + + def __iter__(self): + return (StyleFactory(style) for style in self._element.style_lst) + + def __len__(self): + return len(self._element.style_lst) + + def add_style(self, name, style_type, builtin=False): + """Return a newly added style object of `style_type` and identified by `name`. + + A builtin style can be defined by passing True for the optional `builtin` + argument. + """ + style_name = BabelFish.ui2internal(name) + if style_name in self: + raise ValueError("document already contains style '%s'" % name) + style = self._element.add_style_of_type(style_name, style_type, builtin) + return StyleFactory(style) + + def default(self, style_type: WD_STYLE_TYPE): + """Return the default style for `style_type` or |None| if no default is defined + for that type (not common).""" + style = self._element.default_for(style_type) + if style is None: + return None + return StyleFactory(style) + + def get_by_id(self, style_id: str | None, style_type: WD_STYLE_TYPE): + """Return the style of `style_type` matching `style_id`. + + Returns the default for `style_type` if `style_id` is not found or is |None|, or + if the style having `style_id` is not of `style_type`. + """ + if style_id is None: + return self.default(style_type) + return self._get_by_id(style_id, style_type) + + def get_style_id(self, style_or_name, style_type): + """Return the id of the style corresponding to `style_or_name`, or |None| if + `style_or_name` is |None|. + + If `style_or_name` is not a style object, the style is looked up using + `style_or_name` as a style name, raising |ValueError| if no style with that name + is defined. Raises |ValueError| if the target style is not of `style_type`. + """ + if style_or_name is None: + return None + elif isinstance(style_or_name, BaseStyle): + return self._get_style_id_from_style(style_or_name, style_type) + else: + return self._get_style_id_from_name(style_or_name, style_type) + + @property + def latent_styles(self): + """A |LatentStyles| object providing access to the default behaviors for latent + styles and the collection of |_LatentStyle| objects that define overrides of + those defaults for a particular named latent style.""" + return LatentStyles(self._element.get_or_add_latentStyles()) + + def _get_by_id(self, style_id: str | None, style_type: WD_STYLE_TYPE): + """Return the style of `style_type` matching `style_id`. + + Returns the default for `style_type` if `style_id` is not found or if the style + having `style_id` is not of `style_type`. + """ + style = self._element.get_by_id(style_id) if style_id else None + if style is None or style.type != style_type: + return self.default(style_type) + return StyleFactory(style) + + def _get_style_id_from_name(self, style_name: str, style_type: WD_STYLE_TYPE) -> str | None: + """Return the id of the style of `style_type` corresponding to `style_name`. + + Returns |None| if that style is the default style for `style_type`. Raises + |ValueError| if the named style is not found in the document or does not match + `style_type`. + """ + return self._get_style_id_from_style(self[style_name], style_type) + + def _get_style_id_from_style(self, style: BaseStyle, style_type: WD_STYLE_TYPE) -> str | None: + """Id of `style`, or |None| if it is the default style of `style_type`. + + Raises |ValueError| if style is not of `style_type`. + """ + if style.type != style_type: + raise ValueError("assigned style is type %s, need type %s" % (style.type, style_type)) + if style == self.default(style_type): + return None + return style.style_id diff --git a/src/docx/table.py b/src/docx/table.py new file mode 100644 index 00000000..545c4688 --- /dev/null +++ b/src/docx/table.py @@ -0,0 +1,537 @@ +"""The |Table| object and related proxy classes.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Iterator, cast, overload + +from typing_extensions import TypeAlias + +from docx.blkcntnr import BlockItemContainer +from docx.enum.style import WD_STYLE_TYPE +from docx.enum.table import WD_CELL_VERTICAL_ALIGNMENT +from docx.oxml.simpletypes import ST_Merge +from docx.oxml.table import CT_TblGridCol +from docx.shared import Inches, Parented, StoryChild, lazyproperty + +if TYPE_CHECKING: + import docx.types as t + from docx.enum.table import WD_ROW_HEIGHT_RULE, WD_TABLE_ALIGNMENT, WD_TABLE_DIRECTION + from docx.oxml.table import CT_Row, CT_Tbl, CT_TblPr, CT_Tc + from docx.shared import Length + from docx.styles.style import ( + ParagraphStyle, + _TableStyle, # pyright: ignore[reportPrivateUsage] + ) + +TableParent: TypeAlias = "Table | _Columns | _Rows" + + +class Table(StoryChild): + """Proxy class for a WordprocessingML ```` element.""" + + def __init__(self, tbl: CT_Tbl, parent: t.ProvidesStoryPart): + super(Table, self).__init__(parent) + self._element = tbl + self._tbl = tbl + + def add_column(self, width: Length): + """Return a |_Column| object of `width`, newly added rightmost to the table.""" + tblGrid = self._tbl.tblGrid + gridCol = tblGrid.add_gridCol() + gridCol.w = width + for tr in self._tbl.tr_lst: + tc = tr.add_tc() + tc.width = width + return _Column(gridCol, self) + + def add_row(self): + """Return a |_Row| instance, newly added bottom-most to the table.""" + tbl = self._tbl + tr = tbl.add_tr() + for gridCol in tbl.tblGrid.gridCol_lst: + tc = tr.add_tc() + if gridCol.w is not None: + tc.width = gridCol.w + return _Row(tr, self) + + @property + def alignment(self) -> WD_TABLE_ALIGNMENT | None: + """Read/write. + + A member of :ref:`WdRowAlignment` or None, specifying the positioning of this + table between the page margins. |None| if no setting is specified, causing the + effective value to be inherited from the style hierarchy. + """ + return self._tblPr.alignment + + @alignment.setter + def alignment(self, value: WD_TABLE_ALIGNMENT | None): + self._tblPr.alignment = value + + @property + def autofit(self) -> bool: + """|True| if column widths can be automatically adjusted to improve the fit of + cell contents. + + |False| if table layout is fixed. Column widths are adjusted in either case if + total column width exceeds page width. Read/write boolean. + """ + return self._tblPr.autofit + + @autofit.setter + def autofit(self, value: bool): + self._tblPr.autofit = value + + def cell(self, row_idx: int, col_idx: int) -> _Cell: + """|_Cell| at `row_idx`, `col_idx` intersection. + + (0, 0) is the top, left-most cell. + """ + cell_idx = col_idx + (row_idx * self._column_count) + return self._cells[cell_idx] + + def column_cells(self, column_idx: int) -> list[_Cell]: + """Sequence of cells in the column at `column_idx` in this table.""" + cells = self._cells + idxs = range(column_idx, len(cells), self._column_count) + return [cells[idx] for idx in idxs] + + @lazyproperty + def columns(self): + """|_Columns| instance representing the sequence of columns in this table.""" + return _Columns(self._tbl, self) + + def row_cells(self, row_idx: int) -> list[_Cell]: + """DEPRECATED: Use `table.rows[row_idx].cells` instead. + + Sequence of cells in the row at `row_idx` in this table. + """ + column_count = self._column_count + start = row_idx * column_count + end = start + column_count + return self._cells[start:end] + + @lazyproperty + def rows(self) -> _Rows: + """|_Rows| instance containing the sequence of rows in this table.""" + return _Rows(self._tbl, self) + + @property + def style(self) -> _TableStyle | None: + """|_TableStyle| object representing the style applied to this table. + + Read/write. The default table style for the document (often `Normal Table`) is + returned if the table has no directly-applied style. Assigning |None| to this + property removes any directly-applied table style causing it to inherit the + default table style of the document. + + Note that the style name of a table style differs slightly from that displayed + in the user interface; a hyphen, if it appears, must be removed. For example, + `Light Shading - Accent 1` becomes `Light Shading Accent 1`. + """ + style_id = self._tbl.tblStyle_val + return cast("_TableStyle | None", self.part.get_style(style_id, WD_STYLE_TYPE.TABLE)) + + @style.setter + def style(self, style_or_name: _TableStyle | str | None): + style_id = self.part.get_style_id(style_or_name, WD_STYLE_TYPE.TABLE) + self._tbl.tblStyle_val = style_id + + @property + def table(self): + """Provide child objects with reference to the |Table| object they belong to, + without them having to know their direct parent is a |Table| object. + + This is the terminus of a series of `parent._table` calls from an arbitrary + child through its ancestors. + """ + return self + + @property + def table_direction(self) -> WD_TABLE_DIRECTION | None: + """Member of :ref:`WdTableDirection` indicating cell-ordering direction. + + For example: `WD_TABLE_DIRECTION.LTR`. |None| indicates the value is inherited + from the style hierarchy. + """ + return cast("WD_TABLE_DIRECTION | None", self._tbl.bidiVisual_val) + + @table_direction.setter + def table_direction(self, value: WD_TABLE_DIRECTION | None): + self._element.bidiVisual_val = value + + @property + def _cells(self) -> list[_Cell]: + """A sequence of |_Cell| objects, one for each cell of the layout grid. + + If the table contains a span, one or more |_Cell| object references are + repeated. + """ + col_count = self._column_count + cells: list[_Cell] = [] + for tc in self._tbl.iter_tcs(): + for grid_span_idx in range(tc.grid_span): + if tc.vMerge == ST_Merge.CONTINUE: + cells.append(cells[-col_count]) + elif grid_span_idx > 0: + cells.append(cells[-1]) + else: + cells.append(_Cell(tc, self)) + return cells + + @property + def _column_count(self): + """The number of grid columns in this table.""" + return self._tbl.col_count + + @property + def _tblPr(self) -> CT_TblPr: + return self._tbl.tblPr + + +class _Cell(BlockItemContainer): + """Table cell.""" + + def __init__(self, tc: CT_Tc, parent: TableParent): + super(_Cell, self).__init__(tc, cast("t.ProvidesStoryPart", parent)) + self._parent = parent + self._tc = self._element = tc + + def add_paragraph(self, text: str = "", style: str | ParagraphStyle | None = None): + """Return a paragraph newly added to the end of the content in this cell. + + If present, `text` is added to the paragraph in a single run. If specified, the + paragraph style `style` is applied. If `style` is not specified or is |None|, + the result is as though the 'Normal' style was applied. Note that the formatting + of text in a cell can be influenced by the table style. `text` can contain tab + (``\\t``) characters, which are converted to the appropriate XML form for a tab. + `text` can also include newline (``\\n``) or carriage return (``\\r``) + characters, each of which is converted to a line break. + """ + return super(_Cell, self).add_paragraph(text, style) + + def add_table( # pyright: ignore[reportIncompatibleMethodOverride] + self, rows: int, cols: int + ) -> Table: + """Return a table newly added to this cell after any existing cell content. + + The new table will have `rows` rows and `cols` columns. + + An empty paragraph is added after the table because Word requires a paragraph + element as the last element in every cell. + """ + width = self.width if self.width is not None else Inches(1) + table = super(_Cell, self).add_table(rows, cols, width) + self.add_paragraph() + return table + + @property + def grid_span(self) -> int: + """Number of layout-grid cells this cell spans horizontally. + + A "normal" cell has a grid-span of 1. A horizontally merged cell has a grid-span of 2 or + more. + """ + return self._tc.grid_span + + def merge(self, other_cell: _Cell): + """Return a merged cell created by spanning the rectangular region having this + cell and `other_cell` as diagonal corners. + + Raises |InvalidSpanError| if the cells do not define a rectangular region. + """ + tc, tc_2 = self._tc, other_cell._tc + merged_tc = tc.merge(tc_2) + return _Cell(merged_tc, self._parent) + + @property + def paragraphs(self): + """List of paragraphs in the cell. + + A table cell is required to contain at least one block-level element and end + with a paragraph. By default, a new cell contains a single paragraph. Read-only + """ + return super(_Cell, self).paragraphs + + @property + def tables(self): + """List of tables in the cell, in the order they appear. + + Read-only. + """ + return super(_Cell, self).tables + + @property + def text(self) -> str: + """The entire contents of this cell as a string of text. + + Assigning a string to this property replaces all existing content with a single + paragraph containing the assigned text in a single run. + """ + return "\n".join(p.text for p in self.paragraphs) + + @text.setter + def text(self, text: str): + """Write-only. + + Set entire contents of cell to the string `text`. Any existing content or + revisions are replaced. + """ + tc = self._tc + tc.clear_content() + p = tc.add_p() + r = p.add_r() + r.text = text + + @property + def vertical_alignment(self): + """Member of :ref:`WdCellVerticalAlignment` or None. + + A value of |None| indicates vertical alignment for this cell is inherited. + Assigning |None| causes any explicitly defined vertical alignment to be removed, + restoring inheritance. + """ + tcPr = self._element.tcPr + if tcPr is None: + return None + return tcPr.vAlign_val + + @vertical_alignment.setter + def vertical_alignment(self, value: WD_CELL_VERTICAL_ALIGNMENT | None): + tcPr = self._element.get_or_add_tcPr() + tcPr.vAlign_val = value + + @property + def width(self): + """The width of this cell in EMU, or |None| if no explicit width is set.""" + return self._tc.width + + @width.setter + def width(self, value: Length): + self._tc.width = value + + +class _Column(Parented): + """Table column.""" + + def __init__(self, gridCol: CT_TblGridCol, parent: TableParent): + super(_Column, self).__init__(parent) + self._parent = parent + self._gridCol = gridCol + + @property + def cells(self) -> tuple[_Cell, ...]: + """Sequence of |_Cell| instances corresponding to cells in this column.""" + return tuple(self.table.column_cells(self._index)) + + @property + def table(self) -> Table: + """Reference to the |Table| object this column belongs to.""" + return self._parent.table + + @property + def width(self) -> Length | None: + """The width of this column in EMU, or |None| if no explicit width is set.""" + return self._gridCol.w + + @width.setter + def width(self, value: Length | None): + self._gridCol.w = value + + @property + def _index(self): + """Index of this column in its table, starting from zero.""" + return self._gridCol.gridCol_idx + + +class _Columns(Parented): + """Sequence of |_Column| instances corresponding to the columns in a table. + + Supports ``len()``, iteration and indexed access. + """ + + def __init__(self, tbl: CT_Tbl, parent: TableParent): + super(_Columns, self).__init__(parent) + self._parent = parent + self._tbl = tbl + + def __getitem__(self, idx: int): + """Provide indexed access, e.g. 'columns[0]'.""" + try: + gridCol = self._gridCol_lst[idx] + except IndexError: + msg = "column index [%d] is out of range" % idx + raise IndexError(msg) + return _Column(gridCol, self) + + def __iter__(self): + for gridCol in self._gridCol_lst: + yield _Column(gridCol, self) + + def __len__(self): + return len(self._gridCol_lst) + + @property + def table(self) -> Table: + """Reference to the |Table| object this column collection belongs to.""" + return self._parent.table + + @property + def _gridCol_lst(self): + """Sequence containing ```` elements for this table, each + representing a table column.""" + tblGrid = self._tbl.tblGrid + return tblGrid.gridCol_lst + + +class _Row(Parented): + """Table row.""" + + def __init__(self, tr: CT_Row, parent: TableParent): + super(_Row, self).__init__(parent) + self._parent = parent + self._tr = self._element = tr + + @property + def cells(self) -> tuple[_Cell, ...]: + """Sequence of |_Cell| instances corresponding to cells in this row. + + Note that Word allows table rows to start later than the first column and end before the + last column. + + - Only cells actually present are included in the return value. + - This implies the length of this cell sequence may differ between rows of the same table. + - If you are reading the cells from each row to form a rectangular "matrix" data structure + of the table cell values, you will need to account for empty leading and/or trailing + layout-grid positions using `.grid_cols_before` and `.grid_cols_after`. + + """ + + def iter_tc_cells(tc: CT_Tc) -> Iterator[_Cell]: + """Generate a cell object for each layout-grid cell in `tc`. + + In particular, a `` element with a horizontal "span" with generate the same cell + multiple times, one for each grid-cell being spanned. This approximates a row in a + "uniform" table, where each row has a cell for each column in the table. + """ + # -- a cell comprising the second or later row of a vertical span is indicated by + # -- tc.vMerge="continue" (the default value of the `w:vMerge` attribute, when it is + # -- present in the XML). The `w:tc` element at the same grid-offset in the prior row + # -- is guaranteed to be the same width (gridSpan). So we can delegate content + # -- discovery to that prior-row `w:tc` element (recursively) until we arrive at the + # -- "root" cell -- for the vertical span. + if tc.vMerge == "continue": + yield from iter_tc_cells(tc._tc_above) # pyright: ignore[reportPrivateUsage] + return + + # -- Otherwise, vMerge is either "restart" or None, meaning this `tc` holds the actual + # -- content of the cell (whether it is vertically merged or not). + cell = _Cell(tc, self.table) + for _ in range(tc.grid_span): + yield cell + + def _iter_row_cells() -> Iterator[_Cell]: + """Generate `_Cell` instance for each populated layout-grid cell in this row.""" + for tc in self._tr.tc_lst: + yield from iter_tc_cells(tc) + + return tuple(_iter_row_cells()) + + @property + def grid_cols_after(self) -> int: + """Count of unpopulated grid-columns after the last cell in this row. + + Word allows a row to "end early", meaning that one or more cells are not present at the + end of that row. + + Note these are not simply "empty" cells. The renderer reads this value and "skips" this + many columns after drawing the last cell. + + Note this also implies that not all rows are guaranteed to have the same number of cells, + e.g. `_Row.cells` could have length `n` for one row and `n - m` for the next row in the same + table. Visually this appears as a column (at the beginning or end, not in the middle) with + one or more cells missing. + """ + return self._tr.grid_after + + @property + def grid_cols_before(self) -> int: + """Count of unpopulated grid-columns before the first cell in this row. + + Word allows a row to "start late", meaning that one or more cells are not present at the + beginning of that row. + + Note these are not simply "empty" cells. The renderer reads this value and skips forward to + the table layout-grid position of the first cell in this row; the renderer "skips" this many + columns before drawing the first cell. + + Note this also implies that not all rows are guaranteed to have the same number of cells, + e.g. `_Row.cells` could have length `n` for one row and `n - m` for the next row in the same + table. + """ + return self._tr.grid_before + + @property + def height(self) -> Length | None: + """Return a |Length| object representing the height of this cell, or |None| if + no explicit height is set.""" + return self._tr.trHeight_val + + @height.setter + def height(self, value: Length | None): + self._tr.trHeight_val = value + + @property + def height_rule(self) -> WD_ROW_HEIGHT_RULE | None: + """Return the height rule of this cell as a member of the :ref:`WdRowHeightRule`. + + This value is |None| if no explicit height_rule is set. + """ + return self._tr.trHeight_hRule + + @height_rule.setter + def height_rule(self, value: WD_ROW_HEIGHT_RULE | None): + self._tr.trHeight_hRule = value + + @property + def table(self) -> Table: + """Reference to the |Table| object this row belongs to.""" + return self._parent.table + + @property + def _index(self) -> int: + """Index of this row in its table, starting from zero.""" + return self._tr.tr_idx + + +class _Rows(Parented): + """Sequence of |_Row| objects corresponding to the rows in a table. + + Supports ``len()``, iteration, indexed access, and slicing. + """ + + def __init__(self, tbl: CT_Tbl, parent: TableParent): + super(_Rows, self).__init__(parent) + self._parent = parent + self._tbl = tbl + + @overload + def __getitem__(self, idx: int) -> _Row: ... + + @overload + def __getitem__(self, idx: slice) -> list[_Row]: ... + + def __getitem__(self, idx: int | slice) -> _Row | list[_Row]: + """Provide indexed access, (e.g. `rows[0]` or `rows[1:3]`)""" + return list(self)[idx] + + def __iter__(self): + return (_Row(tr, self) for tr in self._tbl.tr_lst) + + def __len__(self): + return len(self._tbl.tr_lst) + + @property + def table(self) -> Table: + """Reference to the |Table| object this row collection belongs to.""" + return self._parent.table diff --git a/src/docx/templates/default-comments.xml b/src/docx/templates/default-comments.xml new file mode 100644 index 00000000..2a36ca98 --- /dev/null +++ b/src/docx/templates/default-comments.xml @@ -0,0 +1,12 @@ + + diff --git a/docx/templates/default-docx-template/[Content_Types].xml b/src/docx/templates/default-docx-template/[Content_Types].xml similarity index 100% rename from docx/templates/default-docx-template/[Content_Types].xml rename to src/docx/templates/default-docx-template/[Content_Types].xml diff --git a/docx/templates/default-docx-template/_rels/.rels b/src/docx/templates/default-docx-template/_rels/.rels similarity index 100% rename from docx/templates/default-docx-template/_rels/.rels rename to src/docx/templates/default-docx-template/_rels/.rels diff --git a/docx/templates/default-docx-template/customXml/_rels/item1.xml.rels b/src/docx/templates/default-docx-template/customXml/_rels/item1.xml.rels similarity index 100% rename from docx/templates/default-docx-template/customXml/_rels/item1.xml.rels rename to src/docx/templates/default-docx-template/customXml/_rels/item1.xml.rels diff --git a/docx/templates/default-docx-template/customXml/item1.xml b/src/docx/templates/default-docx-template/customXml/item1.xml similarity index 100% rename from docx/templates/default-docx-template/customXml/item1.xml rename to src/docx/templates/default-docx-template/customXml/item1.xml diff --git a/docx/templates/default-docx-template/customXml/itemProps1.xml b/src/docx/templates/default-docx-template/customXml/itemProps1.xml similarity index 100% rename from docx/templates/default-docx-template/customXml/itemProps1.xml rename to src/docx/templates/default-docx-template/customXml/itemProps1.xml diff --git a/docx/templates/default-docx-template/docProps/app.xml b/src/docx/templates/default-docx-template/docProps/app.xml similarity index 100% rename from docx/templates/default-docx-template/docProps/app.xml rename to src/docx/templates/default-docx-template/docProps/app.xml diff --git a/docx/templates/default-docx-template/docProps/core.xml b/src/docx/templates/default-docx-template/docProps/core.xml similarity index 100% rename from docx/templates/default-docx-template/docProps/core.xml rename to src/docx/templates/default-docx-template/docProps/core.xml diff --git a/docx/templates/default-docx-template/docProps/thumbnail.jpeg b/src/docx/templates/default-docx-template/docProps/thumbnail.jpeg similarity index 100% rename from docx/templates/default-docx-template/docProps/thumbnail.jpeg rename to src/docx/templates/default-docx-template/docProps/thumbnail.jpeg diff --git a/docx/templates/default-docx-template/word/_rels/document.xml.rels b/src/docx/templates/default-docx-template/word/_rels/document.xml.rels similarity index 100% rename from docx/templates/default-docx-template/word/_rels/document.xml.rels rename to src/docx/templates/default-docx-template/word/_rels/document.xml.rels diff --git a/docx/templates/default-docx-template/word/document.xml b/src/docx/templates/default-docx-template/word/document.xml similarity index 100% rename from docx/templates/default-docx-template/word/document.xml rename to src/docx/templates/default-docx-template/word/document.xml diff --git a/docx/templates/default-docx-template/word/fontTable.xml b/src/docx/templates/default-docx-template/word/fontTable.xml similarity index 100% rename from docx/templates/default-docx-template/word/fontTable.xml rename to src/docx/templates/default-docx-template/word/fontTable.xml diff --git a/docx/templates/default-docx-template/word/numbering.xml b/src/docx/templates/default-docx-template/word/numbering.xml similarity index 100% rename from docx/templates/default-docx-template/word/numbering.xml rename to src/docx/templates/default-docx-template/word/numbering.xml diff --git a/docx/templates/default-docx-template/word/settings.xml b/src/docx/templates/default-docx-template/word/settings.xml similarity index 100% rename from docx/templates/default-docx-template/word/settings.xml rename to src/docx/templates/default-docx-template/word/settings.xml diff --git a/docx/templates/default-docx-template/word/styles.xml b/src/docx/templates/default-docx-template/word/styles.xml similarity index 100% rename from docx/templates/default-docx-template/word/styles.xml rename to src/docx/templates/default-docx-template/word/styles.xml diff --git a/docx/templates/default-docx-template/word/stylesWithEffects.xml b/src/docx/templates/default-docx-template/word/stylesWithEffects.xml similarity index 100% rename from docx/templates/default-docx-template/word/stylesWithEffects.xml rename to src/docx/templates/default-docx-template/word/stylesWithEffects.xml diff --git a/docx/templates/default-docx-template/word/theme/theme1.xml b/src/docx/templates/default-docx-template/word/theme/theme1.xml similarity index 100% rename from docx/templates/default-docx-template/word/theme/theme1.xml rename to src/docx/templates/default-docx-template/word/theme/theme1.xml diff --git a/docx/templates/default-docx-template/word/webSettings.xml b/src/docx/templates/default-docx-template/word/webSettings.xml similarity index 100% rename from docx/templates/default-docx-template/word/webSettings.xml rename to src/docx/templates/default-docx-template/word/webSettings.xml diff --git a/docx/templates/default-footer.xml b/src/docx/templates/default-footer.xml similarity index 100% rename from docx/templates/default-footer.xml rename to src/docx/templates/default-footer.xml diff --git a/docx/templates/default-header.xml b/src/docx/templates/default-header.xml similarity index 100% rename from docx/templates/default-header.xml rename to src/docx/templates/default-header.xml diff --git a/docx/templates/default-numbering.xml b/src/docx/templates/default-numbering.xml similarity index 100% rename from docx/templates/default-numbering.xml rename to src/docx/templates/default-numbering.xml diff --git a/docx/templates/default-settings.xml b/src/docx/templates/default-settings.xml similarity index 100% rename from docx/templates/default-settings.xml rename to src/docx/templates/default-settings.xml diff --git a/docx/templates/default-styles.xml b/src/docx/templates/default-styles.xml similarity index 100% rename from docx/templates/default-styles.xml rename to src/docx/templates/default-styles.xml diff --git a/docx/templates/default.docx b/src/docx/templates/default.docx similarity index 100% rename from docx/templates/default.docx rename to src/docx/templates/default.docx diff --git a/src/docx/text/__init__.py b/src/docx/text/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/docx/text/font.py b/src/docx/text/font.py new file mode 100644 index 00000000..79b0a80b --- /dev/null +++ b/src/docx/text/font.py @@ -0,0 +1,466 @@ +"""Font-related proxy objects.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Any + +from docx.dml.color import ColorFormat +from docx.enum.text import WD_UNDERLINE +from docx.shared import ElementProxy, Emu + +if TYPE_CHECKING: + from docx.enum.text import WD_COLOR_INDEX + from docx.oxml.text.run import CT_R + from docx.shared import Length + + +class Font(ElementProxy): + """Proxy object for parent of a `` element and providing access to + character properties such as font name, font size, bold, and subscript.""" + + def __init__(self, r: CT_R, parent: Any | None = None): + super().__init__(r, parent) + self._element = r + self._r = r + + @property + def all_caps(self) -> bool | None: + """Read/write. + + Causes text in this font to appear in capital letters. + """ + return self._get_bool_prop("caps") + + @all_caps.setter + def all_caps(self, value: bool | None) -> None: + self._set_bool_prop("caps", value) + + @property + def bold(self) -> bool | None: + """Read/write. + + Causes text in this font to appear in bold. + """ + return self._get_bool_prop("b") + + @bold.setter + def bold(self, value: bool | None) -> None: + self._set_bool_prop("b", value) + + @property + def color(self): + """A |ColorFormat| object providing a way to get and set the text color for this + font.""" + return ColorFormat(self._element) + + @property + def complex_script(self) -> bool | None: + """Read/write tri-state value. + + When |True|, causes the characters in the run to be treated as complex script + regardless of their Unicode values. + """ + return self._get_bool_prop("cs") + + @complex_script.setter + def complex_script(self, value: bool | None) -> None: + self._set_bool_prop("cs", value) + + @property + def cs_bold(self) -> bool | None: + """Read/write tri-state value. + + When |True|, causes the complex script characters in the run to be displayed in + bold typeface. + """ + return self._get_bool_prop("bCs") + + @cs_bold.setter + def cs_bold(self, value: bool | None) -> None: + self._set_bool_prop("bCs", value) + + @property + def cs_italic(self) -> bool | None: + """Read/write tri-state value. + + When |True|, causes the complex script characters in the run to be displayed in + italic typeface. + """ + return self._get_bool_prop("iCs") + + @cs_italic.setter + def cs_italic(self, value: bool | None) -> None: + self._set_bool_prop("iCs", value) + + @property + def double_strike(self) -> bool | None: + """Read/write tri-state value. + + When |True|, causes the text in the run to appear with double strikethrough. + """ + return self._get_bool_prop("dstrike") + + @double_strike.setter + def double_strike(self, value: bool | None) -> None: + self._set_bool_prop("dstrike", value) + + @property + def emboss(self) -> bool | None: + """Read/write tri-state value. + + When |True|, causes the text in the run to appear as if raised off the page in + relief. + """ + return self._get_bool_prop("emboss") + + @emboss.setter + def emboss(self, value: bool | None) -> None: + self._set_bool_prop("emboss", value) + + @property + def hidden(self) -> bool | None: + """Read/write tri-state value. + + When |True|, causes the text in the run to be hidden from display, unless + applications settings force hidden text to be shown. + """ + return self._get_bool_prop("vanish") + + @hidden.setter + def hidden(self, value: bool | None) -> None: + self._set_bool_prop("vanish", value) + + @property + def highlight_color(self) -> WD_COLOR_INDEX | None: + """Color of highlighing applied or |None| if not highlighted.""" + rPr = self._element.rPr + if rPr is None: + return None + return rPr.highlight_val + + @highlight_color.setter + def highlight_color(self, value: WD_COLOR_INDEX | None): + rPr = self._element.get_or_add_rPr() + rPr.highlight_val = value + + @property + def italic(self) -> bool | None: + """Read/write tri-state value. + + When |True|, causes the text of the run to appear in italics. |None| indicates + the effective value is inherited from the style hierarchy. + """ + return self._get_bool_prop("i") + + @italic.setter + def italic(self, value: bool | None) -> None: + self._set_bool_prop("i", value) + + @property + def imprint(self) -> bool | None: + """Read/write tri-state value. + + When |True|, causes the text in the run to appear as if pressed into the page. + """ + return self._get_bool_prop("imprint") + + @imprint.setter + def imprint(self, value: bool | None) -> None: + self._set_bool_prop("imprint", value) + + @property + def math(self) -> bool | None: + """Read/write tri-state value. + + When |True|, specifies this run contains WML that should be handled as though it + was Office Open XML Math. + """ + return self._get_bool_prop("oMath") + + @math.setter + def math(self, value: bool | None) -> None: + self._set_bool_prop("oMath", value) + + @property + def name(self) -> str | None: + """The typeface name for this |Font|. + + Causes the text it controls to appear in the named font, if a matching font is + found. |None| indicates the typeface is inherited from the style hierarchy. + + Returns the value of `ascii` font. To access other font settings, use `eastAsia` + or `hAnsi` properties. + """ + rPr = self._element.rPr + if rPr is None: + return None + return rPr.rFonts_ascii + + @name.setter + def name(self, value: dict[str, str | None] | str | None) -> None: + rPr = self._element.get_or_add_rPr() + if isinstance(value, dict): + if "ascii" in value: + rPr.rFonts_ascii = value["ascii"] + if "hAnsi" in value: + rPr.rFonts_hAnsi = value["hAnsi"] + if "eastAsia" in value: + rPr.rFonts_eastAsia = value["eastAsia"] + else: + rPr.rFonts_ascii = value + rPr.rFonts_hAnsi = value + rPr.rFonts_eastAsia = value + + @property + def eastAsia(self) -> str | None: + """The East Asian typeface name for this |Font|.""" + rPr = self._element.rPr + if rPr is None: + return None + return rPr.rFonts_eastAsia + + @eastAsia.setter + def eastAsia(self, value: str | None) -> None: + rPr = self._element.get_or_add_rPr() + rPr.rFonts_eastAsia = value + + @property + def hAnsi(self) -> str | None: + """The high ANSI typeface name for this |Font|.""" + rPr = self._element.rPr + if rPr is None: + return None + return rPr.rFonts_hAnsi + + @hAnsi.setter + def hAnsi(self, value: str | None) -> None: + rPr = self._element.get_or_add_rPr() + rPr.rFonts_hAnsi = value + + @property + def no_proof(self) -> bool | None: + """Read/write tri-state value. + + When |True|, specifies that the contents of this run should not report any + errors when the document is scanned for spelling and grammar. + """ + return self._get_bool_prop("noProof") + + @no_proof.setter + def no_proof(self, value: bool | None) -> None: + self._set_bool_prop("noProof", value) + + @property + def outline(self) -> bool | None: + """Read/write tri-state value. + + When |True| causes the characters in the run to appear as if they have an + outline, by drawing a one pixel wide border around the inside and outside + borders of each character glyph. + """ + return self._get_bool_prop("outline") + + @outline.setter + def outline(self, value: bool | None) -> None: + self._set_bool_prop("outline", value) + + @property + def rtl(self) -> bool | None: + """Read/write tri-state value. + + When |True| causes the text in the run to have right-to-left characteristics. + """ + return self._get_bool_prop("rtl") + + @rtl.setter + def rtl(self, value: bool | None) -> None: + self._set_bool_prop("rtl", value) + + @property + def shadow(self) -> bool | None: + """Read/write tri-state value. + + When |True| causes the text in the run to appear as if each character has a + shadow. + """ + return self._get_bool_prop("shadow") + + @shadow.setter + def shadow(self, value: bool | None) -> None: + self._set_bool_prop("shadow", value) + + @property + def size(self) -> Length | None: + """Font height in English Metric Units (EMU). + + |None| indicates the font size should be inherited from the style hierarchy. + |Length| is a subclass of |int| having properties for convenient conversion into + points or other length units. The :class:`docx.shared.Pt` class allows + convenient specification of point values:: + + >>> font.size = Pt(24) + >>> font.size + 304800 + >>> font.size.pt + 24.0 + + """ + rPr = self._element.rPr + if rPr is None: + return None + return rPr.sz_val + + @size.setter + def size(self, emu: int | Length | None) -> None: + rPr = self._element.get_or_add_rPr() + rPr.sz_val = None if emu is None else Emu(emu) + + @property + def small_caps(self) -> bool | None: + """Read/write tri-state value. + + When |True| causes the lowercase characters in the run to appear as capital + letters two points smaller than the font size specified for the run. + """ + return self._get_bool_prop("smallCaps") + + @small_caps.setter + def small_caps(self, value: bool | None) -> None: + self._set_bool_prop("smallCaps", value) + + @property + def snap_to_grid(self) -> bool | None: + """Read/write tri-state value. + + When |True| causes the run to use the document grid characters per line settings + defined in the docGrid element when laying out the characters in this run. + """ + return self._get_bool_prop("snapToGrid") + + @snap_to_grid.setter + def snap_to_grid(self, value: bool | None) -> None: + self._set_bool_prop("snapToGrid", value) + + @property + def spec_vanish(self) -> bool | None: + """Read/write tri-state value. + + When |True|, specifies that the given run shall always behave as if it is + hidden, even when hidden text is being displayed in the current document. The + property has a very narrow, specialized use related to the table of contents. + Consult the spec (§17.3.2.36) for more details. + """ + return self._get_bool_prop("specVanish") + + @spec_vanish.setter + def spec_vanish(self, value: bool | None) -> None: + self._set_bool_prop("specVanish", value) + + @property + def strike(self) -> bool | None: + """Read/write tri-state value. + + When |True| causes the text in the run to appear with a single horizontal line + through the center of the line. + """ + return self._get_bool_prop("strike") + + @strike.setter + def strike(self, value: bool | None) -> None: + self._set_bool_prop("strike", value) + + @property + def subscript(self) -> bool | None: + """Boolean indicating whether the characters in this |Font| appear as subscript. + + |None| indicates the subscript/subscript value is inherited from the style + hierarchy. + """ + rPr = self._element.rPr + if rPr is None: + return None + return rPr.subscript + + @subscript.setter + def subscript(self, value: bool | None) -> None: + rPr = self._element.get_or_add_rPr() + rPr.subscript = value + + @property + def superscript(self) -> bool | None: + """Boolean indicating whether the characters in this |Font| appear as + superscript. + + |None| indicates the subscript/superscript value is inherited from the style + hierarchy. + """ + rPr = self._element.rPr + if rPr is None: + return None + return rPr.superscript + + @superscript.setter + def superscript(self, value: bool | None) -> None: + rPr = self._element.get_or_add_rPr() + rPr.superscript = value + + @property + def underline(self) -> bool | WD_UNDERLINE | None: + """The underline style for this |Font|. + + The value is one of |None|, |True|, |False|, or a member of :ref:`WdUnderline`. + + |None| indicates the font inherits its underline value from the style hierarchy. + |False| indicates no underline. |True| indicates single underline. The values + from :ref:`WdUnderline` are used to specify other outline styles such as double, + wavy, and dotted. + """ + rPr = self._element.rPr + if rPr is None: + return None + val = rPr.u_val + return ( + None + if val == WD_UNDERLINE.INHERITED + else True + if val == WD_UNDERLINE.SINGLE + else False + if val == WD_UNDERLINE.NONE + else val + ) + + @underline.setter + def underline(self, value: bool | WD_UNDERLINE | None) -> None: + rPr = self._element.get_or_add_rPr() + # -- works fine without these two mappings, but only because True == 1 and + # -- False == 0, which happen to match the mapping for WD_UNDERLINE.SINGLE + # -- and .NONE respectively. + val = ( + WD_UNDERLINE.SINGLE if value is True else WD_UNDERLINE.NONE if value is False else value + ) + rPr.u_val = val + + @property + def web_hidden(self) -> bool | None: + """Read/write tri-state value. + + When |True|, specifies that the contents of this run shall be hidden when the + document is displayed in web page view. + """ + return self._get_bool_prop("webHidden") + + @web_hidden.setter + def web_hidden(self, value: bool | None) -> None: + self._set_bool_prop("webHidden", value) + + def _get_bool_prop(self, name: str) -> bool | None: + """Return the value of boolean child of `w:rPr` having `name`.""" + rPr = self._element.rPr + if rPr is None: + return None + return rPr._get_bool_val(name) # pyright: ignore[reportPrivateUsage] + + def _set_bool_prop(self, name: str, value: bool | None): + """Assign `value` to the boolean child `name` of `w:rPr`.""" + rPr = self._element.get_or_add_rPr() + rPr._set_bool_val(name, value) # pyright: ignore[reportPrivateUsage] diff --git a/src/docx/text/hyperlink.py b/src/docx/text/hyperlink.py new file mode 100644 index 00000000..a23df1c7 --- /dev/null +++ b/src/docx/text/hyperlink.py @@ -0,0 +1,121 @@ +"""Hyperlink-related proxy objects for python-docx, Hyperlink in particular. + +A hyperlink occurs in a paragraph, at the same level as a Run, and a hyperlink itself +contains runs, which is where the visible text of the hyperlink is stored. So it's kind +of in-between, less than a paragraph and more than a run. So it gets its own module. +""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +from docx.shared import Parented +from docx.text.run import Run + +if TYPE_CHECKING: + import docx.types as t + from docx.oxml.text.hyperlink import CT_Hyperlink + + +class Hyperlink(Parented): + """Proxy object wrapping a `` element. + + A hyperlink occurs as a child of a paragraph, at the same level as a Run. A + hyperlink itself contains runs, which is where the visible text of the hyperlink is + stored. + """ + + def __init__(self, hyperlink: CT_Hyperlink, parent: t.ProvidesStoryPart): + super().__init__(parent) + self._parent = parent + self._hyperlink = self._element = hyperlink + + @property + def address(self) -> str: + """The "URL" of the hyperlink (but not necessarily a web link). + + While commonly a web link like "https://google.com" the hyperlink address can + take a variety of forms including "internal links" to bookmarked locations + within the document. When this hyperlink is an internal "jump" to for example a + heading from the table-of-contents (TOC), the address is blank. The bookmark + reference (like "_Toc147925734") is stored in the `.fragment` property. + """ + rId = self._hyperlink.rId + return self._parent.part.rels[rId].target_ref if rId else "" + + @property + def contains_page_break(self) -> bool: + """True when the text of this hyperlink is broken across page boundaries. + + This is not uncommon and can happen for example when the hyperlink text is + multiple words and occurs in the last line of a page. Theoretically, a hyperlink + can contain more than one page break but that would be extremely uncommon in + practice. Still, this value should be understood to mean that "one-or-more" + rendered page breaks are present. + """ + return bool(self._hyperlink.lastRenderedPageBreaks) + + @property + def fragment(self) -> str: + """Reference like `#glossary` at end of URL that refers to a sub-resource. + + Note that this value does not include the fragment-separator character ("#"). + + This value is known as a "named anchor" in an HTML context and "anchor" in the + MS API, but an "anchor" element (``) represents a full hyperlink in HTML so + we avoid confusion by using the more precise RFC 3986 naming "URI fragment". + + These are also used to refer to bookmarks within the same document, in which + case the `.address` value with be blank ("") and this property will hold a + value like "_Toc147925734". + + To reliably get an entire web URL you will need to concatenate this with the + `.address` value, separated by "#" when both are present. Consider using the + `.url` property for that purpose. + + Word sometimes stores a fragment in this property (an XML attribute) and + sometimes with the address, depending on how the URL is inserted, so don't + depend on this field being empty to indicate no fragment is present. + """ + return self._hyperlink.anchor or "" + + @property + def runs(self) -> list[Run]: + """List of |Run| instances in this hyperlink. + + Together these define the visible text of the hyperlink. The text of a hyperlink + is typically contained in a single run will be broken into multiple runs if for + example part of the hyperlink is bold or the text was changed after the document + was saved. + """ + return [Run(r, self._parent) for r in self._hyperlink.r_lst] + + @property + def text(self) -> str: + """String formed by concatenating the text of each run in the hyperlink. + + Tabs and line breaks in the XML are mapped to ``\\t`` and ``\\n`` characters + respectively. Note that rendered page-breaks can occur within a hyperlink but + they are not reflected in this text. + """ + return self._hyperlink.text + + @property + def url(self) -> str: + """Convenience property to get web URLs from hyperlinks that contain them. + + This value is the empty string ("") when there is no address portion, so its + boolean value can also be used to distinguish external URIs from internal "jump" + hyperlinks like those found in a table-of-contents. + + Note that this value may also be a link to a file, so if you only want web-urls + you'll need to check for a protocol prefix like `https://`. + + When both an address and fragment are present, the return value joins the two + separated by the fragment-separator hash ("#"). Otherwise this value is the same + as that of the `.address` property. + """ + address, fragment = self.address, self.fragment + if not address: + return "" + return f"{address}#{fragment}" if fragment else address diff --git a/src/docx/text/pagebreak.py b/src/docx/text/pagebreak.py new file mode 100644 index 00000000..0977ccea --- /dev/null +++ b/src/docx/text/pagebreak.py @@ -0,0 +1,104 @@ +"""Proxy objects related to rendered page-breaks.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +from docx.oxml.text.pagebreak import CT_LastRenderedPageBreak +from docx.shared import Parented + +if TYPE_CHECKING: + import docx.types as t + from docx.text.paragraph import Paragraph + + +class RenderedPageBreak(Parented): + """A page-break inserted by Word during page-layout for print or display purposes. + + This usually does not correspond to a "hard" page-break inserted by the document + author, rather just that Word ran out of room on one page and needed to start + another. The position of these can change depending on the printer and page-size, as + well as margins, etc. They also will change in response to edits, but not until Word + loads and saves the document. + + Note these are never inserted by `python-docx` because it has no rendering function. + These are generally only useful for text-extraction of existing documents when + `python-docx` is being used solely as a document "reader". + + NOTE: a rendered page-break can occur within a hyperlink; consider a multi-word + hyperlink like "excellent Wikipedia article on LLMs" that happens to fall close to + the end of the last line on a page such that the page breaks between "Wikipedia" and + "article". In such a "page-breaks-in-hyperlink" case, THESE METHODS WILL "MOVE" THE + PAGE-BREAK to occur after the hyperlink, such that the entire hyperlink appears in + the paragraph returned by `.preceding_paragraph_fragment`. While this places the + "tail" text of the hyperlink on the "wrong" page, it avoids having two hyperlinks + each with a fragment of the actual text and pointing to the same address. + """ + + def __init__( + self, + lastRenderedPageBreak: CT_LastRenderedPageBreak, + parent: t.ProvidesStoryPart, + ): + super().__init__(parent) + self._element = lastRenderedPageBreak + self._lastRenderedPageBreak = lastRenderedPageBreak + + @property + def preceding_paragraph_fragment(self) -> Paragraph | None: + """A "loose" paragraph containing the content preceding this page-break. + + Compare `.following_paragraph_fragment` as these two are intended to be used + together. + + This value is `None` when no content precedes this page-break. This case is + common and occurs whenever a page breaks on an even paragraph boundary. + Returning `None` for this case avoids "inserting" a non-existent paragraph into + the content stream. Note that content can include DrawingML items like images or + charts. + + Note the returned paragraph *is divorced from the document body*. Any changes + made to it will not be reflected in the document. It is intended to provide a + familiar container (`Paragraph`) to interrogate for the content preceding this + page-break in the paragraph in which it occured. + + Contains the entire hyperlink when this break occurs within a hyperlink. + """ + if self._lastRenderedPageBreak.precedes_all_content: + return None + + from docx.text.paragraph import Paragraph + + return Paragraph(self._lastRenderedPageBreak.preceding_fragment_p, self._parent) + + @property + def following_paragraph_fragment(self) -> Paragraph | None: + """A "loose" paragraph containing the content following this page-break. + + HAS POTENTIALLY SURPRISING BEHAVIORS so read carefully to be sure this is what + you want. This is primarily targeted toward text-extraction use-cases for which + precisely associating text with the page it occurs on is important. + + Compare `.preceding_paragraph_fragment` as these two are intended to be used + together. + + This value is `None` when no content follows this page-break. This case is + unlikely to occur in practice because Word places even-paragraph-boundary + page-breaks on the paragraph *following* the page-break. Still, it is possible + and must be checked for. Returning `None` for this case avoids "inserting" an + extra, non-existent paragraph into the content stream. Note that content can + include DrawingML items like images or charts, not just text. + + The returned paragraph *is divorced from the document body*. Any changes made to + it will not be reflected in the document. It is intended to provide a container + (`Paragraph`) with familiar properties and methods that can be used to + characterize the paragraph content following a mid-paragraph page-break. + + Contains no portion of the hyperlink when this break occurs within a hyperlink. + """ + if self._lastRenderedPageBreak.follows_all_content: + return None + + from docx.text.paragraph import Paragraph + + return Paragraph(self._lastRenderedPageBreak.following_fragment_p, self._parent) diff --git a/src/docx/text/paragraph.py b/src/docx/text/paragraph.py new file mode 100644 index 00000000..234ea66c --- /dev/null +++ b/src/docx/text/paragraph.py @@ -0,0 +1,173 @@ +"""Paragraph-related proxy types.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Iterator, List, cast + +from docx.enum.style import WD_STYLE_TYPE +from docx.oxml.text.run import CT_R +from docx.shared import StoryChild +from docx.styles.style import ParagraphStyle +from docx.text.hyperlink import Hyperlink +from docx.text.pagebreak import RenderedPageBreak +from docx.text.parfmt import ParagraphFormat +from docx.text.run import Run + +if TYPE_CHECKING: + import docx.types as t + from docx.enum.text import WD_PARAGRAPH_ALIGNMENT + from docx.oxml.text.paragraph import CT_P + from docx.styles.style import CharacterStyle + + +class Paragraph(StoryChild): + """Proxy object wrapping a `` element.""" + + def __init__(self, p: CT_P, parent: t.ProvidesStoryPart): + super(Paragraph, self).__init__(parent) + self._p = self._element = p + + def add_run(self, text: str | None = None, style: str | CharacterStyle | None = None) -> Run: + """Append run containing `text` and having character-style `style`. + + `text` can contain tab (``\\t``) characters, which are converted to the + appropriate XML form for a tab. `text` can also include newline (``\\n``) or + carriage return (``\\r``) characters, each of which is converted to a line + break. When `text` is `None`, the new run is empty. + """ + r = self._p.add_r() + run = Run(r, self) + if text: + run.text = text + if style: + run.style = style + return run + + @property + def alignment(self) -> WD_PARAGRAPH_ALIGNMENT | None: + """A member of the :ref:`WdParagraphAlignment` enumeration specifying the + justification setting for this paragraph. + + A value of |None| indicates the paragraph has no directly-applied alignment + value and will inherit its alignment value from its style hierarchy. Assigning + |None| to this property removes any directly-applied alignment value. + """ + return self._p.alignment + + @alignment.setter + def alignment(self, value: WD_PARAGRAPH_ALIGNMENT): + self._p.alignment = value + + def clear(self): + """Return this same paragraph after removing all its content. + + Paragraph-level formatting, such as style, is preserved. + """ + self._p.clear_content() + return self + + @property + def contains_page_break(self) -> bool: + """`True` when one or more rendered page-breaks occur in this paragraph.""" + return bool(self._p.lastRenderedPageBreaks) + + @property + def hyperlinks(self) -> List[Hyperlink]: + """A |Hyperlink| instance for each hyperlink in this paragraph.""" + return [Hyperlink(hyperlink, self) for hyperlink in self._p.hyperlink_lst] + + def insert_paragraph_before( + self, text: str | None = None, style: str | ParagraphStyle | None = None + ) -> Paragraph: + """Return a newly created paragraph, inserted directly before this paragraph. + + If `text` is supplied, the new paragraph contains that text in a single run. If + `style` is provided, that style is assigned to the new paragraph. + """ + paragraph = self._insert_paragraph_before() + if text: + paragraph.add_run(text) + if style is not None: + paragraph.style = style + return paragraph + + def iter_inner_content(self) -> Iterator[Run | Hyperlink]: + """Generate the runs and hyperlinks in this paragraph, in the order they appear. + + The content in a paragraph consists of both runs and hyperlinks. This method + allows accessing each of those separately, in document order, for when the + precise position of the hyperlink within the paragraph text is important. Note + that a hyperlink itself contains runs. + """ + for r_or_hlink in self._p.inner_content_elements: + yield ( + Run(r_or_hlink, self) + if isinstance(r_or_hlink, CT_R) + else Hyperlink(r_or_hlink, self) + ) + + @property + def paragraph_format(self): + """The |ParagraphFormat| object providing access to the formatting properties + for this paragraph, such as line spacing and indentation.""" + return ParagraphFormat(self._element) + + @property + def rendered_page_breaks(self) -> List[RenderedPageBreak]: + """All rendered page-breaks in this paragraph. + + Most often an empty list, sometimes contains one page-break, but can contain + more than one is rare or contrived cases. + """ + return [RenderedPageBreak(lrpb, self) for lrpb in self._p.lastRenderedPageBreaks] + + @property + def runs(self) -> List[Run]: + """Sequence of |Run| instances corresponding to the elements in this + paragraph.""" + return [Run(r, self) for r in self._p.r_lst] + + @property + def style(self) -> ParagraphStyle | None: + """Read/Write. + + |_ParagraphStyle| object representing the style assigned to this paragraph. If + no explicit style is assigned to this paragraph, its value is the default + paragraph style for the document. A paragraph style name can be assigned in lieu + of a paragraph style object. Assigning |None| removes any applied style, making + its effective value the default paragraph style for the document. + """ + style_id = self._p.style + style = self.part.get_style(style_id, WD_STYLE_TYPE.PARAGRAPH) + return cast(ParagraphStyle, style) + + @style.setter + def style(self, style_or_name: str | ParagraphStyle | None): + style_id = self.part.get_style_id(style_or_name, WD_STYLE_TYPE.PARAGRAPH) + self._p.style = style_id + + @property + def text(self) -> str: + """The textual content of this paragraph. + + The text includes the visible-text portion of any hyperlinks in the paragraph. + Tabs and line breaks in the XML are mapped to ``\\t`` and ``\\n`` characters + respectively. + + Assigning text to this property causes all existing paragraph content to be + replaced with a single run containing the assigned text. A ``\\t`` character in + the text is mapped to a ```` element and each ``\\n`` or ``\\r`` + character is mapped to a line break. Paragraph-level formatting, such as style, + is preserved. All run-level formatting, such as bold or italic, is removed. + """ + return self._p.text + + @text.setter + def text(self, text: str | None): + self.clear() + self.add_run(text) + + def _insert_paragraph_before(self): + """Return a newly created paragraph, inserted directly before this paragraph.""" + p = self._p.add_p_before() + return Paragraph(p, self._parent) diff --git a/docx/text/parfmt.py b/src/docx/text/parfmt.py similarity index 53% rename from docx/text/parfmt.py rename to src/docx/text/parfmt.py index 6d921554..ea374373 100644 --- a/docx/text/parfmt.py +++ b/src/docx/text/parfmt.py @@ -1,31 +1,21 @@ -# encoding: utf-8 +"""Paragraph-related proxy types.""" -""" -Paragraph-related proxy types. -""" - -from __future__ import absolute_import, division, print_function, unicode_literals - -from ..enum.text import WD_LINE_SPACING -from ..shared import ElementProxy, Emu, lazyproperty, Length, Pt, Twips -from .tabstops import TabStops +from docx.enum.text import WD_LINE_SPACING +from docx.shared import ElementProxy, Emu, Length, Pt, Twips, lazyproperty +from docx.text.tabstops import TabStops class ParagraphFormat(ElementProxy): - """ - Provides access to paragraph formatting such as justification, - indentation, line spacing, space before and after, and widow/orphan - control. - """ - - __slots__ = ("_tab_stops",) + """Provides access to paragraph formatting such as justification, indentation, line + spacing, space before and after, and widow/orphan control.""" @property def alignment(self): - """ - A member of the :ref:`WdParagraphAlignment` enumeration specifying - the justification setting for this paragraph. A value of |None| - indicates paragraph alignment is inherited from the style hierarchy. + """A member of the :ref:`WdParagraphAlignment` enumeration specifying the + justification setting for this paragraph. + + A value of |None| indicates paragraph alignment is inherited from the style + hierarchy. """ pPr = self._element.pPr if pPr is None: @@ -39,12 +29,12 @@ def alignment(self, value): @property def first_line_indent(self): - """ - |Length| value specifying the relative difference in indentation for - the first line of the paragraph. A positive value causes the first - line to be indented. A negative value produces a hanging indent. - |None| indicates first line indentation is inherited from the style - hierarchy. + """|Length| value specifying the relative difference in indentation for the + first line of the paragraph. + + A positive value causes the first line to be indented. A negative value produces + a hanging indent. |None| indicates first line indentation is inherited from the + style hierarchy. """ pPr = self._element.pPr if pPr is None: @@ -58,10 +48,10 @@ def first_line_indent(self, value): @property def keep_together(self): - """ - |True| if the paragraph should be kept "in one piece" and not broken - across a page boundary when the document is rendered. |None| - indicates its effective value is inherited from the style hierarchy. + """|True| if the paragraph should be kept "in one piece" and not broken across a + page boundary when the document is rendered. + + |None| indicates its effective value is inherited from the style hierarchy. """ pPr = self._element.pPr if pPr is None: @@ -74,12 +64,12 @@ def keep_together(self, value): @property def keep_with_next(self): - """ - |True| if the paragraph should be kept on the same page as the - subsequent paragraph when the document is rendered. For example, this - property could be used to keep a section heading on the same page as - its first paragraph. |None| indicates its effective value is - inherited from the style hierarchy. + """|True| if the paragraph should be kept on the same page as the subsequent + paragraph when the document is rendered. + + For example, this property could be used to keep a section heading on the same + page as its first paragraph. |None| indicates its effective value is inherited + from the style hierarchy. """ pPr = self._element.pPr if pPr is None: @@ -92,11 +82,12 @@ def keep_with_next(self, value): @property def left_indent(self): - """ - |Length| value specifying the space between the left margin and the - left side of the paragraph. |None| indicates the left indent value is - inherited from the style hierarchy. Use an |Inches| value object as - a convenient way to apply indentation in units of inches. + """|Length| value specifying the space between the left margin and the left side + of the paragraph. + + |None| indicates the left indent value is inherited from the style hierarchy. + Use an |Inches| value object as a convenient way to apply indentation in units + of inches. """ pPr = self._element.pPr if pPr is None: @@ -110,15 +101,15 @@ def left_indent(self, value): @property def line_spacing(self): - """ - |float| or |Length| value specifying the space between baselines in - successive lines of the paragraph. A value of |None| indicates line - spacing is inherited from the style hierarchy. A float value, e.g. - ``2.0`` or ``1.75``, indicates spacing is applied in multiples of - line heights. A |Length| value such as ``Pt(12)`` indicates spacing - is a fixed height. The |Pt| value class is a convenient way to apply - line spacing in units of points. Assigning |None| resets line spacing - to inherit from the style hierarchy. + """|float| or |Length| value specifying the space between baselines in + successive lines of the paragraph. + + A value of |None| indicates line spacing is inherited from the style hierarchy. + A float value, e.g. ``2.0`` or ``1.75``, indicates spacing is applied in + multiples of line heights. A |Length| value such as ``Pt(12)`` indicates spacing + is a fixed height. The |Pt| value class is a convenient way to apply line + spacing in units of points. Assigning |None| resets line spacing to inherit from + the style hierarchy. """ pPr = self._element.pPr if pPr is None: @@ -141,12 +132,12 @@ def line_spacing(self, value): @property def line_spacing_rule(self): - """ - A member of the :ref:`WdLineSpacing` enumeration indicating how the - value of :attr:`line_spacing` should be interpreted. Assigning any of - the :ref:`WdLineSpacing` members :attr:`SINGLE`, :attr:`DOUBLE`, or - :attr:`ONE_POINT_FIVE` will cause the value of :attr:`line_spacing` - to be updated to produce the corresponding line spacing. + """A member of the :ref:`WdLineSpacing` enumeration indicating how the value of + :attr:`line_spacing` should be interpreted. + + Assigning any of the :ref:`WdLineSpacing` members :attr:`SINGLE`, + :attr:`DOUBLE`, or :attr:`ONE_POINT_FIVE` will cause the value of + :attr:`line_spacing` to be updated to produce the corresponding line spacing. """ pPr = self._element.pPr if pPr is None: @@ -170,10 +161,10 @@ def line_spacing_rule(self, value): @property def page_break_before(self): - """ - |True| if the paragraph should appear at the top of the page - following the prior paragraph. |None| indicates its effective value - is inherited from the style hierarchy. + """|True| if the paragraph should appear at the top of the page following the + prior paragraph. + + |None| indicates its effective value is inherited from the style hierarchy. """ pPr = self._element.pPr if pPr is None: @@ -186,11 +177,12 @@ def page_break_before(self, value): @property def right_indent(self): - """ - |Length| value specifying the space between the right margin and the - right side of the paragraph. |None| indicates the right indent value - is inherited from the style hierarchy. Use a |Cm| value object as - a convenient way to apply indentation in units of centimeters. + """|Length| value specifying the space between the right margin and the right + side of the paragraph. + + |None| indicates the right indent value is inherited from the style hierarchy. + Use a |Cm| value object as a convenient way to apply indentation in units of + centimeters. """ pPr = self._element.pPr if pPr is None: @@ -204,13 +196,12 @@ def right_indent(self, value): @property def space_after(self): - """ - |Length| value specifying the spacing to appear between this - paragraph and the subsequent paragraph. |None| indicates this value - is inherited from the style hierarchy. |Length| objects provide - convenience properties, such as :attr:`~.Length.pt` and - :attr:`~.Length.inches`, that allow easy conversion to various length - units. + """|Length| value specifying the spacing to appear between this paragraph and + the subsequent paragraph. + + |None| indicates this value is inherited from the style hierarchy. |Length| + objects provide convenience properties, such as :attr:`~.Length.pt` and + :attr:`~.Length.inches`, that allow easy conversion to various length units. """ pPr = self._element.pPr if pPr is None: @@ -223,13 +214,12 @@ def space_after(self, value): @property def space_before(self): - """ - |Length| value specifying the spacing to appear between this - paragraph and the prior paragraph. |None| indicates this value is - inherited from the style hierarchy. |Length| objects provide - convenience properties, such as :attr:`~.Length.pt` and - :attr:`~.Length.cm`, that allow easy conversion to various length - units. + """|Length| value specifying the spacing to appear between this paragraph and + the prior paragraph. + + |None| indicates this value is inherited from the style hierarchy. |Length| + objects provide convenience properties, such as :attr:`~.Length.pt` and + :attr:`~.Length.cm`, that allow easy conversion to various length units. """ pPr = self._element.pPr if pPr is None: @@ -242,20 +232,17 @@ def space_before(self, value): @lazyproperty def tab_stops(self): - """ - |TabStops| object providing access to the tab stops defined for this - paragraph format. - """ + """|TabStops| object providing access to the tab stops defined for this + paragraph format.""" pPr = self._element.get_or_add_pPr() return TabStops(pPr) @property def widow_control(self): - """ - |True| if the first and last lines in the paragraph remain on the - same page as the rest of the paragraph when Word repaginates the - document. |None| indicates its effective value is inherited from the - style hierarchy. + """|True| if the first and last lines in the paragraph remain on the same page + as the rest of the paragraph when Word repaginates the document. + + |None| indicates its effective value is inherited from the style hierarchy. """ pPr = self._element.pPr if pPr is None: @@ -268,12 +255,12 @@ def widow_control(self, value): @staticmethod def _line_spacing(spacing_line, spacing_lineRule): - """ - Return the line spacing value calculated from the combination of - *spacing_line* and *spacing_lineRule*. Returns a |float| number of - lines when *spacing_lineRule* is ``WD_LINE_SPACING.MULTIPLE``, - otherwise a |Length| object of absolute line height is returned. - Returns |None| when *spacing_line* is |None|. + """Return the line spacing value calculated from the combination of + `spacing_line` and `spacing_lineRule`. + + Returns a |float| number of lines when `spacing_lineRule` is + ``WD_LINE_SPACING.MULTIPLE``, otherwise a |Length| object of absolute line + height is returned. Returns |None| when `spacing_line` is |None|. """ if spacing_line is None: return None @@ -283,11 +270,11 @@ def _line_spacing(spacing_line, spacing_lineRule): @staticmethod def _line_spacing_rule(line, lineRule): - """ - Return the line spacing rule value calculated from the combination of - *line* and *lineRule*. Returns special members of the - :ref:`WdLineSpacing` enumeration when line spacing is single, double, - or 1.5 lines. + """Return the line spacing rule value calculated from the combination of `line` + and `lineRule`. + + Returns special members of the :ref:`WdLineSpacing` enumeration when line + spacing is single, double, or 1.5 lines. """ if lineRule == WD_LINE_SPACING.MULTIPLE: if line == Twips(240): diff --git a/src/docx/text/run.py b/src/docx/text/run.py new file mode 100644 index 00000000..4adf956e --- /dev/null +++ b/src/docx/text/run.py @@ -0,0 +1,272 @@ +"""Run-related proxy objects for python-docx, Run in particular.""" + +from __future__ import annotations + +from typing import IO, TYPE_CHECKING, Iterator, cast + +from docx.drawing import Drawing +from docx.enum.style import WD_STYLE_TYPE +from docx.enum.text import WD_BREAK +from docx.oxml.drawing import CT_Drawing +from docx.oxml.text.pagebreak import CT_LastRenderedPageBreak +from docx.shape import InlineShape +from docx.shared import StoryChild +from docx.styles.style import CharacterStyle +from docx.text.font import Font +from docx.text.pagebreak import RenderedPageBreak + +if TYPE_CHECKING: + import docx.types as t + from docx.enum.text import WD_UNDERLINE + from docx.oxml.text.run import CT_R, CT_Text + from docx.shared import Length + + +class Run(StoryChild): + """Proxy object wrapping `` element. + + Several of the properties on Run take a tri-state value, |True|, |False|, or |None|. + |True| and |False| correspond to on and off respectively. |None| indicates the + property is not specified directly on the run and its effective value is taken from + the style hierarchy. + """ + + def __init__(self, r: CT_R, parent: t.ProvidesStoryPart): + super().__init__(parent) + self._r = self._element = self.element = r + + def add_break(self, break_type: WD_BREAK = WD_BREAK.LINE): + """Add a break element of `break_type` to this run. + + `break_type` can take the values `WD_BREAK.LINE`, `WD_BREAK.PAGE`, and + `WD_BREAK.COLUMN` where `WD_BREAK` is imported from `docx.enum.text`. + `break_type` defaults to `WD_BREAK.LINE`. + """ + type_, clear = { + WD_BREAK.LINE: (None, None), + WD_BREAK.PAGE: ("page", None), + WD_BREAK.COLUMN: ("column", None), + WD_BREAK.LINE_CLEAR_LEFT: ("textWrapping", "left"), + WD_BREAK.LINE_CLEAR_RIGHT: ("textWrapping", "right"), + WD_BREAK.LINE_CLEAR_ALL: ("textWrapping", "all"), + }[break_type] + br = self._r.add_br() + if type_ is not None: + br.type = type_ + if clear is not None: + br.clear = clear + + def add_picture( + self, + image_path_or_stream: str | IO[bytes], + width: int | Length | None = None, + height: int | Length | None = None, + ) -> InlineShape: + """Return |InlineShape| containing image identified by `image_path_or_stream`. + + The picture is added to the end of this run. + + `image_path_or_stream` can be a path (a string) or a file-like object containing + a binary image. + + If neither width nor height is specified, the picture appears at + its native size. If only one is specified, it is used to compute a scaling + factor that is then applied to the unspecified dimension, preserving the aspect + ratio of the image. The native size of the picture is calculated using the dots- + per-inch (dpi) value specified in the image file, defaulting to 72 dpi if no + value is specified, as is often the case. + """ + inline = self.part.new_pic_inline(image_path_or_stream, width, height) + self._r.add_drawing(inline) + return InlineShape(inline) + + def add_float_picture( + self, + image_path_or_stream: str | IO[bytes], + width: int | Length | None = None, + height: int | Length | None = None, + pos_x: int | Length = 0, + pos_y: int | Length = 0, + ): + """Add float picture at fixed position `pos_x` and `pos_y` to the top-left + point of page. + """ + anchor = self.part.new_pic_anchor(image_path_or_stream, width, height, pos_x, pos_y) + self._r.add_drawing(anchor) + return anchor + + def add_tab(self) -> None: + """Add a ```` element at the end of the run, which Word interprets as a + tab character.""" + self._r.add_tab() + + def add_text(self, text: str): + """Returns a newly appended |_Text| object (corresponding to a new ```` + child element) to the run, containing `text`. + + Compare with the possibly more friendly approach of assigning text to the + :attr:`Run.text` property. + """ + t = self._r.add_t(text) + return _Text(t) + + @property + def bold(self) -> bool | None: + """Read/write tri-state value. + + When |True|, causes the text of the run to appear in bold face. When |False|, + the text unconditionally appears non-bold. When |None| the bold setting for this + run is inherited from the style hierarchy. + """ + return self.font.bold + + @bold.setter + def bold(self, value: bool | None): + self.font.bold = value + + def clear(self): + """Return reference to this run after removing all its content. + + All run formatting is preserved. + """ + self._r.clear_content() + return self + + @property + def contains_page_break(self) -> bool: + """`True` when one or more rendered page-breaks occur in this run. + + Note that "hard" page-breaks inserted by the author are not included. A hard + page-break gives rise to a rendered page-break in the right position so if those + were included that page-break would be "double-counted". + + It would be very rare for multiple rendered page-breaks to occur in a single + run, but it is possible. + """ + return bool(self._r.lastRenderedPageBreaks) + + @property + def font(self) -> Font: + """The |Font| object providing access to the character formatting properties for + this run, such as font name and size.""" + return Font(self._element) + + @property + def italic(self) -> bool | None: + """Read/write tri-state value. + + When |True|, causes the text of the run to appear in italics. When |False|, the + text unconditionally appears non-italic. When |None| the italic setting for this + run is inherited from the style hierarchy. + """ + return self.font.italic + + @italic.setter + def italic(self, value: bool | None): + self.font.italic = value + + def iter_inner_content(self) -> Iterator[str | Drawing | RenderedPageBreak]: + """Generate the content-items in this run in the order they appear. + + NOTE: only content-types currently supported by `python-docx` are generated. In + this version, that is text and rendered page-breaks. Drawing is included but + currently only provides access to its XML element (CT_Drawing) on its + `._drawing` attribute. `Drawing` attributes and methods may be expanded in + future releases. + + There are a number of element-types that can appear inside a run, but most of + those (w:br, w:cr, w:noBreakHyphen, w:t, w:tab) have a clear plain-text + equivalent. Any contiguous range of such elements is generated as a single + `str`. Rendered page-break and drawing elements are generated individually. Any + other elements are ignored. + """ + for item in self._r.inner_content_items: + if isinstance(item, str): + yield item + elif isinstance(item, CT_LastRenderedPageBreak): + yield RenderedPageBreak(item, self) + elif isinstance(item, CT_Drawing): # pyright: ignore[reportUnnecessaryIsInstance] + yield Drawing(item, self) + + def mark_comment_range(self, last_run: Run, comment_id: int) -> None: + """Mark the range of runs from this run to `last_run` (inclusive) as belonging to a comment. + + `comment_id` identfies the comment that references this range. + """ + # -- insert `w:commentRangeStart` with `comment_id` before this (first) run -- + self._r.insert_comment_range_start_above(comment_id) + + # -- insert `w:commentRangeEnd` and `w:commentReference` run with `comment_id` after + # -- `last_run` + last_run._r.insert_comment_range_end_and_reference_below(comment_id) + + @property + def style(self) -> CharacterStyle: + """Read/write. + + A |CharacterStyle| object representing the character style applied to this run. + The default character style for the document (often `Default Character Font`) is + returned if the run has no directly-applied character style. Setting this + property to |None| removes any directly-applied character style. + """ + style_id = self._r.style + return cast(CharacterStyle, self.part.get_style(style_id, WD_STYLE_TYPE.CHARACTER)) + + @style.setter + def style(self, style_or_name: str | CharacterStyle | None): + style_id = self.part.get_style_id(style_or_name, WD_STYLE_TYPE.CHARACTER) + self._r.style = style_id + + @property + def text(self) -> str: + """String formed by concatenating the text equivalent of each run. + + Each `` element adds the text characters it contains. A `` element + adds a `\\t` character. A `` or `` element each add a `\\n` + character. Note that a `` element can indicate a page break or column + break as well as a line break. Only line-break `` elements translate to + a `\\n` character. Others are ignored. All other content child elements, such as + ``, are ignored. + + Assigning text to this property has the reverse effect, translating each `\\t` + character to a `` element and each `\\n` or `\\r` character to a + `` element. Any existing run content is replaced. Run formatting is + preserved. + """ + return self._r.text + + @text.setter + def text(self, text: str): + self._r.text = text + + @property + def underline(self) -> bool | WD_UNDERLINE | None: + """The underline style for this |Run|. + + Value is one of |None|, |True|, |False|, or a member of :ref:`WdUnderline`. + + A value of |None| indicates the run has no directly-applied underline value and + so will inherit the underline value of its containing paragraph. Assigning + |None| to this property removes any directly-applied underline value. + + A value of |False| indicates a directly-applied setting of no underline, + overriding any inherited value. + + A value of |True| indicates single underline. + + The values from :ref:`WdUnderline` are used to specify other outline styles such + as double, wavy, and dotted. + """ + return self.font.underline + + @underline.setter + def underline(self, value: bool | WD_UNDERLINE | None): + self.font.underline = value + + +class _Text: + """Proxy object wrapping `` element.""" + + def __init__(self, t_elm: CT_Text): + super(_Text, self).__init__() + self._t = t_elm diff --git a/src/docx/text/tabstops.py b/src/docx/text/tabstops.py new file mode 100644 index 00000000..0f8c22c9 --- /dev/null +++ b/src/docx/text/tabstops.py @@ -0,0 +1,123 @@ +"""Tabstop-related proxy types.""" + +from docx.enum.text import WD_TAB_ALIGNMENT, WD_TAB_LEADER +from docx.shared import ElementProxy + + +class TabStops(ElementProxy): + """A sequence of |TabStop| objects providing access to the tab stops of a paragraph + or paragraph style. + + Supports iteration, indexed access, del, and len(). It is accesed using the + :attr:`~.ParagraphFormat.tab_stops` property of ParagraphFormat; it is not intended + to be constructed directly. + """ + + def __init__(self, element): + super(TabStops, self).__init__(element, None) + self._pPr = element + + def __delitem__(self, idx): + """Remove the tab at offset `idx` in this sequence.""" + tabs = self._pPr.tabs + try: + tabs.remove(tabs[idx]) + except (AttributeError, IndexError): + raise IndexError("tab index out of range") + + if len(tabs) == 0: + self._pPr.remove(tabs) + + def __getitem__(self, idx): + """Enables list-style access by index.""" + tabs = self._pPr.tabs + if tabs is None: + raise IndexError("TabStops object is empty") + tab = tabs.tab_lst[idx] + return TabStop(tab) + + def __iter__(self): + """Generate a TabStop object for each of the w:tab elements, in XML document + order.""" + tabs = self._pPr.tabs + if tabs is not None: + for tab in tabs.tab_lst: + yield TabStop(tab) + + def __len__(self): + tabs = self._pPr.tabs + if tabs is None: + return 0 + return len(tabs.tab_lst) + + def add_tab_stop(self, position, alignment=WD_TAB_ALIGNMENT.LEFT, leader=WD_TAB_LEADER.SPACES): + """Add a new tab stop at `position`, a |Length| object specifying the location + of the tab stop relative to the paragraph edge. + + A negative `position` value is valid and appears in hanging indentation. Tab + alignment defaults to left, but may be specified by passing a member of the + :ref:`WdTabAlignment` enumeration as `alignment`. An optional leader character + can be specified by passing a member of the :ref:`WdTabLeader` enumeration as + `leader`. + """ + tabs = self._pPr.get_or_add_tabs() + tab = tabs.insert_tab_in_order(position, alignment, leader) + return TabStop(tab) + + def clear_all(self): + """Remove all custom tab stops.""" + self._pPr._remove_tabs() + + +class TabStop(ElementProxy): + """An individual tab stop applying to a paragraph or style. + + Accessed using list semantics on its containing |TabStops| object. + """ + + def __init__(self, element): + super(TabStop, self).__init__(element, None) + self._tab = element + + @property + def alignment(self): + """A member of :ref:`WdTabAlignment` specifying the alignment setting for this + tab stop. + + Read/write. + """ + return self._tab.val + + @alignment.setter + def alignment(self, value): + self._tab.val = value + + @property + def leader(self): + """A member of :ref:`WdTabLeader` specifying a repeating character used as a + "leader", filling in the space spanned by this tab. + + Assigning |None| produces the same result as assigning `WD_TAB_LEADER.SPACES`. + Read/write. + """ + return self._tab.leader + + @leader.setter + def leader(self, value): + self._tab.leader = value + + @property + def position(self): + """A |Length| object representing the distance of this tab stop from the inside + edge of the paragraph. + + May be positive or negative. Read/write. + """ + return self._tab.pos + + @position.setter + def position(self, value): + tab = self._tab + tabs = tab.getparent() + self._tab = tabs.insert_tab_in_order(value, tab.val, tab.leader) + tabs.remove(tab) diff --git a/src/docx/types.py b/src/docx/types.py new file mode 100644 index 00000000..06d1a571 --- /dev/null +++ b/src/docx/types.py @@ -0,0 +1,34 @@ +"""Abstract types used by `python-docx`.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +from typing_extensions import Protocol + +if TYPE_CHECKING: + from docx.opc.part import XmlPart + from docx.parts.story import StoryPart + + +class ProvidesStoryPart(Protocol): + """An object that provides access to the StoryPart. + + This type is for objects that have a story part like document or header as their + root part. + """ + + @property + def part(self) -> StoryPart: ... + + +class ProvidesXmlPart(Protocol): + """An object that provides access to its XmlPart. + + This type is for objects that need access to their part but it either isn't a + StoryPart or they don't care, possibly because they just need access to the package + or related parts. + """ + + @property + def part(self) -> XmlPart: ... diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 00000000..2abfcc96 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,21 @@ +"""pytest fixtures that are shared across test modules.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +import pytest + +if TYPE_CHECKING: + from docx import types as t + from docx.parts.story import StoryPart + + +@pytest.fixture +def fake_parent() -> t.ProvidesStoryPart: + class ProvidesStoryPart: + @property + def part(self) -> StoryPart: + raise NotImplementedError + + return ProvidesStoryPart() diff --git a/tests/dml/test_color.py b/tests/dml/test_color.py index 421f7292..f9fcae0c 100644 --- a/tests/dml/test_color.py +++ b/tests/dml/test_color.py @@ -1,63 +1,59 @@ -# encoding: utf-8 +# pyright: reportPrivateUsage=false -""" -Test suite for docx.dml.color module. -""" +"""Unit-test suite for the `docx.dml.color` module.""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import annotations -from docx.enum.dml import MSO_COLOR_TYPE, MSO_THEME_COLOR -from docx.dml.color import ColorFormat -from docx.shared import RGBColor - -from ..unitutil.cxml import element, xml +from typing import cast import pytest +from docx.dml.color import ColorFormat +from docx.enum.dml import MSO_COLOR_TYPE, MSO_THEME_COLOR +from docx.oxml.text.run import CT_R +from docx.shared import RGBColor -class DescribeColorFormat(object): - def it_knows_its_color_type(self, type_fixture): - color_format, expected_value = type_fixture - assert color_format.type == expected_value - - def it_knows_its_RGB_value(self, rgb_get_fixture): - color_format, expected_value = rgb_get_fixture - assert color_format.rgb == expected_value - - def it_can_change_its_RGB_value(self, rgb_set_fixture): - color_format, new_value, expected_xml = rgb_set_fixture - color_format.rgb = new_value - assert color_format._element.xml == expected_xml +from ..unitutil.cxml import element, xml - def it_knows_its_theme_color(self, theme_color_get_fixture): - color_format, expected_value = theme_color_get_fixture - assert color_format.theme_color == expected_value - def it_can_change_its_theme_color(self, theme_color_set_fixture): - color_format, new_value, expected_xml = theme_color_set_fixture - color_format.theme_color = new_value - assert color_format._element.xml == expected_xml +class DescribeColorFormat: + """Unit-test suite for `docx.dml.color.ColorFormat` objects.""" - # fixtures --------------------------------------------- + @pytest.mark.parametrize( + ("r_cxml", "expected_value"), + [ + ("w:r", None), + ("w:r/w:rPr", None), + ("w:r/w:rPr/w:color{w:val=auto}", MSO_COLOR_TYPE.AUTO), + ("w:r/w:rPr/w:color{w:val=4224FF}", MSO_COLOR_TYPE.RGB), + ("w:r/w:rPr/w:color{w:themeColor=dark1}", MSO_COLOR_TYPE.THEME), + ( + "w:r/w:rPr/w:color{w:val=F00BA9,w:themeColor=accent1}", + MSO_COLOR_TYPE.THEME, + ), + ], + ) + def it_knows_its_color_type(self, r_cxml: str, expected_value: MSO_COLOR_TYPE | None): + assert ColorFormat(cast(CT_R, element(r_cxml))).type == expected_value - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("r_cxml", "rgb"), + [ ("w:r", None), ("w:r/w:rPr", None), ("w:r/w:rPr/w:color{w:val=auto}", None), ("w:r/w:rPr/w:color{w:val=4224FF}", "4224ff"), ("w:r/w:rPr/w:color{w:val=auto,w:themeColor=accent1}", None), ("w:r/w:rPr/w:color{w:val=F00BA9,w:themeColor=accent1}", "f00ba9"), - ] + ], ) - def rgb_get_fixture(self, request): - r_cxml, rgb = request.param - color_format = ColorFormat(element(r_cxml)) - expected_value = None if rgb is None else RGBColor.from_string(rgb) - return color_format, expected_value + def it_knows_its_RGB_value(self, r_cxml: str, rgb: str | None): + expected_value = RGBColor.from_string(rgb) if rgb else None + assert ColorFormat(cast(CT_R, element(r_cxml))).rgb == expected_value - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("r_cxml", "new_value", "expected_cxml"), + [ ("w:r", RGBColor(10, 20, 30), "w:r/w:rPr/w:color{w:val=0A141E}"), ("w:r/w:rPr", RGBColor(1, 2, 3), "w:r/w:rPr/w:color{w:val=010203}"), ( @@ -77,73 +73,60 @@ def rgb_get_fixture(self, request): ), ("w:r/w:rPr/w:color{w:val=234bcd,w:themeColor=dark1}", None, "w:r/w:rPr"), ("w:r", None, "w:r"), - ] + ], ) - def rgb_set_fixture(self, request): - r_cxml, new_value, expected_cxml = request.param - color_format = ColorFormat(element(r_cxml)) - expected_xml = xml(expected_cxml) - return color_format, new_value, expected_xml + def it_can_change_its_RGB_value( + self, r_cxml: str, new_value: RGBColor | None, expected_cxml: str + ): + color_format = ColorFormat(cast(CT_R, element(r_cxml))) + color_format.rgb = new_value + assert color_format._element.xml == xml(expected_cxml) - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("r_cxml", "expected_value"), + [ ("w:r", None), ("w:r/w:rPr", None), ("w:r/w:rPr/w:color{w:val=auto}", None), ("w:r/w:rPr/w:color{w:val=4224FF}", None), - ("w:r/w:rPr/w:color{w:themeColor=accent1}", "ACCENT_1"), - ("w:r/w:rPr/w:color{w:val=F00BA9,w:themeColor=dark1}", "DARK_1"), - ] + ("w:r/w:rPr/w:color{w:themeColor=accent1}", MSO_THEME_COLOR.ACCENT_1), + ("w:r/w:rPr/w:color{w:val=F00BA9,w:themeColor=dark1}", MSO_THEME_COLOR.DARK_1), + ], ) - def theme_color_get_fixture(self, request): - r_cxml, value = request.param - color_format = ColorFormat(element(r_cxml)) - expected_value = None if value is None else getattr(MSO_THEME_COLOR, value) - return color_format, expected_value + def it_knows_its_theme_color(self, r_cxml: str, expected_value: MSO_THEME_COLOR | None): + color_format = ColorFormat(cast(CT_R, element(r_cxml))) + assert color_format.theme_color == expected_value - @pytest.fixture( - params=[ - ("w:r", "ACCENT_1", "w:r/w:rPr/w:color{w:val=000000,w:themeColor=accent1}"), + @pytest.mark.parametrize( + ("r_cxml", "new_value", "expected_cxml"), + [ + ( + "w:r", + MSO_THEME_COLOR.ACCENT_1, + "w:r/w:rPr/w:color{w:val=000000,w:themeColor=accent1}", + ), ( "w:r/w:rPr", - "ACCENT_2", + MSO_THEME_COLOR.ACCENT_2, "w:r/w:rPr/w:color{w:val=000000,w:themeColor=accent2}", ), ( "w:r/w:rPr/w:color{w:val=101112}", - "ACCENT_3", + MSO_THEME_COLOR.ACCENT_3, "w:r/w:rPr/w:color{w:val=101112,w:themeColor=accent3}", ), ( "w:r/w:rPr/w:color{w:val=234bcd,w:themeColor=dark1}", - "LIGHT_2", + MSO_THEME_COLOR.LIGHT_2, "w:r/w:rPr/w:color{w:val=234bcd,w:themeColor=light2}", ), ("w:r/w:rPr/w:color{w:val=234bcd,w:themeColor=dark1}", None, "w:r/w:rPr"), ("w:r", None, "w:r"), - ] - ) - def theme_color_set_fixture(self, request): - r_cxml, member, expected_cxml = request.param - color_format = ColorFormat(element(r_cxml)) - new_value = None if member is None else getattr(MSO_THEME_COLOR, member) - expected_xml = xml(expected_cxml) - return color_format, new_value, expected_xml - - @pytest.fixture( - params=[ - ("w:r", None), - ("w:r/w:rPr", None), - ("w:r/w:rPr/w:color{w:val=auto}", MSO_COLOR_TYPE.AUTO), - ("w:r/w:rPr/w:color{w:val=4224FF}", MSO_COLOR_TYPE.RGB), - ("w:r/w:rPr/w:color{w:themeColor=dark1}", MSO_COLOR_TYPE.THEME), - ( - "w:r/w:rPr/w:color{w:val=F00BA9,w:themeColor=accent1}", - MSO_COLOR_TYPE.THEME, - ), - ] + ], ) - def type_fixture(self, request): - r_cxml, expected_value = request.param - color_format = ColorFormat(element(r_cxml)) - return color_format, expected_value + def it_can_change_its_theme_color( + self, r_cxml: str, new_value: MSO_THEME_COLOR | None, expected_cxml: str + ): + color_format = ColorFormat(cast(CT_R, element(r_cxml))) + color_format.theme_color = new_value + assert color_format._element.xml == xml(expected_cxml) diff --git a/tests/image/test_bmp.py b/tests/image/test_bmp.py index 9eb37164..27c0e8f5 100644 --- a/tests/image/test_bmp.py +++ b/tests/image/test_bmp.py @@ -1,28 +1,23 @@ -# encoding: utf-8 +"""Test suite for docx.image.bmp module.""" -""" -Test suite for docx.image.bmp module -""" - -from __future__ import absolute_import, print_function +import io import pytest -from docx.compat import BytesIO -from docx.image.constants import MIME_TYPE from docx.image.bmp import Bmp +from docx.image.constants import MIME_TYPE from ..unitutil.mock import ANY, initializer_mock -class DescribeBmp(object): +class DescribeBmp: def it_can_construct_from_a_bmp_stream(self, Bmp__init__): cx, cy, horz_dpi, vert_dpi = 26, 43, 200, 96 bytes_ = ( - b"fillerfillerfiller\x1A\x00\x00\x00\x2B\x00\x00\x00" - b"fillerfiller\xB8\x1E\x00\x00\x00\x00\x00\x00" + b"fillerfillerfiller\x1a\x00\x00\x00\x2b\x00\x00\x00" + b"fillerfiller\xb8\x1e\x00\x00\x00\x00\x00\x00" ) - stream = BytesIO(bytes_) + stream = io.BytesIO(bytes_) bmp = Bmp.from_stream(stream) diff --git a/tests/image/test_emf.py b/tests/image/test_emf.py index 3fb1453f..dcc7294c 100644 --- a/tests/image/test_emf.py +++ b/tests/image/test_emf.py @@ -1,38 +1,41 @@ # encoding: utf-8 -"""Unit test suite for docx.image.emf module""" +from __future__ import absolute_import, division, print_function, unicode_literals import pytest -from docx.compat import BytesIO -from docx.image.constants import MIME_TYPE +import io from docx.image.emf import Emf +from docx.image.helpers import LITTLE_ENDIAN, StreamReader -from ..unitutil.mock import ANY, initializer_mock +from ..unitutil.file import test_file class DescribeEmf(object): - def it_can_construct_from_a_emf_stream(self, Emf__init__): - cx, cy = 69, 69 - h_dpi, v_dpi = 2540.0, 2540.0 - bytes_ = b"\x01\x00\x00\x00l\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\x00\x00\x00E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\x00\x00\x00E\x00\x00\x00" - stream = BytesIO(bytes_) - + def it_can_construct_from_an_emf_stream(self, from_stream_fixture): + stream, cx, cy, xdpi, ydpi = from_stream_fixture emf = Emf.from_stream(stream) - - Emf__init__.assert_called_once_with(ANY, cx, cy, h_dpi, v_dpi) assert isinstance(emf, Emf) + assert emf.px_width == cx + assert emf.px_height == cy + assert emf.horz_dpi == xdpi + assert emf.vert_dpi == ydpi - def it_knows_its_content_type(self): - emf = Emf(None, None, None, None) - assert emf.content_type == MIME_TYPE.EMF - - def it_knows_its_default_ext(self): - emf = Emf(None, None, None, None) - assert emf.default_ext == "emf" - - # fixture components --------------------------------------------- + # fixtures ------------------------------------------------------- @pytest.fixture - def Emf__init__(self, request): - return initializer_mock(request, Emf) + def from_stream_fixture(self): + path = test_file("sonic.emf") + with open(path, "rb") as f: + stream = io.BytesIO(f.read()) + stream_rdr = StreamReader(stream, LITTLE_ENDIAN) + x0 = stream_rdr.read_long(8) + y0 = stream_rdr.read_long(12) + x1 = stream_rdr.read_long(16) + y1 = stream_rdr.read_long(20) + + frame = tuple(map(stream_rdr.read_long, (24, 28, 32, 36))) + + xdpi = 2540.0 * (x1 - x0) / (frame[2] - frame[0]) + ydpi = 2540.0 * (y1 - y0) / (frame[3] - frame[1]) + return stream, x1 - x0, y1 - y0, xdpi, ydpi \ No newline at end of file diff --git a/tests/image/test_gif.py b/tests/image/test_gif.py index fc00af69..4aa6581b 100644 --- a/tests/image/test_gif.py +++ b/tests/image/test_gif.py @@ -1,23 +1,20 @@ -# encoding: utf-8 +"""Unit test suite for docx.image.gif module.""" -"""Unit test suite for docx.image.gif module""" - -from __future__ import absolute_import, print_function +import io import pytest -from docx.compat import BytesIO from docx.image.constants import MIME_TYPE from docx.image.gif import Gif from ..unitutil.mock import ANY, initializer_mock -class DescribeGif(object): +class DescribeGif: def it_can_construct_from_a_gif_stream(self, Gif__init__): cx, cy = 42, 24 - bytes_ = b"filler\x2A\x00\x18\x00" - stream = BytesIO(bytes_) + bytes_ = b"filler\x2a\x00\x18\x00" + stream = io.BytesIO(bytes_) gif = Gif.from_stream(stream) diff --git a/tests/image/test_helpers.py b/tests/image/test_helpers.py index 8716257d..03421ff5 100644 --- a/tests/image/test_helpers.py +++ b/tests/image/test_helpers.py @@ -1,19 +1,14 @@ -# encoding: utf-8 +"""Test suite for docx.image.helpers module.""" -""" -Test suite for docx.image.helpers module -""" - -from __future__ import absolute_import, print_function +import io import pytest -from docx.compat import BytesIO from docx.image.exceptions import UnexpectedEndOfFileError from docx.image.helpers import BIG_ENDIAN, LITTLE_ENDIAN, StreamReader -class DescribeStreamReader(object): +class DescribeStreamReader: def it_can_read_a_string_of_specified_len_at_offset(self, read_str_fixture): stream_rdr, expected_string = read_str_fixture s = stream_rdr.read_str(6, 2) @@ -33,19 +28,19 @@ def it_can_read_a_long(self, read_long_fixture): @pytest.fixture( params=[ - (BIG_ENDIAN, b"\xBE\x00\x00\x00\x2A\xEF", 1, 42), - (LITTLE_ENDIAN, b"\xBE\xEF\x2A\x00\x00\x00", 2, 42), + (BIG_ENDIAN, b"\xbe\x00\x00\x00\x2a\xef", 1, 42), + (LITTLE_ENDIAN, b"\xbe\xef\x2a\x00\x00\x00", 2, 42), ] ) def read_long_fixture(self, request): byte_order, bytes_, offset, expected_int = request.param - stream = BytesIO(bytes_) + stream = io.BytesIO(bytes_) stream_rdr = StreamReader(stream, byte_order) return stream_rdr, offset, expected_int @pytest.fixture def read_str_fixture(self): - stream = BytesIO(b"\x01\x02foobar\x03\x04") + stream = io.BytesIO(b"\x01\x02foobar\x03\x04") stream_rdr = StreamReader(stream, BIG_ENDIAN) expected_string = "foobar" return stream_rdr, expected_string diff --git a/tests/image/test_image.py b/tests/image/test_image.py index 0bb8707f..c13e8730 100644 --- a/tests/image/test_image.py +++ b/tests/image/test_image.py @@ -1,12 +1,9 @@ -# encoding: utf-8 - """Unit test suite for docx.image package""" -from __future__ import absolute_import, print_function, unicode_literals +import io import pytest -from docx.compat import BytesIO from docx.image.bmp import Bmp from docx.image.exceptions import UnrecognizedImageError from docx.image.gif import Gif @@ -17,7 +14,7 @@ from docx.opc.constants import CONTENT_TYPE as CT from docx.shared import Emu, Length -from ..unitutil.file import testfile +from ..unitutil.file import test_file from ..unitutil.mock import ( ANY, class_mock, @@ -29,10 +26,8 @@ ) -class DescribeImage(object): - def it_can_construct_from_an_image_blob( - self, blob_, BytesIO_, _from_stream_, stream_, image_ - ): +class DescribeImage: + def it_can_construct_from_an_image_blob(self, blob_, BytesIO_, _from_stream_, stream_, image_): image = Image.from_blob(blob_) BytesIO_.assert_called_once_with(blob_) @@ -116,7 +111,7 @@ def it_knows_the_sha1_of_its_image(self): def it_correctly_characterizes_known_images(self, known_image_fixture): image_path, characteristics = known_image_fixture ext, content_type, px_width, px_height, horz_dpi, vert_dpi = characteristics - with open(testfile(image_path), "rb") as stream: + with open(test_file(image_path), "rb") as stream: image = Image.from_file(stream) assert image.content_type == content_type assert image.ext == ext @@ -149,16 +144,16 @@ def dpi_fixture(self, image_header_): @pytest.fixture def from_filelike_fixture(self, _from_stream_, image_): - image_path = testfile("python-icon.png") + image_path = test_file("python-icon.png") with open(image_path, "rb") as f: blob = f.read() - image_stream = BytesIO(blob) + image_stream = io.BytesIO(blob) return image_stream, _from_stream_, blob, image_ @pytest.fixture def from_path_fixture(self, _from_stream_, BytesIO_, stream_, image_): filename = "python-icon.png" - image_path = testfile(filename) + image_path = test_file(filename) with open(image_path, "rb") as f: blob = f.read() return image_path, _from_stream_, stream_, blob, filename, image_ @@ -226,7 +221,7 @@ def blob_(self, request): @pytest.fixture def BytesIO_(self, request, stream_): - return class_mock(request, "docx.image.image.BytesIO", return_value=stream_) + return class_mock(request, "docx.image.image.io.BytesIO", return_value=stream_) @pytest.fixture def filename_(self, request): @@ -234,9 +229,7 @@ def filename_(self, request): @pytest.fixture def _from_stream_(self, request, image_): - return method_mock( - request, Image, "_from_stream", autospec=False, return_value=image_ - ) + return method_mock(request, Image, "_from_stream", autospec=False, return_value=image_) @pytest.fixture def height_prop_(self, request): @@ -262,21 +255,21 @@ def Image__init_(self, request): @pytest.fixture def stream_(self, request): - return instance_mock(request, BytesIO) + return instance_mock(request, io.BytesIO) @pytest.fixture def width_prop_(self, request): return property_mock(request, Image, "width") -class Describe_ImageHeaderFactory(object): +class Describe_ImageHeaderFactory: def it_constructs_the_right_class_for_a_given_image_stream(self, call_fixture): stream, expected_class = call_fixture image_header = _ImageHeaderFactory(stream) assert isinstance(image_header, expected_class) def it_raises_on_unrecognized_image_stream(self): - stream = BytesIO(b"foobar 666 not an image stream") + stream = io.BytesIO(b"foobar 666 not an image stream") with pytest.raises(UnrecognizedImageError): _ImageHeaderFactory(stream) @@ -295,15 +288,15 @@ def it_raises_on_unrecognized_image_stream(self): ) def call_fixture(self, request): image_filename, expected_class = request.param - image_path = testfile(image_filename) + image_path = test_file(image_filename) with open(image_path, "rb") as f: blob = f.read() - image_stream = BytesIO(blob) + image_stream = io.BytesIO(blob) image_stream.seek(666) return image_stream, expected_class -class DescribeBaseImageHeader(object): +class DescribeBaseImageHeader: def it_defines_content_type_as_an_abstract_property(self): base_image_header = BaseImageHeader(None, None, None, None) with pytest.raises(NotImplementedError): diff --git a/tests/image/test_jpeg.py b/tests/image/test_jpeg.py index 824ef393..bf08da08 100644 --- a/tests/image/test_jpeg.py +++ b/tests/image/test_jpeg.py @@ -1,21 +1,20 @@ -# encoding: utf-8 +# pyright: basic, reportPrivateUsage=false """Unit test suite for docx.image.jpeg module""" -from __future__ import absolute_import, print_function +import io import pytest -from docx.compat import BytesIO from docx.image.constants import JPEG_MARKER_CODE, MIME_TYPE from docx.image.helpers import BIG_ENDIAN, StreamReader from docx.image.jpeg import ( - _App0Marker, - _App1Marker, Exif, Jfif, - _JfifMarkers, Jpeg, + _App0Marker, + _App1Marker, + _JfifMarkers, _Marker, _MarkerFactory, _MarkerFinder, @@ -31,29 +30,30 @@ initializer_mock, instance_mock, method_mock, - MagicMock, - PropertyMock ) +from ..unitutil.file import test_file -class DescribeJpeg(object): +class DescribeJpeg: def it_knows_its_content_type(self): - jpeg = Jpeg(None, None, None, None) + jpeg = Jpeg(0, 0, 0, 0) assert jpeg.content_type == MIME_TYPE.JPEG def it_knows_its_default_ext(self): - jpeg = Jpeg(None, None, None, None) + jpeg = Jpeg(0, 0, 0, 0) assert jpeg.default_ext == "jpg" - def it_not_contains_app0_or_app1(self): - with open("tests/test_files/jpeg_without_app0_and_app1.jpg", "rb") as f: - jpeg = Jpeg.from_stream(f) - assert jpeg.horz_dpi == 72 - assert jpeg.vert_dpi == 72 - assert jpeg.px_width == 1190 - assert jpeg.px_height == 1190 + def it_falls_back_to_default_dpi_when_app_markers_missing(self): + path = test_file("jpeg_without_app0_and_app1.jpg") + with open(path, "rb") as stream: + jpeg = Jpeg.from_stream(stream) - class DescribeExif(object): + assert jpeg.horz_dpi == Jpeg.DEFAULT_DPI + assert jpeg.vert_dpi == Jpeg.DEFAULT_DPI + assert jpeg.px_width == 1190 + assert jpeg.px_height == 1190 + + class DescribeExif: def it_can_construct_from_an_exif_stream(self, from_exif_fixture): # fixture ---------------------- stream_, _JfifMarkers_, cx, cy, horz_dpi, vert_dpi = from_exif_fixture @@ -67,7 +67,7 @@ def it_can_construct_from_an_exif_stream(self, from_exif_fixture): assert exif.horz_dpi == horz_dpi assert exif.vert_dpi == vert_dpi - class DescribeJfif(object): + class DescribeJfif: def it_can_construct_from_a_jfif_stream(self, from_jfif_fixture): stream_, _JfifMarkers_, cx, cy, horz_dpi, vert_dpi = from_jfif_fixture jfif = Jfif.from_stream(stream_) @@ -112,10 +112,10 @@ def jfif_markers_(self, request): @pytest.fixture def stream_(self, request): - return instance_mock(request, BytesIO) + return instance_mock(request, io.BytesIO) -class Describe_JfifMarkers(object): +class Describe_JfifMarkers: def it_can_construct_from_a_jfif_stream( self, stream_, _MarkerParser_, _JfifMarkers__init_, soi_, app0_, sof_, sos_ ): @@ -238,10 +238,10 @@ def sos_(self, request): @pytest.fixture def stream_(self, request): - return instance_mock(request, BytesIO) + return instance_mock(request, io.BytesIO) -class Describe_Marker(object): +class Describe_Marker: def it_can_construct_from_a_stream_and_offset(self, from_stream_fixture): stream, marker_code, offset, _Marker__init_, length = from_stream_fixture @@ -260,8 +260,8 @@ def it_can_construct_from_a_stream_and_offset(self, from_stream_fixture): ) def from_stream_fixture(self, request, _Marker__init_): marker_code, offset, length = request.param - bytes_ = b"\xFF\xD8\xFF\xE0\x00\x10" - stream_reader = StreamReader(BytesIO(bytes_), BIG_ENDIAN) + bytes_ = b"\xff\xd8\xff\xe0\x00\x10" + stream_reader = StreamReader(io.BytesIO(bytes_), BIG_ENDIAN) return stream_reader, marker_code, offset, _Marker__init_, length @pytest.fixture @@ -269,12 +269,12 @@ def _Marker__init_(self, request): return initializer_mock(request, _Marker) -class Describe_App0Marker(object): +class Describe_App0Marker: def it_can_construct_from_a_stream_and_offset(self, _App0Marker__init_): - bytes_ = b"\x00\x10JFIF\x00\x01\x01\x01\x00\x2A\x00\x18" + bytes_ = b"\x00\x10JFIF\x00\x01\x01\x01\x00\x2a\x00\x18" marker_code, offset, length = JPEG_MARKER_CODE.APP0, 0, 16 density_units, x_density, y_density = 1, 42, 24 - stream = StreamReader(BytesIO(bytes_), BIG_ENDIAN) + stream = StreamReader(io.BytesIO(bytes_), BIG_ENDIAN) app0_marker = _App0Marker.from_stream(stream, marker_code, offset) @@ -307,14 +307,14 @@ def dpi_fixture(self, request): return density_units, x_density, y_density, horz_dpi, vert_dpi -class Describe_App1Marker(object): +class Describe_App1Marker: def it_can_construct_from_a_stream_and_offset( self, _App1Marker__init_, _tiff_from_exif_segment_ ): bytes_ = b"\x00\x42Exif\x00\x00" marker_code, offset, length = JPEG_MARKER_CODE.APP1, 0, 66 horz_dpi, vert_dpi = 42, 24 - stream = StreamReader(BytesIO(bytes_), BIG_ENDIAN) + stream = StreamReader(io.BytesIO(bytes_), BIG_ENDIAN) app1_marker = _App1Marker.from_stream(stream, marker_code, offset) @@ -327,13 +327,11 @@ def it_can_construct_from_a_stream_and_offset( def it_can_construct_from_non_Exif_APP1_segment(self, _App1Marker__init_): bytes_ = b"\x00\x42Foobar" marker_code, offset, length = JPEG_MARKER_CODE.APP1, 0, 66 - stream = StreamReader(BytesIO(bytes_), BIG_ENDIAN) + stream = StreamReader(io.BytesIO(bytes_), BIG_ENDIAN) app1_marker = _App1Marker.from_stream(stream, marker_code, offset) - _App1Marker__init_.assert_called_once_with( - ANY, marker_code, offset, length, 72, 72 - ) + _App1Marker__init_.assert_called_once_with(ANY, marker_code, offset, length, 72, 72) assert isinstance(app1_marker, _App1Marker) def it_gets_a_tiff_from_its_Exif_segment_to_help_construct(self, get_tiff_fixture): @@ -358,13 +356,10 @@ def _App1Marker__init_(self, request): return initializer_mock(request, _App1Marker) @pytest.fixture - def BytesIO_(self, request, substream_): - return class_mock(request, "docx.image.jpeg.BytesIO", return_value=substream_) - - @pytest.fixture - def get_tiff_fixture(self, request, BytesIO_, substream_, Tiff_, tiff_): + def get_tiff_fixture(self, request, substream_, Tiff_, tiff_): bytes_ = b"xfillerxMM\x00*\x00\x00\x00\x42" - stream_reader = StreamReader(BytesIO(bytes_), BIG_ENDIAN) + stream_reader = StreamReader(io.BytesIO(bytes_), BIG_ENDIAN) + BytesIO_ = class_mock(request, "docx.image.jpeg.io.BytesIO", return_value=substream_) offset, segment_length, segment_bytes = 0, 16, bytes_[8:] return ( stream_reader, @@ -379,7 +374,7 @@ def get_tiff_fixture(self, request, BytesIO_, substream_, Tiff_, tiff_): @pytest.fixture def substream_(self, request): - return instance_mock(request, BytesIO) + return instance_mock(request, io.BytesIO) @pytest.fixture def Tiff_(self, request, tiff_): @@ -402,12 +397,12 @@ def _tiff_from_exif_segment_(self, request, tiff_): ) -class Describe_SofMarker(object): +class Describe_SofMarker: def it_can_construct_from_a_stream_and_offset(self, request, _SofMarker__init_): - bytes_ = b"\x00\x11\x00\x00\x2A\x00\x18" + bytes_ = b"\x00\x11\x00\x00\x2a\x00\x18" marker_code, offset, length = JPEG_MARKER_CODE.SOF0, 0, 17 px_width, px_height = 24, 42 - stream = StreamReader(BytesIO(bytes_), BIG_ENDIAN) + stream = StreamReader(io.BytesIO(bytes_), BIG_ENDIAN) sof_marker = _SofMarker.from_stream(stream, marker_code, offset) @@ -428,7 +423,7 @@ def _SofMarker__init_(self, request): return initializer_mock(request, _SofMarker) -class Describe_MarkerFactory(object): +class Describe_MarkerFactory: def it_constructs_the_appropriate_marker_object(self, call_fixture): marker_code, stream_, offset_, marker_cls_ = call_fixture marker = _MarkerFactory(marker_code, stream_, offset_) @@ -489,10 +484,10 @@ def _SofMarker_(self, request): @pytest.fixture def stream_(self, request): - return instance_mock(request, BytesIO) + return instance_mock(request, io.BytesIO) -class Describe_MarkerFinder(object): +class Describe_MarkerFinder: def it_can_construct_from_a_stream(self, stream_, _MarkerFinder__init_): marker_finder = _MarkerFinder.from_stream(stream_) @@ -523,18 +518,18 @@ def _MarkerFinder__init_(self, request): ) def next_fixture(self, request): start, marker_code, segment_offset = request.param - bytes_ = b"\xFF\xD8\xFF\xE0\x00\x01\xFF\x00\xFF\xFF\xFF\xD9" - stream_reader = StreamReader(BytesIO(bytes_), BIG_ENDIAN) + bytes_ = b"\xff\xd8\xff\xe0\x00\x01\xff\x00\xff\xff\xff\xd9" + stream_reader = StreamReader(io.BytesIO(bytes_), BIG_ENDIAN) marker_finder = _MarkerFinder(stream_reader) expected_code_and_offset = (marker_code, segment_offset) return marker_finder, start, expected_code_and_offset @pytest.fixture def stream_(self, request): - return instance_mock(request, BytesIO) + return instance_mock(request, io.BytesIO) -class Describe_MarkerParser(object): +class Describe_MarkerParser: def it_can_construct_from_a_jfif_stream( self, stream_, StreamReader_, _MarkerParser__init_, stream_reader_ ): @@ -555,7 +550,7 @@ def it_can_iterate_over_the_jfif_markers_in_its_stream(self, iter_markers_fixtur offsets, marker_lst, ) = iter_markers_fixture - markers = [marker for marker in marker_parser.iter_markers()] + markers = list(marker_parser.iter_markers()) _MarkerFinder_.from_stream.assert_called_once_with(stream_) assert marker_finder_.next.call_args_list == [call(0), call(2), call(20)] assert _MarkerFactory_.call_args_list == [ @@ -636,85 +631,12 @@ def soi_(self, request): @pytest.fixture def stream_(self, request): - return instance_mock(request, BytesIO) + return instance_mock(request, io.BytesIO) @pytest.fixture def StreamReader_(self, request, stream_reader_): - return class_mock( - request, "docx.image.jpeg.StreamReader", return_value=stream_reader_ - ) + return class_mock(request, "docx.image.jpeg.StreamReader", return_value=stream_reader_) @pytest.fixture def stream_reader_(self, request): return instance_mock(request, StreamReader) - - -class TestJpegMethods: - def test_get_horz_dpi_and_vert_dpi_from_app0(self, mocker): - markers = MagicMock() - mocker.patch.object(Jpeg, "_try_get_dpi_from_app0", return_value=(96, 96)) - horz_dpi,vert_dpi = Jpeg._get_horz_dpi_and_vert_dpi(markers) - assert horz_dpi == 96 - assert vert_dpi == 96 - - def test_get_horz_dpi_and_vert_dpi_from_app0_but_return_zero(self, mocker): - markers = MagicMock() - mocker.patch.object(Jpeg, "_try_get_dpi_from_app0", return_value=(0, 0)) - horz_dpi,vert_dpi = Jpeg._get_horz_dpi_and_vert_dpi(markers) - assert horz_dpi == 72 - assert vert_dpi == 72 - - - def test_get_horz_dpi_and_vert_dpi_from_app1(self, mocker): - markers = MagicMock() - mocker.patch.object(Jpeg, "_try_get_dpi_from_app0", return_value=(None, None)) - mocker.patch.object(Jpeg, "_try_get_dpi_from_app1", return_value=(96, 96)) - horz_dpi,vert_dpi = Jpeg._get_horz_dpi_and_vert_dpi(markers) - assert horz_dpi == 96 - assert vert_dpi == 96 - - def test_get_horz_dpi_and_vert_dpi_from_app1_but_return_zero(self, mocker): - markers = MagicMock() - mocker.patch.object(Jpeg, "_try_get_dpi_from_app0", return_value=(None, None)) - mocker.patch.object(Jpeg, "_try_get_dpi_from_app1", return_value=(0, 0)) - horz_dpi,vert_dpi = Jpeg._get_horz_dpi_and_vert_dpi(markers) - assert horz_dpi == 72 - assert vert_dpi == 72 - - def test_get_horz_dpi_and_vert_dpi_from_DEFAULT_DPI(self, mocker): - markers = MagicMock() - mocker.patch.object(Jpeg, "_try_get_dpi_from_app0", return_value=(None, None)) - mocker.patch.object(Jpeg, "_try_get_dpi_from_app1", return_value=(None, None)) - horz_dpi,vert_dpi = Jpeg._get_horz_dpi_and_vert_dpi(markers) - assert horz_dpi == 72 - assert vert_dpi == 72 - - def test__try_get_dpi_from_app0_returns_None(self, mocker): - markers = MagicMock() - type(markers).app0 = PropertyMock(side_effect=KeyError("APP0 not found")) - horz_dpi,vert_dpi = Jpeg._try_get_dpi_from_app0(markers) - assert horz_dpi is None - assert vert_dpi is None - - def test__try_get_dpi_from_app0(self, mocker): - markers = MagicMock() - markers.app0.horz_dpi = 96 - markers.app0.vert_dpi = 96 - horz_dpi,vert_dpi = Jpeg._try_get_dpi_from_app0(markers) - assert horz_dpi == 96 - assert vert_dpi == 96 - - def test__try_get_dpi_from_app1_returns_None(self, mocker): - markers = MagicMock() - type(markers).app1 = PropertyMock(side_effect=KeyError("APP1 not found")) - horz_dpi,vert_dpi = Jpeg._try_get_dpi_from_app1(markers) - assert horz_dpi is None - assert vert_dpi is None - - def test__try_get_dpi_from_app1(self, mocker): - markers = MagicMock() - markers.app1.horz_dpi = 96 - markers.app1.vert_dpi = 96 - horz_dpi,vert_dpi = Jpeg._try_get_dpi_from_app1(markers) - assert horz_dpi == 96 - assert vert_dpi == 96 diff --git a/tests/image/test_png.py b/tests/image/test_png.py index 71b2c7e1..5379b403 100644 --- a/tests/image/test_png.py +++ b/tests/image/test_png.py @@ -1,23 +1,20 @@ -# encoding: utf-8 +"""Unit test suite for docx.image.png module.""" -"""Unit test suite for docx.image.png module""" - -from __future__ import absolute_import, print_function +import io import pytest -from docx.compat import BytesIO from docx.image.constants import MIME_TYPE, PNG_CHUNK_TYPE from docx.image.exceptions import InvalidImageStreamError from docx.image.helpers import BIG_ENDIAN, StreamReader from docx.image.png import ( + Png, _Chunk, - _Chunks, _ChunkFactory, _ChunkParser, + _Chunks, _IHDRChunk, _pHYsChunk, - Png, _PngParser, ) @@ -32,10 +29,8 @@ ) -class DescribePng(object): - def it_can_construct_from_a_png_stream( - self, stream_, _PngParser_, png_parser_, Png__init__ - ): +class DescribePng: + def it_can_construct_from_a_png_stream(self, stream_, _PngParser_, png_parser_, Png__init__): px_width, px_height, horz_dpi, vert_dpi = 42, 24, 36, 63 png_parser_.px_width = px_width png_parser_.px_height = px_height @@ -45,9 +40,7 @@ def it_can_construct_from_a_png_stream( png = Png.from_stream(stream_) _PngParser_.parse.assert_called_once_with(stream_) - Png__init__.assert_called_once_with( - ANY, px_width, px_height, horz_dpi, vert_dpi - ) + Png__init__.assert_called_once_with(ANY, px_width, px_height, horz_dpi, vert_dpi) assert isinstance(png, Png) def it_knows_its_content_type(self): @@ -76,10 +69,10 @@ def png_parser_(self, request): @pytest.fixture def stream_(self, request): - return instance_mock(request, BytesIO) + return instance_mock(request, io.BytesIO) -class Describe_PngParser(object): +class Describe_PngParser: def it_can_parse_the_headers_of_a_PNG_stream( self, stream_, _Chunks_, _PngParser__init_, chunks_ ): @@ -156,13 +149,11 @@ def _PngParser__init_(self, request): @pytest.fixture def stream_(self, request): - return instance_mock(request, BytesIO) + return instance_mock(request, io.BytesIO) -class Describe_Chunks(object): - def it_can_construct_from_a_stream( - self, stream_, _ChunkParser_, chunk_parser_, _Chunks__init_ - ): +class Describe_Chunks: + def it_can_construct_from_a_stream(self, stream_, _ChunkParser_, chunk_parser_, _Chunks__init_): chunk_lst = [1, 2] chunk_parser_.iter_chunks.return_value = iter(chunk_lst) @@ -175,7 +166,7 @@ def it_can_construct_from_a_stream( def it_provides_access_to_the_IHDR_chunk(self, IHDR_fixture): chunks, IHDR_chunk_ = IHDR_fixture - assert chunks.IHDR == IHDR_chunk_ + assert IHDR_chunk_ == chunks.IHDR def it_provides_access_to_the_pHYs_chunk(self, pHYs_fixture): chunks, expected_chunk = pHYs_fixture @@ -234,10 +225,10 @@ def pHYs_fixture(self, request, IHDR_chunk_, pHYs_chunk_): @pytest.fixture def stream_(self, request): - return instance_mock(request, BytesIO) + return instance_mock(request, io.BytesIO) -class Describe_ChunkParser(object): +class Describe_ChunkParser: def it_can_construct_from_a_stream( self, stream_, StreamReader_, stream_rdr_, _ChunkParser__init_ ): @@ -254,7 +245,7 @@ def it_can_iterate_over_the_chunks_in_its_png_stream( chunk_lst = [chunk_, chunk_2_] chunk_parser = _ChunkParser(stream_rdr_) - chunks = [chunk for chunk in chunk_parser.iter_chunks()] + chunks = list(chunk_parser.iter_chunks()) _iter_chunk_offsets_.assert_called_once_with(chunk_parser) assert _ChunkFactory_.call_args_list == [ @@ -265,7 +256,7 @@ def it_can_iterate_over_the_chunks_in_its_png_stream( def it_iterates_over_the_chunk_offsets_to_help_parse(self, iter_offsets_fixture): chunk_parser, expected_chunk_offsets = iter_offsets_fixture - chunk_offsets = [co for co in chunk_parser._iter_chunk_offsets()] + chunk_offsets = list(chunk_parser._iter_chunk_offsets()) assert chunk_offsets == expected_chunk_offsets # fixtures ------------------------------------------------------- @@ -280,9 +271,7 @@ def chunk_2_(self, request): @pytest.fixture def _ChunkFactory_(self, request, chunk_lst_): - return function_mock( - request, "docx.image.png._ChunkFactory", side_effect=chunk_lst_ - ) + return function_mock(request, "docx.image.png._ChunkFactory", side_effect=chunk_lst_) @pytest.fixture def chunk_lst_(self, chunk_, chunk_2_): @@ -308,7 +297,7 @@ def _iter_chunk_offsets_(self, request): @pytest.fixture def iter_offsets_fixture(self): bytes_ = b"-filler-\x00\x00\x00\x00IHDRxxxx\x00\x00\x00\x00IEND" - stream_rdr = StreamReader(BytesIO(bytes_), BIG_ENDIAN) + stream_rdr = StreamReader(io.BytesIO(bytes_), BIG_ENDIAN) chunk_parser = _ChunkParser(stream_rdr) expected_chunk_offsets = [ (PNG_CHUNK_TYPE.IHDR, 16), @@ -318,20 +307,18 @@ def iter_offsets_fixture(self): @pytest.fixture def StreamReader_(self, request, stream_rdr_): - return class_mock( - request, "docx.image.png.StreamReader", return_value=stream_rdr_ - ) + return class_mock(request, "docx.image.png.StreamReader", return_value=stream_rdr_) @pytest.fixture def stream_(self, request): - return instance_mock(request, BytesIO) + return instance_mock(request, io.BytesIO) @pytest.fixture def stream_rdr_(self, request): return instance_mock(request, StreamReader) -class Describe_ChunkFactory(object): +class Describe_ChunkFactory: def it_constructs_the_appropriate_Chunk_subclass(self, call_fixture): chunk_type, stream_rdr_, offset, chunk_cls_ = call_fixture chunk = _ChunkFactory(chunk_type, stream_rdr_, offset) @@ -392,7 +379,7 @@ def stream_rdr_(self, request): return instance_mock(request, StreamReader) -class Describe_Chunk(object): +class Describe_Chunk: def it_can_construct_from_a_stream_and_offset(self): chunk_type = "fOOB" chunk = _Chunk.from_offset(chunk_type, None, None) @@ -400,7 +387,7 @@ def it_can_construct_from_a_stream_and_offset(self): assert chunk.type_name == chunk_type -class Describe_IHDRChunk(object): +class Describe_IHDRChunk: def it_can_construct_from_a_stream_and_offset(self, from_offset_fixture): stream_rdr, offset, px_width, px_height = from_offset_fixture ihdr_chunk = _IHDRChunk.from_offset(None, stream_rdr, offset) @@ -412,13 +399,13 @@ def it_can_construct_from_a_stream_and_offset(self, from_offset_fixture): @pytest.fixture def from_offset_fixture(self): - bytes_ = b"\x00\x00\x00\x2A\x00\x00\x00\x18" - stream_rdr = StreamReader(BytesIO(bytes_), BIG_ENDIAN) + bytes_ = b"\x00\x00\x00\x2a\x00\x00\x00\x18" + stream_rdr = StreamReader(io.BytesIO(bytes_), BIG_ENDIAN) offset, px_width, px_height = 0, 42, 24 return stream_rdr, offset, px_width, px_height -class Describe_pHYsChunk(object): +class Describe_pHYsChunk: def it_can_construct_from_a_stream_and_offset(self, from_offset_fixture): stream_rdr, offset = from_offset_fixture[:2] horz_px_per_unit, vert_px_per_unit = from_offset_fixture[2:4] @@ -433,7 +420,7 @@ def it_can_construct_from_a_stream_and_offset(self, from_offset_fixture): @pytest.fixture def from_offset_fixture(self): - bytes_ = b"\x00\x00\x00\x2A\x00\x00\x00\x18\x01" - stream_rdr = StreamReader(BytesIO(bytes_), BIG_ENDIAN) + bytes_ = b"\x00\x00\x00\x2a\x00\x00\x00\x18\x01" + stream_rdr = StreamReader(io.BytesIO(bytes_), BIG_ENDIAN) offset, horz_px_per_unit, vert_px_per_unit, units_specifier = (0, 42, 24, 1) return (stream_rdr, offset, horz_px_per_unit, vert_px_per_unit, units_specifier) diff --git a/tests/image/test_svg.py b/tests/image/test_svg.py index 9f45d4fb..abaaa842 100644 --- a/tests/image/test_svg.py +++ b/tests/image/test_svg.py @@ -74,22 +74,21 @@ def unit_value_data(request): return request.param -def test_parse_svg_unit_value(unit_value_data): - value_str, expected_value = unit_value_data - assert Svg._parse_svg_unit_value(value_str) == pytest.approx(expected_value) - - -def test_dimensions_from_stream(svg_stream_data): - stream_data, expected_width, expected_height = svg_stream_data - stream = io.BytesIO(stream_data) - width, height = Svg._dimensions_from_stream(stream) - assert width == expected_width - assert height == expected_height - - -def test_calculate_scaled_dimensions(viewbox_data): - viewbox, expected_width, expected_height, base_px = viewbox_data - width, height = Svg._calculate_scaled_dimensions(viewbox, base_px) - assert width == expected_width - assert height == expected_height +class DescribeSvg: + def it_parses_svg_unit_values(self, unit_value_data): + value_str, expected_value = unit_value_data + assert Svg._parse_svg_unit_value(value_str) == pytest.approx(expected_value) + + def it_gets_dimensions_from_stream(self, svg_stream_data): + stream_data, expected_width, expected_height = svg_stream_data + stream = io.BytesIO(stream_data) + width, height = Svg._dimensions_from_stream(stream) + assert width == expected_width + assert height == expected_height + + def it_calculates_scaled_dimensions(self, viewbox_data): + viewbox, expected_width, expected_height, base_px = viewbox_data + width, height = Svg._calculate_scaled_dimensions(viewbox, base_px) + assert width == expected_width + assert height == expected_height diff --git a/tests/image/test_tiff.py b/tests/image/test_tiff.py index a5f07acd..35344eed 100644 --- a/tests/image/test_tiff.py +++ b/tests/image/test_tiff.py @@ -1,15 +1,13 @@ -# encoding: utf-8 - """Unit test suite for docx.image.tiff module""" -from __future__ import absolute_import, print_function +import io import pytest -from docx.compat import BytesIO from docx.image.constants import MIME_TYPE, TIFF_TAG from docx.image.helpers import BIG_ENDIAN, LITTLE_ENDIAN, StreamReader from docx.image.tiff import ( + Tiff, _AsciiIfdEntry, _IfdEntries, _IfdEntry, @@ -18,7 +16,6 @@ _LongIfdEntry, _RationalIfdEntry, _ShortIfdEntry, - Tiff, _TiffParser, ) @@ -34,10 +31,8 @@ ) -class DescribeTiff(object): - def it_can_construct_from_a_tiff_stream( - self, stream_, _TiffParser_, tiff_parser_, Tiff__init_ - ): +class DescribeTiff: + def it_can_construct_from_a_tiff_stream(self, stream_, _TiffParser_, tiff_parser_, Tiff__init_): px_width, px_height = 111, 222 horz_dpi, vert_dpi = 333, 444 tiff_parser_.px_width = px_width @@ -48,9 +43,7 @@ def it_can_construct_from_a_tiff_stream( tiff = Tiff.from_stream(stream_) _TiffParser_.parse.assert_called_once_with(stream_) - Tiff__init_.assert_called_once_with( - ANY, px_width, px_height, horz_dpi, vert_dpi - ) + Tiff__init_.assert_called_once_with(ANY, px_width, px_height, horz_dpi, vert_dpi) assert isinstance(tiff, Tiff) def it_knows_its_content_type(self): @@ -79,10 +72,10 @@ def tiff_parser_(self, request): @pytest.fixture def stream_(self, request): - return instance_mock(request, BytesIO) + return instance_mock(request, io.BytesIO) -class Describe_TiffParser(object): +class Describe_TiffParser: def it_can_parse_the_properties_from_a_tiff_stream( self, stream_, @@ -180,18 +173,16 @@ def _make_stream_reader_(self, request, stream_rdr_): ) def mk_stream_rdr_fixture(self, request, StreamReader_, stream_rdr_): bytes_, endian = request.param - stream = BytesIO(bytes_) + stream = io.BytesIO(bytes_) return stream, StreamReader_, endian, stream_rdr_ @pytest.fixture def stream_(self, request): - return instance_mock(request, BytesIO) + return instance_mock(request, io.BytesIO) @pytest.fixture def StreamReader_(self, request, stream_rdr_): - return class_mock( - request, "docx.image.tiff.StreamReader", return_value=stream_rdr_ - ) + return class_mock(request, "docx.image.tiff.StreamReader", return_value=stream_rdr_) @pytest.fixture def stream_rdr_(self, request, ifd0_offset_): @@ -204,7 +195,7 @@ def _TiffParser__init_(self, request): return initializer_mock(request, _TiffParser) -class Describe_IfdEntries(object): +class Describe_IfdEntries: def it_can_construct_from_a_stream_and_offset( self, stream_, @@ -247,9 +238,7 @@ def _IfdEntries__init_(self, request): @pytest.fixture def _IfdParser_(self, request, ifd_parser_): - return class_mock( - request, "docx.image.tiff._IfdParser", return_value=ifd_parser_ - ) + return class_mock(request, "docx.image.tiff._IfdParser", return_value=ifd_parser_) @pytest.fixture def ifd_parser_(self, request): @@ -261,10 +250,10 @@ def offset_(self, request): @pytest.fixture def stream_(self, request): - return instance_mock(request, BytesIO) + return instance_mock(request, io.BytesIO) -class Describe_IfdParser(object): +class Describe_IfdParser: def it_can_iterate_through_the_directory_entries_in_an_IFD(self, iter_fixture): ( ifd_parser, @@ -273,7 +262,7 @@ def it_can_iterate_through_the_directory_entries_in_an_IFD(self, iter_fixture): offsets, expected_entries, ) = iter_fixture - entries = [e for e in ifd_parser.iter_entries()] + entries = list(ifd_parser.iter_entries()) assert _IfdEntryFactory_.call_args_list == [ call(stream_rdr, offsets[0]), call(stream_rdr, offsets[1]), @@ -300,14 +289,14 @@ def _IfdEntryFactory_(self, request, ifd_entry_, ifd_entry_2_): @pytest.fixture def iter_fixture(self, _IfdEntryFactory_, ifd_entry_, ifd_entry_2_): - stream_rdr = StreamReader(BytesIO(b"\x00\x02"), BIG_ENDIAN) + stream_rdr = StreamReader(io.BytesIO(b"\x00\x02"), BIG_ENDIAN) offsets = [2, 14] ifd_parser = _IfdParser(stream_rdr, offset=0) expected_entries = [ifd_entry_, ifd_entry_2_] return (ifd_parser, _IfdEntryFactory_, stream_rdr, offsets, expected_entries) -class Describe_IfdEntryFactory(object): +class Describe_IfdEntryFactory: def it_constructs_the_right_class_for_a_given_ifd_entry(self, fixture): stream_rdr, offset, entry_cls_, ifd_entry_ = fixture ifd_entry = _IfdEntryFactory(stream_rdr, offset) @@ -345,7 +334,7 @@ def fixture( "RATIONAL": _RationalIfdEntry_, "CUSTOM": _IfdEntry_, }[entry_type] - stream_rdr = StreamReader(BytesIO(bytes_), BIG_ENDIAN) + stream_rdr = StreamReader(io.BytesIO(bytes_), BIG_ENDIAN) offset = 0 return stream_rdr, offset, entry_cls_, ifd_entry_ @@ -388,20 +377,16 @@ def offset_(self, request): return instance_mock(request, int) -class Describe_IfdEntry(object): - def it_can_construct_from_a_stream_and_offset( - self, _parse_value_, _IfdEntry__init_, value_ - ): +class Describe_IfdEntry: + def it_can_construct_from_a_stream_and_offset(self, _parse_value_, _IfdEntry__init_, value_): bytes_ = b"\x00\x01\x66\x66\x00\x00\x00\x02\x00\x00\x00\x03" - stream_rdr = StreamReader(BytesIO(bytes_), BIG_ENDIAN) + stream_rdr = StreamReader(io.BytesIO(bytes_), BIG_ENDIAN) offset, tag_code, value_count, value_offset = 0, 1, 2, 3 _parse_value_.return_value = value_ ifd_entry = _IfdEntry.from_stream(stream_rdr, offset) - _parse_value_.assert_called_once_with( - stream_rdr, offset, value_count, value_offset - ) + _parse_value_.assert_called_once_with(stream_rdr, offset, value_count, value_offset) _IfdEntry__init_.assert_called_once_with(ANY, tag_code, value_) assert isinstance(ifd_entry, _IfdEntry) @@ -425,33 +410,33 @@ def value_(self, request): return loose_mock(request) -class Describe_AsciiIfdEntry(object): +class Describe_AsciiIfdEntry: def it_can_parse_an_ascii_string_IFD_entry(self): bytes_ = b"foobar\x00" - stream_rdr = StreamReader(BytesIO(bytes_), BIG_ENDIAN) + stream_rdr = StreamReader(io.BytesIO(bytes_), BIG_ENDIAN) val = _AsciiIfdEntry._parse_value(stream_rdr, None, 7, 0) assert val == "foobar" -class Describe_ShortIfdEntry(object): +class Describe_ShortIfdEntry: def it_can_parse_a_short_int_IFD_entry(self): - bytes_ = b"foobaroo\x00\x2A" - stream_rdr = StreamReader(BytesIO(bytes_), BIG_ENDIAN) + bytes_ = b"foobaroo\x00\x2a" + stream_rdr = StreamReader(io.BytesIO(bytes_), BIG_ENDIAN) val = _ShortIfdEntry._parse_value(stream_rdr, 0, 1, None) assert val == 42 -class Describe_LongIfdEntry(object): +class Describe_LongIfdEntry: def it_can_parse_a_long_int_IFD_entry(self): - bytes_ = b"foobaroo\x00\x00\x00\x2A" - stream_rdr = StreamReader(BytesIO(bytes_), BIG_ENDIAN) + bytes_ = b"foobaroo\x00\x00\x00\x2a" + stream_rdr = StreamReader(io.BytesIO(bytes_), BIG_ENDIAN) val = _LongIfdEntry._parse_value(stream_rdr, 0, 1, None) assert val == 42 -class Describe_RationalIfdEntry(object): +class Describe_RationalIfdEntry: def it_can_parse_a_rational_IFD_entry(self): - bytes_ = b"\x00\x00\x00\x2A\x00\x00\x00\x54" - stream_rdr = StreamReader(BytesIO(bytes_), BIG_ENDIAN) + bytes_ = b"\x00\x00\x00\x2a\x00\x00\x00\x54" + stream_rdr = StreamReader(io.BytesIO(bytes_), BIG_ENDIAN) val = _RationalIfdEntry._parse_value(stream_rdr, None, 1, 0) assert val == 0.5 diff --git a/tests/opc/parts/test_coreprops.py b/tests/opc/parts/test_coreprops.py index 66222cef..b754d2d7 100644 --- a/tests/opc/parts/test_coreprops.py +++ b/tests/opc/parts/test_coreprops.py @@ -1,53 +1,53 @@ -# encoding: utf-8 +"""Unit test suite for the docx.opc.parts.coreprops module.""" -""" -Unit test suite for the docx.opc.parts.coreprops module -""" +from __future__ import annotations -from __future__ import absolute_import, division, print_function, unicode_literals - -from datetime import datetime, timedelta +import datetime as dt import pytest from docx.opc.coreprops import CoreProperties +from docx.opc.package import OpcPackage +from docx.opc.packuri import PackURI from docx.opc.parts.coreprops import CorePropertiesPart -from docx.oxml.coreprops import CT_CoreProperties -from ...unitutil.mock import class_mock, instance_mock +from ...unitutil.cxml import element +from ...unitutil.mock import FixtureRequest, Mock, class_mock, instance_mock + +class DescribeCorePropertiesPart: + """Unit-test suite for `docx.opc.parts.coreprops.CorePropertiesPart` objects.""" + + def it_provides_access_to_its_core_props_object(self, CoreProperties_: Mock, package_: Mock): + core_properties_part = CorePropertiesPart( + PackURI("/part/name"), "content/type", element("cp:coreProperties"), package_ + ) -class DescribeCorePropertiesPart(object): - def it_provides_access_to_its_core_props_object(self, coreprops_fixture): - core_properties_part, CoreProperties_ = coreprops_fixture core_properties = core_properties_part.core_properties + CoreProperties_.assert_called_once_with(core_properties_part.element) assert isinstance(core_properties, CoreProperties) - def it_can_create_a_default_core_properties_part(self): - core_properties_part = CorePropertiesPart.default(None) + def it_can_create_a_default_core_properties_part(self, package_: Mock): + core_properties_part = CorePropertiesPart.default(package_) + assert isinstance(core_properties_part, CorePropertiesPart) + # -- core_properties = core_properties_part.core_properties assert core_properties.title == "Word Document" assert core_properties.last_modified_by == "python-docx" assert core_properties.revision == 1 - delta = datetime.utcnow() - core_properties.modified - max_expected_delta = timedelta(seconds=2) + assert core_properties.modified is not None + delta = dt.datetime.now(dt.timezone.utc) - core_properties.modified + max_expected_delta = dt.timedelta(seconds=2) assert delta < max_expected_delta # fixtures --------------------------------------------- @pytest.fixture - def coreprops_fixture(self, element_, CoreProperties_): - core_properties_part = CorePropertiesPart(None, None, element_, None) - return core_properties_part, CoreProperties_ - - # fixture components ----------------------------------- - - @pytest.fixture - def CoreProperties_(self, request): + def CoreProperties_(self, request: FixtureRequest): return class_mock(request, "docx.opc.parts.coreprops.CoreProperties") @pytest.fixture - def element_(self, request): - return instance_mock(request, CT_CoreProperties) + def package_(self, request: FixtureRequest): + return instance_mock(request, OpcPackage) diff --git a/tests/opc/test_coreprops.py b/tests/opc/test_coreprops.py index 97da5dea..5d974339 100644 --- a/tests/opc/test_coreprops.py +++ b/tests/opc/test_coreprops.py @@ -1,166 +1,153 @@ -# encoding: utf-8 +# pyright: reportPrivateUsage=false -""" -Unit test suite for the docx.opc.coreprops module -""" +"""Unit test suite for the docx.opc.coreprops module.""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import annotations -import pytest +import datetime as dt +from typing import TYPE_CHECKING, cast -from datetime import datetime +import pytest from docx.opc.coreprops import CoreProperties -from docx.oxml import parse_xml +from docx.oxml.parser import parse_xml + +if TYPE_CHECKING: + from docx.oxml.coreprops import CT_CoreProperties -class DescribeCoreProperties(object): - def it_knows_the_string_property_values(self, text_prop_get_fixture): - core_properties, prop_name, expected_value = text_prop_get_fixture +class DescribeCoreProperties: + """Unit-test suite for `docx.opc.coreprops.CoreProperties` objects.""" + + @pytest.mark.parametrize( + ("prop_name", "expected_value"), + [ + ("author", "python-docx"), + ("category", ""), + ("comments", ""), + ("content_status", "DRAFT"), + ("identifier", "GXS 10.2.1ab"), + ("keywords", "foo bar baz"), + ("language", "US-EN"), + ("last_modified_by", "Steve Canny"), + ("subject", "Spam"), + ("title", "Word Document"), + ("version", "1.2.88"), + ], + ) + def it_knows_the_string_property_values( + self, prop_name: str, expected_value: str, core_properties: CoreProperties + ): actual_value = getattr(core_properties, prop_name) assert actual_value == expected_value - def it_can_change_the_string_property_values(self, text_prop_set_fixture): - core_properties, prop_name, value, expected_xml = text_prop_set_fixture - setattr(core_properties, prop_name, value) - assert core_properties._element.xml == expected_xml - - def it_knows_the_date_property_values(self, date_prop_get_fixture): - core_properties, prop_name, expected_datetime = date_prop_get_fixture - actual_datetime = getattr(core_properties, prop_name) - assert actual_datetime == expected_datetime + @pytest.mark.parametrize( + ("prop_name", "tagname", "value"), + [ + ("author", "dc:creator", "scanny"), + ("category", "cp:category", "silly stories"), + ("comments", "dc:description", "Bar foo to you"), + ("content_status", "cp:contentStatus", "FINAL"), + ("identifier", "dc:identifier", "GT 5.2.xab"), + ("keywords", "cp:keywords", "dog cat moo"), + ("language", "dc:language", "GB-EN"), + ("last_modified_by", "cp:lastModifiedBy", "Billy Bob"), + ("subject", "dc:subject", "Eggs"), + ("title", "dc:title", "Dissertation"), + ("version", "cp:version", "81.2.8"), + ], + ) + def it_can_change_the_string_property_values(self, prop_name: str, tagname: str, value: str): + coreProperties = self.coreProperties(tagname="", str_val="") + core_properties = CoreProperties(cast("CT_CoreProperties", parse_xml(coreProperties))) - def it_can_change_the_date_property_values(self, date_prop_set_fixture): - core_properties, prop_name, value, expected_xml = date_prop_set_fixture setattr(core_properties, prop_name, value) - assert core_properties._element.xml == expected_xml - - def it_knows_the_revision_number(self, revision_get_fixture): - core_properties, expected_revision = revision_get_fixture - assert core_properties.revision == expected_revision - - def it_can_change_the_revision_number(self, revision_set_fixture): - core_properties, revision, expected_xml = revision_set_fixture - core_properties.revision = revision - assert core_properties._element.xml == expected_xml - # fixtures ------------------------------------------------------- + assert core_properties._element.xml == self.coreProperties(tagname, value) - @pytest.fixture( - params=[ - ("created", datetime(2012, 11, 17, 16, 37, 40)), - ("last_printed", datetime(2014, 6, 4, 4, 28)), + @pytest.mark.parametrize( + ("prop_name", "expected_datetime"), + [ + ("created", dt.datetime(2012, 11, 17, 16, 37, 40, tzinfo=dt.timezone.utc)), + ("last_printed", dt.datetime(2014, 6, 4, 4, 28, tzinfo=dt.timezone.utc)), ("modified", None), - ] + ], ) - def date_prop_get_fixture(self, request, core_properties): - prop_name, expected_datetime = request.param - return core_properties, prop_name, expected_datetime + def it_knows_the_date_property_values( + self, prop_name: str, expected_datetime: dt.datetime, core_properties: CoreProperties + ): + actual_datetime = getattr(core_properties, prop_name) + assert actual_datetime == expected_datetime - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("prop_name", "tagname", "value", "str_val", "attrs"), + [ ( "created", "dcterms:created", - datetime(2001, 2, 3, 4, 5), + dt.datetime(2001, 2, 3, 4, 5), "2001-02-03T04:05:00Z", ' xsi:type="dcterms:W3CDTF"', ), ( "last_printed", "cp:lastPrinted", - datetime(2014, 6, 4, 4), + dt.datetime(2014, 6, 4, 4), "2014-06-04T04:00:00Z", "", ), ( "modified", "dcterms:modified", - datetime(2005, 4, 3, 2, 1), + dt.datetime(2005, 4, 3, 2, 1), "2005-04-03T02:01:00Z", ' xsi:type="dcterms:W3CDTF"', ), - ] + ], ) - def date_prop_set_fixture(self, request): - prop_name, tagname, value, str_val, attrs = request.param - coreProperties = self.coreProperties(None, None) - core_properties = CoreProperties(parse_xml(coreProperties)) + def it_can_change_the_date_property_values( + self, prop_name: str, tagname: str, value: dt.datetime, str_val: str, attrs: str + ): + coreProperties = self.coreProperties(tagname="", str_val="") + core_properties = CoreProperties(cast("CT_CoreProperties", parse_xml(coreProperties))) expected_xml = self.coreProperties(tagname, str_val, attrs) - return core_properties, prop_name, value, expected_xml - @pytest.fixture( - params=[("42", 42), (None, 0), ("foobar", 0), ("-17", 0), ("32.7", 0)] - ) - def revision_get_fixture(self, request): - str_val, expected_revision = request.param - tagname = "" if str_val is None else "cp:revision" - coreProperties = self.coreProperties(tagname, str_val) - core_properties = CoreProperties(parse_xml(coreProperties)) - return core_properties, expected_revision - - @pytest.fixture( - params=[ - (42, "42"), - ] + setattr(core_properties, prop_name, value) + + assert core_properties._element.xml == expected_xml + + @pytest.mark.parametrize( + ("str_val", "expected_value"), + [("42", 42), (None, 0), ("foobar", 0), ("-17", 0), ("32.7", 0)], ) - def revision_set_fixture(self, request): - value, str_val = request.param - coreProperties = self.coreProperties(None, None) - core_properties = CoreProperties(parse_xml(coreProperties)) + def it_knows_the_revision_number(self, str_val: str | None, expected_value: int): + tagname, str_val = ("cp:revision", str_val) if str_val else ("", "") + coreProperties = self.coreProperties(tagname, str_val or "") + core_properties = CoreProperties(cast("CT_CoreProperties", parse_xml(coreProperties))) + + assert core_properties.revision == expected_value + + @pytest.mark.parametrize(("value", "str_val"), [(42, "42")]) + def it_can_change_the_revision_number(self, value: int, str_val: str): + coreProperties = self.coreProperties(tagname="", str_val="") + core_properties = CoreProperties(cast("CT_CoreProperties", parse_xml(coreProperties))) expected_xml = self.coreProperties("cp:revision", str_val) - return core_properties, value, expected_xml - @pytest.fixture( - params=[ - ("author", "python-docx"), - ("category", ""), - ("comments", ""), - ("content_status", "DRAFT"), - ("identifier", "GXS 10.2.1ab"), - ("keywords", "foo bar baz"), - ("language", "US-EN"), - ("last_modified_by", "Steve Canny"), - ("subject", "Spam"), - ("title", "Word Document"), - ("version", "1.2.88"), - ] - ) - def text_prop_get_fixture(self, request, core_properties): - prop_name, expected_value = request.param - return core_properties, prop_name, expected_value + core_properties.revision = value - @pytest.fixture( - params=[ - ("author", "dc:creator", "scanny"), - ("category", "cp:category", "silly stories"), - ("comments", "dc:description", "Bar foo to you"), - ("content_status", "cp:contentStatus", "FINAL"), - ("identifier", "dc:identifier", "GT 5.2.xab"), - ("keywords", "cp:keywords", "dog cat moo"), - ("language", "dc:language", "GB-EN"), - ("last_modified_by", "cp:lastModifiedBy", "Billy Bob"), - ("subject", "dc:subject", "Eggs"), - ("title", "dc:title", "Dissertation"), - ("version", "cp:version", "81.2.8"), - ] - ) - def text_prop_set_fixture(self, request): - prop_name, tagname, value = request.param - coreProperties = self.coreProperties(None, None) - core_properties = CoreProperties(parse_xml(coreProperties)) - expected_xml = self.coreProperties(tagname, value) - return core_properties, prop_name, value, expected_xml + assert core_properties._element.xml == expected_xml - # fixture components --------------------------------------------- + # fixtures ------------------------------------------------------- - def coreProperties(self, tagname, str_val, attrs=""): + def coreProperties(self, tagname: str, str_val: str, attrs: str = "") -> str: tmpl = ( - '%s\n' + "%s\n" ) if not tagname: child_element = "" @@ -172,27 +159,30 @@ def coreProperties(self, tagname, str_val, attrs=""): @pytest.fixture def core_properties(self): - element = parse_xml( - b"" - b'\n\n' - b" DRAFT\n" - b" python-docx\n" - b' 2012-11-17T11:07:' - b"40-05:30\n" - b" \n" - b" GXS 10.2.1ab\n" - b" US-EN\n" - b" 2014-06-04T04:28:00Z\n" - b" foo bar baz\n" - b" Steve Canny\n" - b" 4\n" - b" Spam\n" - b" Word Document\n" - b" 1.2.88\n" - b"\n" + element = cast( + "CT_CoreProperties", + parse_xml( + b"" + b'\n\n' + b" DRAFT\n" + b" python-docx\n" + b' 2012-11-17T11:07:' + b"40-05:30\n" + b" \n" + b" GXS 10.2.1ab\n" + b" US-EN\n" + b" 2014-06-04T04:28:00Z\n" + b" foo bar baz\n" + b" Steve Canny\n" + b" 4\n" + b" Spam\n" + b" Word Document\n" + b" 1.2.88\n" + b"\n" + ), ) return CoreProperties(element) diff --git a/tests/opc/test_customprops.py b/tests/opc/test_customprops.py index 1d5e1838..b63d038b 100644 --- a/tests/opc/test_customprops.py +++ b/tests/opc/test_customprops.py @@ -2,6 +2,7 @@ Unit test suite for the docx.opc.customprops module """ import pytest +from lxml import etree from docx.opc.customprops import CustomProperties from docx.oxml import parse_xml @@ -17,9 +18,9 @@ def it_can_change_existing_prop_values(self): pass def it_can_set_new_prop_values(self, prop_set_fixture): - custom_properties, prop_name, value, exp_xml = prop_set_fixture + custom_properties, prop_name, value, expected_xml = prop_set_fixture custom_properties[prop_name] = value - assert custom_properties._element.xml == exp_xml + assert etree.tostring(custom_properties._element, pretty_print=True).decode() == expected_xml # fixtures ------------------------------------------------------- @@ -44,40 +45,35 @@ def prop_get_fixture(self, request, custom_properties_default): ) def prop_set_fixture(self, request, custom_properties_blank): prop_name, str_type, str_value, value = request.param - expected_xml = self.custom_properties(prop_name, str_type, str_value) + # The actual code generates pid="2" for the first prop. + expected_xml = self.custom_properties(prop_name, str_type, str_value, pid="2") return custom_properties_blank, prop_name, value, expected_xml # fixture components --------------------------------------------- - def custom_properties(self, prop_name, str_type, str_value): - tmpl = ( - '\n' - ' \n' - " %s\n" - " \n" - "" - ) - return tmpl % (prop_name, str_type, str_value, str_type) + def custom_properties(self, prop_name, str_type, str_value, pid): + # Using triple-quotes for safe multi-line string definition + tmpl = f''' + + {str_value} + + +''' + return tmpl @pytest.fixture def custom_properties_blank(self): - element = parse_xml( - '' - "\n" - ) + xml = '''''' + element = parse_xml(xml) return CustomProperties(element) @pytest.fixture def custom_properties_default(self): - element = parse_xml( - b'\n' - b'\n' - b' 1\n' - b' 13\n' - b' Test String\n' - b"\n" - ) + xml = b''' + + 1 + 13 + Test String +''' + element = parse_xml(xml) return CustomProperties(element) diff --git a/tests/opc/test_oxml.py b/tests/opc/test_oxml.py index c269bde3..0b3e5e36 100644 --- a/tests/opc/test_oxml.py +++ b/tests/opc/test_oxml.py @@ -1,8 +1,4 @@ -# encoding: utf-8 - -""" -Test suite for opc.oxml module -""" +"""Test suite for opc.oxml module.""" from docx.opc.constants import RELATIONSHIP_TARGET_MODE as RTM from docx.opc.oxml import ( @@ -16,14 +12,14 @@ from .unitdata.rels import ( a_Default, - an_Override, a_Relationship, a_Relationships, a_Types, + an_Override, ) -class DescribeCT_Default(object): +class DescribeCT_Default: def it_provides_read_access_to_xml_values(self): default = a_Default().element assert default.extension == "xml" @@ -35,7 +31,7 @@ def it_can_construct_a_new_default_element(self): assert default.xml == expected_xml -class DescribeCT_Override(object): +class DescribeCT_Override: def it_provides_read_access_to_xml_values(self): override = an_Override().element assert override.partname == "/part/name.xml" @@ -47,7 +43,7 @@ def it_can_construct_a_new_override_element(self): assert override.xml == expected_xml -class DescribeCT_Relationship(object): +class DescribeCT_Relationship: def it_provides_read_access_to_xml_values(self): rel = a_Relationship().element assert rel.rId == "rId9" @@ -73,7 +69,7 @@ def it_can_construct_from_attribute_values(self): assert rel.xml == expected_rel_xml -class DescribeCT_Relationships(object): +class DescribeCT_Relationships: def it_can_construct_a_new_relationships_element(self): rels = CT_Relationships.new() expected_xml = ( @@ -102,7 +98,7 @@ def it_can_generate_rels_file_xml(self): assert CT_Relationships.new().xml == expected_xml -class DescribeCT_Types(object): +class DescribeCT_Types: def it_provides_access_to_default_child_elements(self): types = a_Types().element assert len(types.defaults) == 2 diff --git a/tests/opc/test_package.py b/tests/opc/test_package.py index e2edb3ae..7ad65a0d 100644 --- a/tests/opc/test_package.py +++ b/tests/opc/test_package.py @@ -1,8 +1,8 @@ -# encoding: utf-8 +# pyright: reportPrivateUsage=false """Unit test suite for docx.opc.package module""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import annotations import pytest @@ -13,22 +13,24 @@ from docx.opc.part import Part from docx.opc.parts.coreprops import CorePropertiesPart from docx.opc.pkgreader import PackageReader -from docx.opc.rel import _Relationship, Relationships +from docx.opc.rel import Relationships, _Relationship from ..unitutil.mock import ( + FixtureRequest, + Mock, call, class_mock, instance_mock, loose_mock, method_mock, - Mock, patch, - PropertyMock, property_mock, ) -class DescribeOpcPackage(object): +class DescribeOpcPackage: + """Unit-test suite for `docx.opc.package.OpcPackage` objects.""" + def it_can_open_a_pkg_file(self, PackageReader_, PartFactory_, Unmarshaller_): # mockery ---------------------- pkg_file = Mock(name="pkg_file") @@ -46,19 +48,26 @@ def it_initializes_its_rels_collection_on_first_reference(self, Relationships_): Relationships_.assert_called_once_with(PACKAGE_URI.baseURI) assert rels == Relationships_.return_value - def it_can_add_a_relationship_to_a_part(self, pkg_with_rels_, rel_attrs_): - reltype, target, rId = rel_attrs_ - pkg = pkg_with_rels_ - # exercise --------------------- - pkg.load_rel(reltype, target, rId) - # verify ----------------------- - pkg._rels.add_relationship.assert_called_once_with(reltype, target, rId, False) + def it_can_add_a_relationship_to_a_part(self, rels_prop_: Mock, rels_: Mock, part_: Mock): + rels_prop_.return_value = rels_ + pkg = OpcPackage() + + pkg.load_rel("http://rel/type", part_, "rId99") - def it_can_establish_a_relationship_to_another_part(self, relate_to_part_fixture_): - pkg, part_, reltype, rId = relate_to_part_fixture_ - _rId = pkg.relate_to(part_, reltype) - pkg.rels.get_or_add.assert_called_once_with(reltype, part_) - assert _rId == rId + rels_.add_relationship.assert_called_once_with("http://rel/type", part_, "rId99", False) + + def it_can_establish_a_relationship_to_another_part( + self, rels_prop_: Mock, rels_: Mock, rel_: Mock, part_: Mock + ): + rel_.rId = "rId99" + rels_.get_or_add.return_value = rel_ + rels_prop_.return_value = rels_ + pkg = OpcPackage() + + rId = pkg.relate_to(part_, "http://rel/type") + + rels_.get_or_add.assert_called_once_with("http://rel/type", part_) + assert rId == "rId99" def it_can_provide_a_list_of_the_parts_it_contains(self): # mockery ---------------------- @@ -68,7 +77,7 @@ def it_can_provide_a_list_of_the_parts_it_contains(self): with patch.object(OpcPackage, "iter_parts", return_value=parts): assert pkg.parts == [parts[0], parts[1]] - def it_can_iterate_over_parts_by_walking_rels_graph(self): + def it_can_iterate_over_parts_by_walking_rels_graph(self, rels_prop_: Mock): # +----------+ +--------+ # | pkg_rels |-----> | part_1 | # +----------+ +--------+ @@ -81,14 +90,14 @@ def it_can_iterate_over_parts_by_walking_rels_graph(self): part1.rels = {1: Mock(name="rel1", is_external=False, target_part=part2)} part2.rels = {1: Mock(name="rel2", is_external=False, target_part=part1)} pkg = OpcPackage() - pkg._rels = { + rels_prop_.return_value = { 1: Mock(name="rel3", is_external=False, target_part=part1), 2: Mock(name="rel4", is_external=True), } # verify ----------------------- assert part1 in pkg.iter_parts() assert part2 in pkg.iter_parts() - assert len([p for p in pkg.iter_parts()]) == 2 + assert len(list(pkg.iter_parts())) == 2 def it_can_find_the_next_available_vector_partname( self, next_partname_fixture, iter_parts_, PackURI_, packuri_ @@ -104,27 +113,54 @@ def it_can_find_the_next_available_vector_partname( PackURI_.assert_called_once_with(expected_value) assert partname is packuri_ + def it_can_drop_relationships_by_cmp_function(self, rels_prop_: Mock, rels_: Mock): + """Test drop_rels method.""" + # mockery ---------------------- + pkg = OpcPackage() + rels_prop_.return_value = rels_ + + # create mock relationships + rel1 = Mock(name="rel1", rId="rId1", is_external=True) + rel2 = Mock(name="rel2", rId="rId2", is_external=False) + rel3 = Mock(name="rel3", rId="rId3", is_external=True) + + rels_.items.return_value = [("rId1", rel1), ("rId2", rel2), ("rId3", rel3)] + + # define cmp function that matches external relationships + def is_external(rel): + return rel.is_external + + # exercise --------------------- + dropped_rids = pkg.drop_rels(is_external) + + # verify ----------------------- + assert dropped_rids == ["rId1", "rId3"] + rels_.__delitem__.assert_any_call("rId1") + rels_.__delitem__.assert_any_call("rId3") + assert rels_.__delitem__.call_count == 2 + def it_can_find_a_part_related_by_reltype(self, related_part_fixture_): pkg, reltype, related_part_ = related_part_fixture_ related_part = pkg.part_related_by(reltype) pkg.rels.part_with_reltype.assert_called_once_with(reltype) assert related_part is related_part_ - def it_can_save_to_a_pkg_file(self, pkg_file_, PackageWriter_, parts, parts_): + def it_can_save_to_a_pkg_file( + self, pkg_file_: Mock, PackageWriter_: Mock, parts_prop_: Mock, parts_: list[Mock] + ): + parts_prop_.return_value = parts_ pkg = OpcPackage() pkg.save(pkg_file_) for part in parts_: part.before_marshal.assert_called_once_with() - PackageWriter_.write.assert_called_once_with(pkg_file_, pkg._rels, parts_) + PackageWriter_.write.assert_called_once_with(pkg_file_, pkg.rels, parts_) def it_provides_access_to_the_core_properties(self, core_props_fixture): opc_package, core_properties_ = core_props_fixture core_properties = opc_package.core_properties assert core_properties is core_properties_ - def it_provides_access_to_the_core_properties_part_to_help( - self, core_props_part_fixture - ): + def it_provides_access_to_the_core_properties_part_to_help(self, core_props_part_fixture): opc_package, core_properties_part_ = core_props_part_fixture core_properties_part = opc_package._core_properties_part assert core_properties_part is core_properties_part_ @@ -139,9 +175,7 @@ def it_creates_a_default_core_props_part_if_none_present( core_properties_part = opc_package._core_properties_part CorePropertiesPart_.default.assert_called_once_with(opc_package) - relate_to_.assert_called_once_with( - opc_package, core_properties_part_, RT.CORE_PROPERTIES - ) + relate_to_.assert_called_once_with(opc_package, core_properties_part_, RT.CORE_PROPERTIES) assert core_properties_part is core_properties_part_ # fixtures --------------------------------------------- @@ -165,138 +199,110 @@ def core_props_part_fixture(self, part_related_by_, core_properties_part_): def next_partname_fixture(self, request, iter_parts_): existing_partname_ns, next_partname_n = request.param parts_ = [ - instance_mock( - request, Part, name="part[%d]" % idx, partname="/foo/bar/baz%d.xml" % n - ) + instance_mock(request, Part, name="part[%d]" % idx, partname="/foo/bar/baz%d.xml" % n) for idx, n in enumerate(existing_partname_ns) ] expected_value = "/foo/bar/baz%d.xml" % next_partname_n return parts_, expected_value @pytest.fixture - def relate_to_part_fixture_(self, request, pkg, rels_, reltype): - rId = "rId99" - rel_ = instance_mock(request, _Relationship, name="rel_", rId=rId) - rels_.get_or_add.return_value = rel_ - pkg._rels = rels_ - part_ = instance_mock(request, Part, name="part_") - return pkg, part_, reltype, rId - - @pytest.fixture - def related_part_fixture_(self, request, rels_, reltype): + def related_part_fixture_(self, request: FixtureRequest, rels_prop_: Mock, rels_: Mock): related_part_ = instance_mock(request, Part, name="related_part_") rels_.part_with_reltype.return_value = related_part_ pkg = OpcPackage() - pkg._rels = rels_ - return pkg, reltype, related_part_ + rels_prop_.return_value = rels_ + return pkg, "http://rel/type", related_part_ # fixture components ----------------------------------- @pytest.fixture - def CorePropertiesPart_(self, request): + def CorePropertiesPart_(self, request: FixtureRequest): return class_mock(request, "docx.opc.package.CorePropertiesPart") @pytest.fixture - def core_properties_(self, request): + def core_properties_(self, request: FixtureRequest): return instance_mock(request, CoreProperties) @pytest.fixture - def core_properties_part_(self, request): + def core_properties_part_(self, request: FixtureRequest): return instance_mock(request, CorePropertiesPart) @pytest.fixture - def _core_properties_part_prop_(self, request): + def _core_properties_part_prop_(self, request: FixtureRequest): return property_mock(request, OpcPackage, "_core_properties_part") @pytest.fixture - def iter_parts_(self, request): + def iter_parts_(self, request: FixtureRequest): return method_mock(request, OpcPackage, "iter_parts") @pytest.fixture - def PackageReader_(self, request): + def PackageReader_(self, request: FixtureRequest): return class_mock(request, "docx.opc.package.PackageReader") @pytest.fixture - def PackURI_(self, request): + def PackURI_(self, request: FixtureRequest): return class_mock(request, "docx.opc.package.PackURI") @pytest.fixture - def packuri_(self, request): + def packuri_(self, request: FixtureRequest): return instance_mock(request, PackURI) @pytest.fixture - def PackageWriter_(self, request): + def PackageWriter_(self, request: FixtureRequest): return class_mock(request, "docx.opc.package.PackageWriter") @pytest.fixture - def PartFactory_(self, request): + def PartFactory_(self, request: FixtureRequest): return class_mock(request, "docx.opc.package.PartFactory") @pytest.fixture - def part_related_by_(self, request): - return method_mock(request, OpcPackage, "part_related_by") + def part_(self, request: FixtureRequest): + return instance_mock(request, Part) @pytest.fixture - def parts(self, request, parts_): - """ - Return a mock patching property OpcPackage.parts, reversing the - patch after each use. - """ - _patch = patch.object( - OpcPackage, "parts", new_callable=PropertyMock, return_value=parts_ - ) - request.addfinalizer(_patch.stop) - return _patch.start() + def part_related_by_(self, request: FixtureRequest): + return method_mock(request, OpcPackage, "part_related_by") @pytest.fixture - def parts_(self, request): + def parts_(self, request: FixtureRequest): part_ = instance_mock(request, Part, name="part_") part_2_ = instance_mock(request, Part, name="part_2_") return [part_, part_2_] @pytest.fixture - def pkg(self, request): - return OpcPackage() + def parts_prop_(self, request: FixtureRequest): + return property_mock(request, OpcPackage, "parts") @pytest.fixture - def pkg_file_(self, request): + def pkg_file_(self, request: FixtureRequest): return loose_mock(request) @pytest.fixture - def pkg_with_rels_(self, request, rels_): - pkg = OpcPackage() - pkg._rels = rels_ - return pkg - - @pytest.fixture - def Relationships_(self, request): + def Relationships_(self, request: FixtureRequest): return class_mock(request, "docx.opc.package.Relationships") @pytest.fixture - def rel_attrs_(self, request): - reltype = "http://rel/type" - target_ = instance_mock(request, Part, name="target_") - rId = "rId99" - return reltype, target_, rId + def rel_(self, request: FixtureRequest): + return instance_mock(request, _Relationship) @pytest.fixture - def relate_to_(self, request): + def relate_to_(self, request: FixtureRequest): return method_mock(request, OpcPackage, "relate_to") @pytest.fixture - def rels_(self, request): + def rels_(self, request: FixtureRequest): return instance_mock(request, Relationships) @pytest.fixture - def reltype(self, request): - return "http://rel/type" + def rels_prop_(self, request: FixtureRequest): + return property_mock(request, OpcPackage, "rels") @pytest.fixture - def Unmarshaller_(self, request): + def Unmarshaller_(self, request: FixtureRequest): return class_mock(request, "docx.opc.package.Unmarshaller") -class DescribeUnmarshaller(object): +class DescribeUnmarshaller: def it_can_unmarshal_from_a_pkg_reader( self, pkg_reader_, @@ -310,9 +316,7 @@ def it_can_unmarshal_from_a_pkg_reader( Unmarshaller.unmarshal(pkg_reader_, pkg_, part_factory_) _unmarshal_parts_.assert_called_once_with(pkg_reader_, pkg_, part_factory_) - _unmarshal_relationships_.assert_called_once_with( - pkg_reader_, pkg_, parts_dict_ - ) + _unmarshal_relationships_.assert_called_once_with(pkg_reader_, pkg_, parts_dict_) for part in parts_dict_.values(): part.after_unmarshal.assert_called_once_with() pkg_.after_unmarshal.assert_called_once_with() @@ -410,13 +414,13 @@ def it_can_unmarshal_relationships(self): # fixtures --------------------------------------------- @pytest.fixture - def blobs_(self, request): + def blobs_(self, request: FixtureRequest): blob_ = loose_mock(request, spec=str, name="blob_") blob_2_ = loose_mock(request, spec=str, name="blob_2_") return blob_, blob_2_ @pytest.fixture - def content_types_(self, request): + def content_types_(self, request: FixtureRequest): content_type_ = loose_mock(request, spec=str, name="content_type_") content_type_2_ = loose_mock(request, spec=str, name="content_type_2_") return content_type_, content_type_2_ @@ -428,13 +432,13 @@ def part_factory_(self, request, parts_): return part_factory_ @pytest.fixture - def partnames_(self, request): + def partnames_(self, request: FixtureRequest): partname_ = loose_mock(request, spec=str, name="partname_") partname_2_ = loose_mock(request, spec=str, name="partname_2_") return partname_, partname_2_ @pytest.fixture - def parts_(self, request): + def parts_(self, request: FixtureRequest): part_ = instance_mock(request, Part, name="part_") part_2_ = instance_mock(request, Part, name="part_2") return part_, part_2_ @@ -446,7 +450,7 @@ def parts_dict_(self, request, partnames_, parts_): return {partname_: part_, partname_2_: part_2_} @pytest.fixture - def pkg_(self, request): + def pkg_(self, request: FixtureRequest): return instance_mock(request, OpcPackage) @pytest.fixture @@ -464,17 +468,15 @@ def pkg_reader_(self, request, partnames_, content_types_, reltypes_, blobs_): return pkg_reader_ @pytest.fixture - def reltypes_(self, request): + def reltypes_(self, request: FixtureRequest): reltype_ = instance_mock(request, str, name="reltype_") reltype_2_ = instance_mock(request, str, name="reltype_2") return reltype_, reltype_2_ @pytest.fixture - def _unmarshal_parts_(self, request): + def _unmarshal_parts_(self, request: FixtureRequest): return method_mock(request, Unmarshaller, "_unmarshal_parts", autospec=False) @pytest.fixture - def _unmarshal_relationships_(self, request): - return method_mock( - request, Unmarshaller, "_unmarshal_relationships", autospec=False - ) + def _unmarshal_relationships_(self, request: FixtureRequest): + return method_mock(request, Unmarshaller, "_unmarshal_relationships", autospec=False) diff --git a/tests/opc/test_packuri.py b/tests/opc/test_packuri.py index a56badcd..987da69c 100644 --- a/tests/opc/test_packuri.py +++ b/tests/opc/test_packuri.py @@ -1,19 +1,15 @@ -# encoding: utf-8 - -""" -Test suite for the docx.opc.packuri module -""" +"""Test suite for the docx.opc.packuri module.""" import pytest from docx.opc.packuri import PackURI -class DescribePackURI(object): +class DescribePackURI: def cases(self, expected_values): """ Return list of tuples zipped from uri_str cases and - *expected_values*. Raise if lengths don't match. + `expected_values`. Raise if lengths don't match. """ uri_str_cases = [ "/", @@ -33,7 +29,7 @@ def it_can_construct_from_relative_ref(self): assert pack_uri == "/ppt/slideLayouts/slideLayout1.xml" def it_should_raise_on_construct_with_bad_pack_uri_str(self): - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="PackURI must begin with slash"): PackURI("foobar") def it_can_calculate_baseURI(self): diff --git a/tests/opc/test_part.py b/tests/opc/test_part.py index 6de08c95..50e98976 100644 --- a/tests/opc/test_part.py +++ b/tests/opc/test_part.py @@ -1,8 +1,10 @@ -# encoding: utf-8 +# pyright: reportPrivateUsage=false + +# pyright: basic, reportPrivateUsage=false """Unit test suite for docx.opc.part module""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import annotations import pytest @@ -15,6 +17,7 @@ from ..unitutil.cxml import element from ..unitutil.mock import ( ANY, + FixtureRequest, Mock, class_mock, cls_attr_mock, @@ -22,251 +25,183 @@ initializer_mock, instance_mock, loose_mock, + property_mock, ) -class DescribePart(object): - def it_can_be_constructed_by_PartFactory( - self, partname_, content_type_, blob_, package_, __init_ - ): - part = Part.load(partname_, content_type_, blob_, package_) +class DescribePart: + """Unit-test suite for `docx.opc.part.Part` objects.""" + + def it_can_be_constructed_by_PartFactory(self, package_: Mock, init__: Mock): + part = Part.load(PackURI("/part/name"), "content/type", b"1be2", package_) - __init_.assert_called_once_with(ANY, partname_, content_type_, blob_, package_) + init__.assert_called_once_with(ANY, "/part/name", "content/type", b"1be2", package_) assert isinstance(part, Part) - def it_knows_its_partname(self, partname_get_fixture): - part, expected_partname = partname_get_fixture - assert part.partname == expected_partname + def it_knows_its_partname(self): + part = Part(PackURI("/part/name"), "content/type") + assert part.partname == "/part/name" + + def it_can_change_its_partname(self): + part = Part(PackURI("/old/part/name"), "content/type") + part.partname = PackURI("/new/part/name") + assert part.partname == "/new/part/name" + + def it_knows_its_content_type(self): + part = Part(PackURI("/part/name"), "content/type") + assert part.content_type == "content/type" + + def it_compares_equal_by_type_and_partname(self): + part = Part(PackURI("/part/name"), "content/type") + same_part = Part(PackURI("/part/name"), "another/type") - def it_can_change_its_partname(self, partname_set_fixture): - part, new_partname = partname_set_fixture - part.partname = new_partname - assert part.partname == new_partname + assert part == same_part - def it_knows_its_content_type(self, content_type_fixture): - part, expected_content_type = content_type_fixture - assert part.content_type == expected_content_type + different_part = Part(PackURI("/other/name"), "content/type") - def it_knows_the_package_it_belongs_to(self, package_get_fixture): - part, expected_package = package_get_fixture - assert part.package == expected_package + assert part != different_part - def it_can_be_notified_after_unmarshalling_is_complete(self, part): + def it_knows_the_package_it_belongs_to(self, package_: Mock): + part = Part(PackURI("/part/name"), "content/type", package=package_) + assert part.package is package_ + + def it_can_be_notified_after_unmarshalling_is_complete(self): + part = Part(PackURI("/part/name"), "content/type") part.after_unmarshal() - def it_can_be_notified_before_marshalling_is_started(self, part): + def it_can_be_notified_before_marshalling_is_started(self): + part = Part(PackURI("/part/name"), "content/type") part.before_marshal() - def it_uses_the_load_blob_as_its_blob(self, blob_fixture): - part, load_blob = blob_fixture - assert part.blob is load_blob + def it_uses_the_load_blob_as_its_blob(self): + blob = b"abcde" + part = Part(PackURI("/part/name"), "content/type", blob) + assert part.blob is blob # fixtures --------------------------------------------- @pytest.fixture - def blob_fixture(self, blob_): - part = Part(None, None, blob_, None) - return part, blob_ + def init__(self, request: FixtureRequest): + return initializer_mock(request, Part) @pytest.fixture - def content_type_fixture(self): - content_type = "content/type" - part = Part(None, content_type, None, None) - return part, content_type + def package_(self, request: FixtureRequest): + return instance_mock(request, OpcPackage) - @pytest.fixture - def package_get_fixture(self, package_): - part = Part(None, None, None, package_) - return part, package_ - @pytest.fixture - def part(self): - return Part(None, None) +class DescribePartRelationshipManagementInterface: + """Unit-test suite for `docx.opc.package.Part` relationship behaviors.""" - @pytest.fixture - def partname_get_fixture(self): - partname = PackURI("/part/name") - part = Part(partname, None, None, None) - return part, partname + def it_provides_access_to_its_relationships( + self, Relationships_: Mock, partname_: Mock, rels_: Mock + ): + Relationships_.return_value = rels_ + part = Part(partname_, "content_type") - @pytest.fixture - def partname_set_fixture(self): - old_partname = PackURI("/old/part/name") - new_partname = PackURI("/new/part/name") - part = Part(old_partname, None, None, None) - return part, new_partname + rels = part.rels - # fixture components --------------------------------------------- + Relationships_.assert_called_once_with(partname_.baseURI) + assert rels is rels_ - @pytest.fixture - def blob_(self, request): - return instance_mock(request, bytes) + def it_can_load_a_relationship(self, rels_prop_: Mock, rels_: Mock, other_part_: Mock): + rels_prop_.return_value = rels_ + part = Part(PackURI("/part/name"), "content/type") - @pytest.fixture - def content_type_(self, request): - return instance_mock(request, str) + part.load_rel("http://rel/type", other_part_, "rId42") - @pytest.fixture - def __init_(self, request): - return initializer_mock(request, Part) - - @pytest.fixture - def package_(self, request): - return instance_mock(request, OpcPackage) + rels_.add_relationship.assert_called_once_with( + "http://rel/type", other_part_, "rId42", False + ) - @pytest.fixture - def partname_(self, request): - return instance_mock(request, PackURI) + def it_can_establish_a_relationship_to_another_part( + self, rels_prop_: Mock, rels_: Mock, rel_: Mock, other_part_: Mock + ): + rels_prop_.return_value = rels_ + rels_.get_or_add.return_value = rel_ + rel_.rId = "rId18" + part = Part(PackURI("/part/name"), "content/type") + rId = part.relate_to(other_part_, "http://rel/type") -class DescribePartRelationshipManagementInterface(object): - def it_provides_access_to_its_relationships(self, rels_fixture): - part, Relationships_, partname_, rels_ = rels_fixture - rels = part.rels - Relationships_.assert_called_once_with(partname_.baseURI) - assert rels is rels_ + rels_.get_or_add.assert_called_once_with("http://rel/type", other_part_) + assert rId == "rId18" - def it_can_load_a_relationship(self, load_rel_fixture): - part, rels_, reltype_, target_, rId_ = load_rel_fixture - part.load_rel(reltype_, target_, rId_) - rels_.add_relationship.assert_called_once_with(reltype_, target_, rId_, False) - - def it_can_establish_a_relationship_to_another_part(self, relate_to_part_fixture): - part, target_, reltype_, rId_ = relate_to_part_fixture - rId = part.relate_to(target_, reltype_) - part.rels.get_or_add.assert_called_once_with(reltype_, target_) - assert rId is rId_ - - def it_can_establish_an_external_relationship(self, relate_to_url_fixture): - part, url_, reltype_, rId_ = relate_to_url_fixture - rId = part.relate_to(url_, reltype_, is_external=True) - part.rels.get_or_add_ext_rel.assert_called_once_with(reltype_, url_) - assert rId is rId_ - - def it_can_drop_a_relationship(self, drop_rel_fixture): - part, rId, rel_should_be_gone = drop_rel_fixture - part.drop_rel(rId) - if rel_should_be_gone: - assert rId not in part.rels - else: - assert rId in part.rels - - def it_can_find_a_related_part_by_reltype(self, related_part_fixture): - part, reltype_, related_part_ = related_part_fixture - related_part = part.part_related_by(reltype_) - part.rels.part_with_reltype.assert_called_once_with(reltype_) - assert related_part is related_part_ - - def it_can_find_a_related_part_by_rId(self, related_parts_fixture): - part, related_parts_ = related_parts_fixture - assert part.related_parts is related_parts_ - - def it_can_find_the_uri_of_an_external_relationship(self, target_ref_fixture): - part, rId_, url_ = target_ref_fixture - url = part.target_ref(rId_) - assert url == url_ + def it_can_establish_an_external_relationship(self, rels_prop_: Mock, rels_: Mock): + rels_prop_.return_value = rels_ + rels_.get_or_add_ext_rel.return_value = "rId27" + part = Part(PackURI("/part/name"), "content/type") - # fixtures --------------------------------------------- + rId = part.relate_to("https://hyper/link", "http://rel/type", is_external=True) - @pytest.fixture( - params=[ - ("w:p", True), - ("w:p/r:a{r:id=rId42}", True), - ("w:p/r:a{r:id=rId42}/r:b{r:id=rId42}", False), - ] - ) - def drop_rel_fixture(self, request, part): - part_cxml, rel_should_be_dropped = request.param - rId = "rId42" - part._element = element(part_cxml) - part._rels = {rId: None} - return part, rId, rel_should_be_dropped + rels_.get_or_add_ext_rel.assert_called_once_with("http://rel/type", "https://hyper/link") + assert rId == "rId27" - @pytest.fixture - def load_rel_fixture(self, part, rels_, reltype_, part_, rId_): - part._rels = rels_ - return part, rels_, reltype_, part_, rId_ + def it_can_drop_a_relationship(self, rels_prop_: Mock): + rels_prop_.return_value = {"rId42": None} + part = Part(PackURI("/partname"), "content_type") - @pytest.fixture - def relate_to_part_fixture(self, request, part, reltype_, part_, rels_, rId_): - part._rels = rels_ - target_ = part_ - return part, target_, reltype_, rId_ + part.drop_rel("rId42") - @pytest.fixture - def relate_to_url_fixture(self, request, part, rels_, url_, reltype_, rId_): - part._rels = rels_ - return part, url_, reltype_, rId_ + assert "rId42" not in part.rels - @pytest.fixture - def related_part_fixture(self, request, part, rels_, reltype_, part_): - part._rels = rels_ - return part, reltype_, part_ + def it_can_find_a_related_part_by_reltype( + self, rels_prop_: Mock, rels_: Mock, other_part_: Mock + ): + rels_prop_.return_value = rels_ + rels_.part_with_reltype.return_value = other_part_ + part = Part(PackURI("/part/name"), "content/type") - @pytest.fixture - def related_parts_fixture(self, request, part, rels_, related_parts_): - part._rels = rels_ - return part, related_parts_ + related_part = part.part_related_by("http://rel/type") - @pytest.fixture - def rels_fixture(self, Relationships_, partname_, rels_): - part = Part(partname_, None) - return part, Relationships_, partname_, rels_ + rels_.part_with_reltype.assert_called_once_with("http://rel/type") + assert related_part is other_part_ - @pytest.fixture - def target_ref_fixture(self, request, part, rId_, rel_, url_): - part._rels = {rId_: rel_} - return part, rId_, url_ + def it_can_find_a_related_part_by_rId(self, rels_prop_: Mock, rels_: Mock, other_part_: Mock): + rels_prop_.return_value = rels_ + rels_.related_parts = {"rId24": other_part_} + part = Part(PackURI("/part/name"), "content/type") - # fixture components --------------------------------------------- + assert part.related_parts["rId24"] is other_part_ - @pytest.fixture - def part(self): - return Part(None, None) + def it_can_find_the_uri_of_an_external_relationship( + self, rels_prop_: Mock, rel_: Mock, other_part_: Mock + ): + rels_prop_.return_value = {"rId7": rel_} + rel_.target_ref = "https://hyper/link" + part = Part(PackURI("/part/name"), "content/type") - @pytest.fixture - def part_(self, request): - return instance_mock(request, Part) + url = part.target_ref("rId7") - @pytest.fixture - def partname_(self, request): - return instance_mock(request, PackURI) + assert url == "https://hyper/link" - @pytest.fixture - def Relationships_(self, request, rels_): - return class_mock(request, "docx.opc.part.Relationships", return_value=rels_) + # fixtures --------------------------------------------- @pytest.fixture - def rel_(self, request, rId_, url_): - return instance_mock(request, _Relationship, rId=rId_, target_ref=url_) + def other_part_(self, request: FixtureRequest): + return instance_mock(request, Part) @pytest.fixture - def rels_(self, request, part_, rel_, rId_, related_parts_): - rels_ = instance_mock(request, Relationships) - rels_.part_with_reltype.return_value = part_ - rels_.get_or_add.return_value = rel_ - rels_.get_or_add_ext_rel.return_value = rId_ - rels_.related_parts = related_parts_ - return rels_ + def partname_(self, request: FixtureRequest): + return instance_mock(request, PackURI) @pytest.fixture - def related_parts_(self, request): - return instance_mock(request, dict) + def Relationships_(self, request: FixtureRequest): + return class_mock(request, "docx.opc.part.Relationships") @pytest.fixture - def reltype_(self, request): - return instance_mock(request, str) + def rel_(self, request: FixtureRequest): + return instance_mock(request, _Relationship) @pytest.fixture - def rId_(self, request): - return instance_mock(request, str) + def rels_(self, request: FixtureRequest): + return instance_mock(request, Relationships) @pytest.fixture - def url_(self, request): - return instance_mock(request, str) + def rels_prop_(self, request: FixtureRequest): + return property_mock(request, Part, "rels") -class DescribePartFactory(object): +class DescribePartFactory: def it_constructs_part_from_selector_if_defined(self, cls_selector_fixture): # fixture ---------------------- ( @@ -281,9 +216,7 @@ def it_constructs_part_from_selector_if_defined(self, cls_selector_fixture): part = PartFactory(partname, content_type, reltype, blob, package) # verify ----------------------- cls_selector_fn_.assert_called_once_with(content_type, reltype) - CustomPartClass_.load.assert_called_once_with( - partname, content_type, blob, package - ) + CustomPartClass_.load.assert_called_once_with(partname, content_type, blob, package) assert part is part_of_custom_type_ def it_constructs_custom_part_type_for_registered_content_types( @@ -295,9 +228,7 @@ def it_constructs_custom_part_type_for_registered_content_types( PartFactory.part_type_for[content_type] = CustomPartClass_ part = PartFactory(partname, content_type, reltype, blob, package) # verify ----------------------- - CustomPartClass_.load.assert_called_once_with( - partname, content_type, blob, package - ) + CustomPartClass_.load.assert_called_once_with(partname, content_type, blob, package) assert part is part_of_custom_type_ def it_constructs_part_using_default_class_when_no_custom_registered( @@ -305,9 +236,7 @@ def it_constructs_part_using_default_class_when_no_custom_registered( ): partname, content_type, reltype, blob, package = part_args_2_ part = PartFactory(partname, content_type, reltype, blob, package) - DefaultPartClass_.load.assert_called_once_with( - partname, content_type, blob, package - ) + DefaultPartClass_.load.assert_called_once_with(partname, content_type, blob, package) assert part is part_of_default_type_ # fixtures --------------------------------------------- @@ -322,31 +251,25 @@ def blob_2_(self, request): @pytest.fixture def cls_method_fn_(self, request, cls_selector_fn_): - return function_mock( - request, "docx.opc.part.cls_method_fn", return_value=cls_selector_fn_ - ) + return function_mock(request, "docx.opc.part.cls_method_fn", return_value=cls_selector_fn_) @pytest.fixture def cls_selector_fixture( self, - request, cls_selector_fn_, cls_method_fn_, part_load_params, CustomPartClass_, part_of_custom_type_, ): - def reset_part_class_selector(): - PartFactory.part_class_selector = original_part_class_selector - original_part_class_selector = PartFactory.part_class_selector - request.addfinalizer(reset_part_class_selector) - return ( + yield ( cls_selector_fn_, part_load_params, CustomPartClass_, part_of_custom_type_, ) + PartFactory.part_class_selector = original_part_class_selector @pytest.fixture def cls_selector_fn_(self, request, CustomPartClass_): @@ -412,9 +335,7 @@ def part_args_(self, request, partname_, content_type_, reltype_, package_, blob return partname_, content_type_, reltype_, blob_, package_ @pytest.fixture - def part_args_2_( - self, request, partname_2_, content_type_2_, reltype_2_, package_2_, blob_2_ - ): + def part_args_2_(self, request, partname_2_, content_type_2_, reltype_2_, package_2_, blob_2_): return partname_2_, content_type_2_, reltype_2_, blob_2_, package_2_ @pytest.fixture @@ -426,16 +347,14 @@ def reltype_2_(self, request): return instance_mock(request, str) -class DescribeXmlPart(object): +class DescribeXmlPart: def it_can_be_constructed_by_PartFactory( self, partname_, content_type_, blob_, package_, element_, parse_xml_, __init_ ): part = XmlPart.load(partname_, content_type_, blob_, package_) parse_xml_.assert_called_once_with(blob_) - __init_.assert_called_once_with( - ANY, partname_, content_type_, element_, package_ - ) + __init_.assert_called_once_with(ANY, partname_, content_type_, element_, package_) assert isinstance(part, XmlPart) def it_can_serialize_to_xml(self, blob_fixture): @@ -448,16 +367,38 @@ def it_knows_its_the_part_for_its_child_objects(self, part_fixture): xml_part = part_fixture assert xml_part.part is xml_part + def it_can_set_its_element(self, part_fixture: XmlPart, new_element_: Mock): + part_fixture.element = new_element_ + assert part_fixture.element is new_element_ + + @pytest.mark.parametrize( + ("part_cxml", "rel_should_be_dropped"), + [ + ("w:p", True), + ("w:p/r:a{r:id=rId42}", True), + ("w:p/r:a{r:id=rId42}/r:b{r:id=rId42}", False), + ], + ) + def it_only_drops_a_relationship_with_zero_reference_count( + self, part_cxml: str, rel_should_be_dropped: bool, rels_prop_: Mock, package_: Mock + ): + rels_prop_.return_value = {"rId42": None} + part = XmlPart(PackURI("/partname"), "content_type", element(part_cxml), package_) + + part.drop_rel("rId42") + + assert ("rId42" not in part.rels) is rel_should_be_dropped + # fixtures ------------------------------------------------------- @pytest.fixture - def blob_fixture(self, request, element_, serialize_part_xml_): - xml_part = XmlPart(None, None, element_, None) + def blob_fixture(self, request, element_, serialize_part_xml_, package_): + xml_part = XmlPart(PackURI("/part/name"), "content/type", element_, package_) return xml_part, element_, serialize_part_xml_ @pytest.fixture - def part_fixture(self): - return XmlPart(None, None, None, None) + def part_fixture(self, package_): + return XmlPart(PackURI("/part/name"), "content/type", element("w:p"), package_) # fixture components --------------------------------------------- @@ -470,11 +411,15 @@ def content_type_(self, request): return instance_mock(request, str) @pytest.fixture - def element_(self, request): + def element_(self, request: FixtureRequest): + return instance_mock(request, BaseOxmlElement) + + @pytest.fixture + def new_element_(self, request: FixtureRequest): return instance_mock(request, BaseOxmlElement) @pytest.fixture - def __init_(self, request): + def __init_(self, request: FixtureRequest): return initializer_mock(request, XmlPart) @pytest.fixture @@ -490,32 +435,9 @@ def partname_(self, request): return instance_mock(request, PackURI) @pytest.fixture - def serialize_part_xml_(self, request): - return function_mock(request, "docx.opc.part.serialize_part_xml") - - -class TestPart: - def test_drop_rels(self, part_with_rels): - def cmp(rel): - return rel.target_part == "target1" - - ret = part_with_rels.drop_rels(cmp) - assert len(part_with_rels.rels) == 1 - assert part_with_rels.rels["rId2"].target_part == "target2" - assert ret == ["rId1"] - - @pytest.fixture - def part_with_rels(self, mocker, rels): - mocker.patch( - "docx.opc.part.Part.rels", - new_callable=mocker.PropertyMock, - return_value=rels, - ) - return Part("null", None) + def rels_prop_(self, request: FixtureRequest): + return property_mock(request, XmlPart, "rels") @pytest.fixture - def rels(self): - rels = Relationships(None) - rels["rId1"] = _Relationship("rId1", "reltype1", "target1", "base1") - rels["rId2"] = _Relationship("rId2", "reltype2", "target2", "base2") - return rels + def serialize_part_xml_(self, request): + return function_mock(request, "docx.opc.part.serialize_part_xml") diff --git a/tests/opc/test_phys_pkg.py b/tests/opc/test_phys_pkg.py index 25cf1554..6de0d868 100644 --- a/tests/opc/test_phys_pkg.py +++ b/tests/opc/test_phys_pkg.py @@ -1,41 +1,30 @@ -# encoding: utf-8 - -""" -Test suite for docx.opc.phys_pkg module -""" - -from __future__ import absolute_import - -try: - from io import BytesIO # Python 3 -except ImportError: - from StringIO import StringIO as BytesIO +"""Test suite for docx.opc.phys_pkg module.""" import hashlib -import pytest - +import io from zipfile import ZIP_DEFLATED, ZipFile +import pytest + from docx.opc.exceptions import PackageNotFoundError from docx.opc.packuri import PACKAGE_URI, PackURI from docx.opc.phys_pkg import ( - _DirPkgReader, PhysPkgReader, PhysPkgWriter, + _DirPkgReader, _ZipPkgReader, _ZipPkgWriter, ) -from ..unitutil.file import absjoin, testfile_dir -from ..unitutil.mock import class_mock, loose_mock, Mock - +from ..unitutil.file import absjoin, test_file_dir +from ..unitutil.mock import Mock, class_mock, loose_mock -test_docx_path = absjoin(testfile_dir, "test.docx") -dir_pkg_path = absjoin(testfile_dir, "expanded_docx") +test_docx_path = absjoin(test_file_dir, "test.docx") +dir_pkg_path = absjoin(test_file_dir, "expanded_docx") zip_pkg_path = test_docx_path -class DescribeDirPkgReader(object): +class DescribeDirPkgReader: def it_is_used_by_PhysPkgReader_when_pkg_is_a_dir(self): phys_reader = PhysPkgReader(dir_pkg_path) assert isinstance(phys_reader, _DirPkgReader) @@ -74,13 +63,13 @@ def dir_reader(self): return _DirPkgReader(dir_pkg_path) -class DescribePhysPkgReader(object): +class DescribePhysPkgReader: def it_raises_when_pkg_path_is_not_a_package(self): with pytest.raises(PackageNotFoundError): PhysPkgReader("foobar") -class DescribeZipPkgReader(object): +class DescribeZipPkgReader: def it_is_used_by_PhysPkgReader_when_pkg_is_a_zip(self): phys_reader = PhysPkgReader(zip_pkg_path) assert isinstance(phys_reader, _ZipPkgReader) @@ -126,17 +115,17 @@ def it_returns_none_when_part_has_no_rels_xml(self, phys_reader): # fixtures --------------------------------------------- @pytest.fixture(scope="class") - def phys_reader(self, request): + def phys_reader(self): phys_reader = _ZipPkgReader(zip_pkg_path) - request.addfinalizer(phys_reader.close) - return phys_reader + yield phys_reader + phys_reader.close() @pytest.fixture def pkg_file_(self, request): return loose_mock(request) -class DescribeZipPkgWriter(object): +class DescribeZipPkgWriter: def it_is_used_by_PhysPkgWriter_unconditionally(self, tmp_docx_path): phys_writer = PhysPkgWriter(tmp_docx_path) assert isinstance(phys_writer, _ZipPkgWriter) @@ -174,10 +163,10 @@ def it_can_write_a_blob(self, pkg_file): # fixtures --------------------------------------------- @pytest.fixture - def pkg_file(self, request): - pkg_file = BytesIO() - request.addfinalizer(pkg_file.close) - return pkg_file + def pkg_file(self): + pkg_file = io.BytesIO() + yield pkg_file + pkg_file.close() # fixtures ------------------------------------------------- diff --git a/tests/opc/test_pkgreader.py b/tests/opc/test_pkgreader.py index ac75e836..0aed52c8 100644 --- a/tests/opc/test_pkgreader.py +++ b/tests/opc/test_pkgreader.py @@ -1,25 +1,22 @@ -# encoding: utf-8 - -"""Unit test suite for docx.opc.pkgreader module""" - -from __future__ import absolute_import, print_function, unicode_literals +"""Unit test suite for docx.opc.pkgreader module.""" import pytest -from docx.opc.constants import CONTENT_TYPE as CT, RELATIONSHIP_TARGET_MODE as RTM +from docx.opc.constants import CONTENT_TYPE as CT +from docx.opc.constants import RELATIONSHIP_TARGET_MODE as RTM from docx.opc.packuri import PackURI from docx.opc.phys_pkg import _ZipPkgReader from docx.opc.pkgreader import ( - _ContentTypeMap, PackageReader, + _ContentTypeMap, _SerializedPart, _SerializedRelationship, _SerializedRelationships, ) -from .unitdata.types import a_Default, a_Types, an_Override from ..unitutil.mock import ( ANY, + Mock, call, class_mock, function_mock, @@ -27,12 +24,12 @@ instance_mock, loose_mock, method_mock, - Mock, patch, ) +from .unitdata.types import a_Default, a_Types, an_Override -class DescribePackageReader(object): +class DescribePackageReader: def it_can_construct_from_pkg_file( self, _init_, PhysPkgReader_, from_xml, _srels_for, _load_serialized_parts ): @@ -47,9 +44,7 @@ def it_can_construct_from_pkg_file( PhysPkgReader_.assert_called_once_with(pkg_file) from_xml.assert_called_once_with(phys_reader.content_types_xml) _srels_for.assert_called_once_with(phys_reader, "/") - _load_serialized_parts.assert_called_once_with( - phys_reader, pkg_srels, content_types - ) + _load_serialized_parts.assert_called_once_with(phys_reader, pkg_srels, content_types) phys_reader.close.assert_called_once_with() _init_.assert_called_once_with(ANY, content_types, pkg_srels, sparts) assert isinstance(pkg_reader, PackageReader) @@ -68,7 +63,7 @@ def it_can_iterate_over_all_the_srels(self): ] pkg_reader = PackageReader(None, pkg_srels, sparts) # exercise --------------------- - generated_tuples = [t for t in pkg_reader.iter_srels()] + generated_tuples = list(pkg_reader.iter_srels()) # verify ----------------------- expected_tuples = [ ("/", "srel1"), @@ -87,7 +82,7 @@ def it_can_load_serialized_parts(self, _SerializedPart_, _walk_phys_parts): ("/part/name2.xml", "app/vnd.type_2", "reltype2", "", "srels_2"), ) iter_vals = [(t[0], t[2], t[3], t[4]) for t in test_data] - content_types = dict((t[0], t[1]) for t in test_data) + content_types = {t[0]: t[1] for t in test_data} # mockery ---------------------- phys_reader = Mock(name="phys_reader") pkg_srels = Mock(name="pkg_srels") @@ -97,17 +92,11 @@ def it_can_load_serialized_parts(self, _SerializedPart_, _walk_phys_parts): Mock(name="spart_2"), ) # exercise --------------------- - retval = PackageReader._load_serialized_parts( - phys_reader, pkg_srels, content_types - ) + retval = PackageReader._load_serialized_parts(phys_reader, pkg_srels, content_types) # verify ----------------------- expected_calls = [ - call( - "/part/name1.xml", "app/vnd.type_1", "", "reltype1", "srels_1" - ), - call( - "/part/name2.xml", "app/vnd.type_2", "", "reltype2", "srels_2" - ), + call("/part/name1.xml", "app/vnd.type_1", "", "reltype1", "srels_1"), + call("/part/name2.xml", "app/vnd.type_2", "", "reltype2", "srels_2"), ] assert _SerializedPart_.call_args_list == expected_calls assert retval == expected_sparts @@ -211,9 +200,7 @@ def _init_(self, request): return initializer_mock(request, PackageReader) @pytest.fixture - def iter_sparts_fixture( - self, sparts_, partnames_, content_types_, reltypes_, blobs_ - ): + def iter_sparts_fixture(self, sparts_, partnames_, content_types_, reltypes_, blobs_): pkg_reader = PackageReader(None, None, sparts_) expected_iter_spart_items = [ (partnames_[0], content_types_[0], reltypes_[0], blobs_[0]), @@ -223,9 +210,7 @@ def iter_sparts_fixture( @pytest.fixture def _load_serialized_parts(self, request): - return method_mock( - request, PackageReader, "_load_serialized_parts", autospec=False - ) + return method_mock(request, PackageReader, "_load_serialized_parts", autospec=False) @pytest.fixture def partnames_(self, request): @@ -234,10 +219,10 @@ def partnames_(self, request): return partname_, partname_2_ @pytest.fixture - def PhysPkgReader_(self, request): - _patch = patch("docx.opc.pkgreader.PhysPkgReader", spec_set=_ZipPkgReader) - request.addfinalizer(_patch.stop) - return _patch.start() + def PhysPkgReader_(self): + p = patch("docx.opc.pkgreader.PhysPkgReader", spec_set=_ZipPkgReader) + yield p.start() + p.stop() @pytest.fixture def reltypes_(self, request): @@ -279,22 +264,18 @@ def _walk_phys_parts(self, request): return method_mock(request, PackageReader, "_walk_phys_parts", autospec=False) -class Describe_ContentTypeMap(object): +class Describe_ContentTypeMap: def it_can_construct_from_ct_item_xml(self, from_xml_fixture): content_types_xml, expected_defaults, expected_overrides = from_xml_fixture ct_map = _ContentTypeMap.from_xml(content_types_xml) assert ct_map._defaults == expected_defaults assert ct_map._overrides == expected_overrides - def it_matches_an_override_on_case_insensitive_partname( - self, match_override_fixture - ): + def it_matches_an_override_on_case_insensitive_partname(self, match_override_fixture): ct_map, partname, content_type = match_override_fixture assert ct_map[partname] == content_type - def it_falls_back_to_case_insensitive_extension_default_match( - self, match_default_fixture - ): + def it_falls_back_to_case_insensitive_extension_default_match(self, match_default_fixture): ct_map, partname, content_type = match_default_fixture assert ct_map[partname] == content_type @@ -364,7 +345,7 @@ def match_override_fixture(self, request): def _xml_from(self, entries): """ - Return XML for a [Content_Types].xml based on items in *entries*. + Return XML for a [Content_Types].xml based on items in `entries`. """ types_bldr = a_Types().with_nsdecls() for entry in entries: @@ -383,7 +364,7 @@ def _xml_from(self, entries): return types_bldr.xml() -class Describe_SerializedPart(object): +class Describe_SerializedPart: def it_remembers_construction_values(self): # test data -------------------- partname = "/part/name.xml" @@ -401,7 +382,7 @@ def it_remembers_construction_values(self): assert spart.srels == srels -class Describe_SerializedRelationship(object): +class Describe_SerializedRelationship: def it_remembers_construction_values(self): # test data -------------------- rel_elm = Mock( @@ -467,11 +448,11 @@ def it_raises_on_target_partname_when_external(self): target_mode=RTM.EXTERNAL, ) srel = _SerializedRelationship("/", rel_elm) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="target_partname attribute on Relat"): srel.target_partname -class Describe_SerializedRelationships(object): +class Describe_SerializedRelationships: def it_can_load_from_xml(self, parse_xml_, _SerializedRelationship_): # mockery ---------------------- baseURI, rels_item_xml, rel_elm_1, rel_elm_2 = ( diff --git a/tests/opc/test_pkgwriter.py b/tests/opc/test_pkgwriter.py index 25bcadb4..aff8b22d 100644 --- a/tests/opc/test_pkgwriter.py +++ b/tests/opc/test_pkgwriter.py @@ -1,8 +1,8 @@ -# encoding: utf-8 +# pyright: reportPrivateUsage=false -""" -Test suite for opc.pkgwriter module -""" +"""Test suite for opc.pkgwriter module.""" + +from __future__ import annotations import pytest @@ -10,21 +10,22 @@ from docx.opc.packuri import PackURI from docx.opc.part import Part from docx.opc.phys_pkg import _ZipPkgWriter -from docx.opc.pkgwriter import _ContentTypesItem, PackageWriter +from docx.opc.pkgwriter import PackageWriter, _ContentTypesItem +from docx.opc.rel import Relationships -from .unitdata.types import a_Default, a_Types, an_Override from ..unitutil.mock import ( + FixtureRequest, + Mock, call, class_mock, instance_mock, - MagicMock, method_mock, - Mock, patch, ) +from .unitdata.types import a_Default, a_Types, an_Override -class DescribePackageWriter(object): +class DescribePackageWriter: def it_can_write_a_package(self, PhysPkgWriter_, _write_methods): # mockery ---------------------- pkg_file = Mock(name="pkg_file") @@ -58,59 +59,70 @@ def it_can_write_a_pkg_rels_item(self): # verify ----------------------- phys_writer.write.assert_called_once_with("/_rels/.rels", pkg_rels.xml) - def it_can_write_a_list_of_parts(self): - # mockery ---------------------- - phys_writer = Mock(name="phys_writer") - rels = MagicMock(name="rels") - rels.__len__.return_value = 1 - part1 = Mock(name="part1", _rels=rels) - part2 = Mock(name="part2", _rels=[]) - # exercise --------------------- - PackageWriter._write_parts(phys_writer, [part1, part2]) - # verify ----------------------- + def it_can_write_a_list_of_parts( + self, phys_pkg_writer_: Mock, part_: Mock, part_2_: Mock, rels_: Mock + ): + rels_.__len__.return_value = 1 + part_.rels = rels_ + part_2_.rels = [] + + PackageWriter._write_parts(phys_pkg_writer_, [part_, part_2_]) + expected_calls = [ - call(part1.partname, part1.blob), - call(part1.partname.rels_uri, part1._rels.xml), - call(part2.partname, part2.blob), + call(part_.partname, part_.blob), + call(part_.partname.rels_uri, part_.rels.xml), + call(part_2_.partname, part_2_.blob), ] - assert phys_writer.write.mock_calls == expected_calls + assert phys_pkg_writer_.write.mock_calls == expected_calls # fixtures --------------------------------------------- @pytest.fixture - def blob_(self, request): + def blob_(self, request: FixtureRequest): return instance_mock(request, str) @pytest.fixture - def cti_(self, request, blob_): + def cti_(self, request: FixtureRequest, blob_): return instance_mock(request, _ContentTypesItem, blob=blob_) @pytest.fixture - def _ContentTypesItem_(self, request, cti_): + def _ContentTypesItem_(self, request: FixtureRequest, cti_): _ContentTypesItem_ = class_mock(request, "docx.opc.pkgwriter._ContentTypesItem") _ContentTypesItem_.from_parts.return_value = cti_ return _ContentTypesItem_ @pytest.fixture - def parts_(self, request): + def part_(self, request: FixtureRequest): + return instance_mock(request, Part) + + @pytest.fixture + def part_2_(self, request: FixtureRequest): + return instance_mock(request, Part) + + @pytest.fixture + def parts_(self, request: FixtureRequest): return instance_mock(request, list) @pytest.fixture - def PhysPkgWriter_(self, request): - _patch = patch("docx.opc.pkgwriter.PhysPkgWriter") - request.addfinalizer(_patch.stop) - return _patch.start() + def PhysPkgWriter_(self): + p = patch("docx.opc.pkgwriter.PhysPkgWriter") + yield p.start() + p.stop() @pytest.fixture - def phys_pkg_writer_(self, request): + def phys_pkg_writer_(self, request: FixtureRequest): return instance_mock(request, _ZipPkgWriter) + @pytest.fixture + def rels_(self, request: FixtureRequest): + return instance_mock(request, Relationships) + @pytest.fixture def write_cti_fixture(self, _ContentTypesItem_, parts_, phys_pkg_writer_, blob_): return _ContentTypesItem_, parts_, phys_pkg_writer_, blob_ @pytest.fixture - def _write_methods(self, request): + def _write_methods(self): """Mock that patches all the _write_* methods of PackageWriter""" root_mock = Mock(name="PackageWriter") patch1 = patch.object(PackageWriter, "_write_content_types_stream") @@ -120,20 +132,18 @@ def _write_methods(self, request): root_mock.attach_mock(patch2.start(), "_write_pkg_rels") root_mock.attach_mock(patch3.start(), "_write_parts") - def fin(): - patch1.stop() - patch2.stop() - patch3.stop() + yield root_mock - request.addfinalizer(fin) - return root_mock + patch1.stop() + patch2.stop() + patch3.stop() @pytest.fixture - def xml_for_(self, request): + def xml_for_(self, request: FixtureRequest): return method_mock(request, _ContentTypesItem, "xml_for") -class Describe_ContentTypesItem(object): +class Describe_ContentTypesItem: def it_can_compose_content_types_element(self, xml_for_fixture): cti, expected_xml = xml_for_fixture types_elm = cti._element @@ -141,11 +151,9 @@ def it_can_compose_content_types_element(self, xml_for_fixture): # fixtures --------------------------------------------- - def _mock_part(self, request, name, partname_str, content_type): + def _mock_part(self, request: FixtureRequest, name, partname_str, content_type): partname = PackURI(partname_str) - return instance_mock( - request, Part, name=name, partname=partname, content_type=content_type - ) + return instance_mock(request, Part, name=name, partname=partname, content_type=content_type) @pytest.fixture( params=[ @@ -158,7 +166,7 @@ def _mock_part(self, request, name, partname_str, content_type): ("Override", "/zebra/foo.bar", "app/vnd.foobar"), ] ) - def xml_for_fixture(self, request): + def xml_for_fixture(self, request: FixtureRequest): elm_type, partname_str, content_type = request.param part_ = self._mock_part(request, "part_", partname_str, content_type) cti = _ContentTypesItem.from_parts([part_]) @@ -174,9 +182,7 @@ def xml_for_fixture(self, request): types_bldr.with_child( a_Default().with_Extension("rels").with_ContentType(CT.OPC_RELATIONSHIPS) ) - types_bldr.with_child( - a_Default().with_Extension("xml").with_ContentType(CT.XML) - ) + types_bldr.with_child(a_Default().with_Extension("xml").with_ContentType(CT.XML)) if elm_type == "Override": override_bldr = an_Override() diff --git a/tests/opc/test_rel.py b/tests/opc/test_rel.py index 9f11b3f6..79c083df 100644 --- a/tests/opc/test_rel.py +++ b/tests/opc/test_rel.py @@ -1,6 +1,7 @@ -""" -Unit test suite for the docx.opc.rel module -""" +# pyright: reportPrivateUsage=false + +"""Unit test suite for the docx.opc.rel module.""" + import pytest from docx.opc.oxml import CT_Relationships @@ -8,11 +9,10 @@ from docx.opc.part import Part from docx.opc.rel import Relationships, _Relationship -from ..unitutil.mock import (Mock, PropertyMock, call, class_mock, - instance_mock, patch) +from ..unitutil.mock import Mock, PropertyMock, call, class_mock, instance_mock, patch -class Describe_Relationship(object): +class Describe_Relationship: def it_remembers_construction_values(self): # test data -------------------- rId = "rId9" @@ -29,7 +29,7 @@ def it_remembers_construction_values(self): def it_should_raise_on_target_part_access_on_external_rel(self): rel = _Relationship(None, None, None, None, external=True) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="target_part property on _Relat"): rel.target_part def it_should_have_target_ref_for_external_rel(self): @@ -42,9 +42,9 @@ def it_should_change_target_ref_for_external_rel(self): rel.target_ref = new_target assert rel.target_ref == new_target - def it_raises_on_chaged_internal_rel(self): + def it_raises_on_changed_internal_rel(self): rel = _Relationship(None, None, "internal_target1", None, external=False) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="can not set internal target_ref"): rel.target_ref = "t2" def it_should_have_relative_ref_for_internal_rel(self): @@ -59,7 +59,7 @@ def it_should_have_relative_ref_for_internal_rel(self): assert rel.target_ref == "../media/image1.png" -class DescribeRelationships(object): +class DescribeRelationships: def it_can_add_a_relationship(self, _Relationship_): baseURI, rId, reltype, target, external = ( "baseURI", @@ -88,19 +88,14 @@ def it_can_find_a_relationship_by_rId(self): rels["foobar"] = rel assert rels["foobar"] == rel - def it_can_find_or_add_a_relationship( - self, rels_with_matching_rel_, rels_with_missing_rel_ - ): - + def it_can_find_or_add_a_relationship(self, rels_with_matching_rel_, rels_with_missing_rel_): rels, reltype, part, matching_rel = rels_with_matching_rel_ assert rels.get_or_add(reltype, part) == matching_rel rels, reltype, part, new_rel = rels_with_missing_rel_ assert rels.get_or_add(reltype, part) == new_rel - def it_can_find_or_add_an_external_relationship( - self, add_matching_ext_rel_fixture_ - ): + def it_can_find_or_add_an_external_relationship(self, add_matching_ext_rel_fixture_): rels, reltype, url, rId = add_matching_ext_rel_fixture_ _rId = rels.get_or_add_ext_rel(reltype, url) assert _rId == rId @@ -120,6 +115,11 @@ def it_can_find_a_related_part_by_reltype(self, rels_with_target_known_by_reltyp part = rels.part_with_reltype(reltype) assert part is known_target_part + def it_can_find_related_parts_by_reltype(self, rels_with_targets_known_by_reltype): + rels, reltype, known_target_parts = rels_with_targets_known_by_reltype + parts = rels.parts_with_reltype(reltype) + assert parts == known_target_parts + def it_can_compose_rels_xml(self, rels, rels_elm): # exercise --------------------- rels.xml @@ -146,7 +146,7 @@ def add_ext_rel_fixture_(self, reltype, url): return rels, reltype, url @pytest.fixture - def add_matching_ext_rel_fixture_(self, reltype, url): + def add_matching_ext_rel_fixture_(self, request, reltype, url): rId = "rId369" rels = Relationships(None) rels.add_relationship(reltype, url, rId, is_external=True) @@ -186,7 +186,7 @@ def rels(self): return rels @pytest.fixture - def rels_elm(self, request): + def rels_elm(self): """ Return a rels_elm mock that will be returned from CT_Relationships.new() @@ -200,8 +200,8 @@ def rels_elm(self, request): # patch CT_Relationships to return that rels_elm patch_ = patch.object(CT_Relationships, "new", return_value=rels_elm) patch_.start() - request.addfinalizer(patch_.stop) - return rels_elm + yield rels_elm + patch_.stop() @pytest.fixture def _rel_with_known_target_part(self, _rId, reltype, _target_part, _baseURI): @@ -210,7 +210,7 @@ def _rel_with_known_target_part(self, _rId, reltype, _target_part, _baseURI): @pytest.fixture def rels_with_known_target_part(self, rels, _rel_with_known_target_part): - _, rId, target_part = _rel_with_known_target_part + rel, rId, target_part = _rel_with_known_target_part rels.add_relationship(None, target_part, rId) return rels, rId, target_part @@ -247,24 +247,25 @@ def rels_with_missing_rel_(self, request, rels, _Relationship_): @pytest.fixture def rels_with_rId_gap(self, request): rels = Relationships(None) - rel_with_rId1 = instance_mock( - request, _Relationship, name="rel_with_rId1", rId="rId1" - ) - rel_with_rId3 = instance_mock( - request, _Relationship, name="rel_with_rId3", rId="rId3" - ) + rel_with_rId1 = instance_mock(request, _Relationship, name="rel_with_rId1", rId="rId1") + rel_with_rId3 = instance_mock(request, _Relationship, name="rel_with_rId3", rId="rId3") rels["rId1"] = rel_with_rId1 rels["rId3"] = rel_with_rId3 return rels, "rId2" @pytest.fixture - def rels_with_target_known_by_reltype( - self, rels, _rel_with_target_known_by_reltype - ): + def rels_with_target_known_by_reltype(self, rels, _rel_with_target_known_by_reltype): rel, reltype, target_part = _rel_with_target_known_by_reltype rels[1] = rel return rels, reltype, target_part + @pytest.fixture + def rels_with_targets_known_by_reltype(self, rels, _rel_with_target_known_by_reltype, _target_part): + rel, reltype, _ = _rel_with_target_known_by_reltype + rels[1] = rel + rels[2] = _Relationship("rId7", reltype, _target_part, "baseURI") + return rels, reltype, [rel.target_part, _target_part] + @pytest.fixture def reltype(self): return "http://rel/type" diff --git a/tests/opc/unitdata/rels.py b/tests/opc/unitdata/rels.py index 73663d18..268216af 100644 --- a/tests/opc/unitdata/rels.py +++ b/tests/opc/unitdata/rels.py @@ -1,19 +1,12 @@ -# encoding: utf-8 - -""" -Test data for relationship-related unit tests. -""" - -from __future__ import absolute_import - -from docx.opc.constants import RELATIONSHIP_TYPE as RT -from docx.opc.rel import Relationships +"""Test data for relationship-related unit tests.""" from docx.opc.constants import NAMESPACE as NS +from docx.opc.constants import RELATIONSHIP_TYPE as RT from docx.opc.oxml import parse_xml +from docx.opc.rel import Relationships -class BaseBuilder(object): +class BaseBuilder: """ Provides common behavior for all data builders. """ @@ -24,12 +17,12 @@ def element(self): return parse_xml(self.xml) def with_indent(self, indent): - """Add integer *indent* spaces at beginning of element XML""" + """Add integer `indent` spaces at beginning of element XML""" self._indent = indent return self -class RelationshipsBuilder(object): +class RelationshipsBuilder: """Builder class for test Relationships""" partname_tmpls = { @@ -81,12 +74,12 @@ def __init__(self): self._namespace = ' xmlns="%s"' % NS.OPC_CONTENT_TYPES def with_content_type(self, content_type): - """Set ContentType attribute to *content_type*""" + """Set ContentType attribute to `content_type`""" self._content_type = content_type return self def with_extension(self, extension): - """Set Extension attribute to *extension*""" + """Set Extension attribute to `extension`""" self._extension = extension return self @@ -117,12 +110,12 @@ def __init__(self): self._partname = "/part/name.xml" def with_content_type(self, content_type): - """Set ContentType attribute to *content_type*""" + """Set ContentType attribute to `content_type`""" self._content_type = content_type return self def with_partname(self, partname): - """Set PartName attribute to *partname*""" + """Set PartName attribute to `partname`""" self._partname = partname return self @@ -155,22 +148,22 @@ def __init__(self): self._namespace = ' xmlns="%s"' % NS.OPC_RELATIONSHIPS def with_rId(self, rId): - """Set Id attribute to *rId*""" + """Set Id attribute to `rId`""" self._rId = rId return self def with_reltype(self, reltype): - """Set Type attribute to *reltype*""" + """Set Type attribute to `reltype`""" self._reltype = reltype return self def with_target(self, target): - """Set XXX attribute to *target*""" + """Set XXX attribute to `target`""" self._target = target return self def with_target_mode(self, target_mode): - """Set TargetMode attribute to *target_mode*""" + """Set TargetMode attribute to `target_mode`""" self._target_mode = None if target_mode == "Internal" else target_mode return self diff --git a/tests/opc/unitdata/types.py b/tests/opc/unitdata/types.py index d5b742b1..206ba74a 100644 --- a/tests/opc/unitdata/types.py +++ b/tests/opc/unitdata/types.py @@ -1,10 +1,4 @@ -# encoding: utf-8 - -""" -XML test data builders for [Content_Types].xml elements -""" - -from __future__ import absolute_import, print_function, unicode_literals +"""XML test data builders for [Content_Types].xml elements.""" from docx.opc.oxml import nsmap diff --git a/tests/oxml/parts/test_document.py b/tests/oxml/parts/test_document.py index 707a0dd7..149a6579 100644 --- a/tests/oxml/parts/test_document.py +++ b/tests/oxml/parts/test_document.py @@ -1,17 +1,11 @@ -# encoding: utf-8 - -""" -Test suite for the docx.oxml.parts module. -""" - -from __future__ import absolute_import, print_function, unicode_literals +"""Test suite for the docx.oxml.parts module.""" import pytest from ...unitutil.cxml import element, xml -class DescribeCT_Body(object): +class DescribeCT_Body: def it_can_clear_all_its_content(self, clear_fixture): body, expected_xml = clear_fixture body.clear_content() @@ -44,9 +38,6 @@ def clear_fixture(self, request): def section_break_fixture(self): body = element("w:body/w:sectPr/w:type{w:val=foobar}") expected_xml = xml( - "w:body/(" - " w:p/w:pPr/w:sectPr/w:type{w:val=foobar}," - " w:sectPr/w:type{w:val=foobar}" - ")" + "w:body/(w:p/w:pPr/w:sectPr/w:type{w:val=foobar},w:sectPr/w:type{w:val=foobar})" ) return body, expected_xml diff --git a/tests/oxml/parts/unitdata/document.py b/tests/oxml/parts/unitdata/document.py index 6dd8efe7..36d7738b 100644 --- a/tests/oxml/parts/unitdata/document.py +++ b/tests/oxml/parts/unitdata/document.py @@ -1,8 +1,4 @@ -# encoding: utf-8 - -""" -Test data builders for parts XML. -""" +"""Test data builders for parts XML.""" from ....unitdata import BaseBuilder diff --git a/tests/oxml/test__init__.py b/tests/oxml/test__init__.py index 85302d64..9f19094b 100644 --- a/tests/oxml/test__init__.py +++ b/tests/oxml/test__init__.py @@ -1,33 +1,23 @@ -# encoding: utf-8 - -""" -Test suite for pptx.oxml.__init__.py module, primarily XML parser-related. -""" - -from __future__ import print_function, unicode_literals +"""Test suite for pptx.oxml.__init__.py module, primarily XML parser-related.""" import pytest - from lxml import etree -from docx.oxml import OxmlElement, oxml_parser, parse_xml, register_element_cls from docx.oxml.ns import qn +from docx.oxml.parser import OxmlElement, oxml_parser, parse_xml, register_element_cls from docx.oxml.shared import BaseOxmlElement -class DescribeOxmlElement(object): +class DescribeOxmlElement: def it_returns_an_lxml_element_with_matching_tag_name(self): element = OxmlElement("a:foo") assert isinstance(element, etree._Element) - assert element.tag == ( - "{http://schemas.openxmlformats.org/drawingml/2006/main}foo" - ) + assert element.tag == ("{http://schemas.openxmlformats.org/drawingml/2006/main}foo") def it_adds_supplied_attributes(self): element = OxmlElement("a:foo", {"a": "b", "c": "d"}) assert etree.tostring(element) == ( - '' + '' ).encode("utf-8") def it_adds_additional_namespace_declarations_when_supplied(self): @@ -39,7 +29,7 @@ def it_adds_additional_namespace_declarations_when_supplied(self): assert element.nsmap["x"] == ns2 -class DescribeOxmlParser(object): +class DescribeOxmlParser: def it_strips_whitespace_between_elements(self, whitespace_fixture): pretty_xml_text, stripped_xml_text = whitespace_fixture element = etree.fromstring(pretty_xml_text, oxml_parser) @@ -50,12 +40,12 @@ def it_strips_whitespace_between_elements(self, whitespace_fixture): @pytest.fixture def whitespace_fixture(self): - pretty_xml_text = "\n" " text\n" "\n" + pretty_xml_text = "\n text\n\n" stripped_xml_text = "text" return pretty_xml_text, stripped_xml_text -class DescribeParseXml(object): +class DescribeParseXml: def it_accepts_bytes_and_assumes_utf8_encoding(self, xml_bytes): parse_xml(xml_bytes) @@ -70,7 +60,7 @@ def it_accepts_unicode_providing_there_is_no_encoding_declaration(self): parse_xml(xml_text) # but adding encoding in the declaration raises ValueError xml_text = "%s\n%s" % (enc_decl, xml_body) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="Unicode strings with encoding declara"): parse_xml(xml_text) def it_uses_registered_element_classes(self, xml_bytes): @@ -90,7 +80,7 @@ def xml_bytes(self): ).encode("utf-8") -class DescribeRegisterElementCls(object): +class DescribeRegisterElementCls: def it_determines_class_used_for_elements_with_matching_tagname(self, xml_text): register_element_cls("a:foo", CustElmCls) foo = parse_xml(xml_text) diff --git a/tests/oxml/test_comments.py b/tests/oxml/test_comments.py new file mode 100644 index 00000000..8fc11614 --- /dev/null +++ b/tests/oxml/test_comments.py @@ -0,0 +1,31 @@ +# pyright: reportPrivateUsage=false + +"""Unit-test suite for `docx.oxml.comments` module.""" + +from __future__ import annotations + +from typing import cast + +import pytest + +from docx.oxml.comments import CT_Comments + +from ..unitutil.cxml import element + + +class DescribeCT_Comments: + """Unit-test suite for `docx.oxml.comments.CT_Comments`.""" + + @pytest.mark.parametrize( + ("cxml", "expected_value"), + [ + ("w:comments", 0), + ("w:comments/(w:comment{w:id=1})", 2), + ("w:comments/(w:comment{w:id=4},w:comment{w:id=2147483646})", 2147483647), + ("w:comments/(w:comment{w:id=1},w:comment{w:id=2147483647})", 0), + ("w:comments/(w:comment{w:id=1},w:comment{w:id=2},w:comment{w:id=3})", 4), + ], + ) + def it_finds_the_next_available_comment_id_to_help(self, cxml: str, expected_value: int): + comments_elm = cast(CT_Comments, element(cxml)) + assert comments_elm._next_available_comment_id() == expected_value diff --git a/tests/oxml/test_document.py b/tests/oxml/test_document.py new file mode 100644 index 00000000..f7f99a52 --- /dev/null +++ b/tests/oxml/test_document.py @@ -0,0 +1,19 @@ +"""Unit-test suite for `docx.oxml.document` module.""" + +from __future__ import annotations + +from typing import cast + +from docx.oxml.document import CT_Body +from docx.oxml.table import CT_Tbl +from docx.oxml.text.paragraph import CT_P + +from ..unitutil.cxml import element + + +class DescribeCT_Body: + """Unit-test suite for selected units of `docx.oxml.document.CT_Body`.""" + + def it_knows_its_inner_content_block_item_elements(self): + body = cast(CT_Body, element("w:body/(w:tbl, w:p,w:p)")) + assert [type(e) for e in body.inner_content_elements] == [CT_Tbl, CT_P, CT_P] diff --git a/tests/oxml/test_ns.py b/tests/oxml/test_ns.py index 413d10bd..cd493e6c 100644 --- a/tests/oxml/test_ns.py +++ b/tests/oxml/test_ns.py @@ -1,17 +1,11 @@ -# encoding: utf-8 - -""" -Test suite for docx.oxml.ns -""" - -from __future__ import absolute_import, print_function, unicode_literals +"""Test suite for docx.oxml.ns.""" import pytest from docx.oxml.ns import NamespacePrefixedTag -class DescribeNamespacePrefixedTag(object): +class DescribeNamespacePrefixedTag: def it_behaves_like_a_string_when_you_want_it_to(self, nsptag): s = "- %s -" % nsptag assert s == "- a:foobar -" diff --git a/tests/oxml/test_section.py b/tests/oxml/test_section.py new file mode 100644 index 00000000..8cf0bd9b --- /dev/null +++ b/tests/oxml/test_section.py @@ -0,0 +1,19 @@ +"""Unit-test suite for `docx.oxml.section` module.""" + +from __future__ import annotations + +from typing import cast + +from docx.oxml.section import CT_HdrFtr +from docx.oxml.table import CT_Tbl +from docx.oxml.text.paragraph import CT_P + +from ..unitutil.cxml import element + + +class DescribeCT_HdrFtr: + """Unit-test suite for selected units of `docx.oxml.section.CT_HdrFtr`.""" + + def it_knows_its_inner_content_block_item_elements(self): + hdr = cast(CT_HdrFtr, element("w:hdr/(w:tbl,w:tbl,w:p)")) + assert [type(e) for e in hdr.inner_content_elements] == [CT_Tbl, CT_Tbl, CT_P] diff --git a/tests/oxml/test_styles.py b/tests/oxml/test_styles.py index 0c34f663..8814dd6a 100644 --- a/tests/oxml/test_styles.py +++ b/tests/oxml/test_styles.py @@ -1,10 +1,4 @@ -# encoding: utf-8 - -""" -Test suite for the docx.oxml.styles module. -""" - -from __future__ import absolute_import, division, print_function, unicode_literals +"""Test suite for the docx.oxml.styles module.""" import pytest @@ -13,7 +7,7 @@ from ..unitutil.cxml import element, xml -class DescribeCT_Styles(object): +class DescribeCT_Styles: def it_can_add_a_style_of_type(self, add_fixture): styles, name, style_type, builtin, expected_xml = add_fixture style = styles.add_style_of_type(name, style_type, builtin) @@ -37,8 +31,7 @@ def it_can_add_a_style_of_type(self, add_fixture): "heading 1", WD_STYLE_TYPE.PARAGRAPH, True, - "w:styles/w:style{w:type=paragraph,w:styleId=Heading1}/w:name{w:val" - "=heading 1}", + "w:styles/w:style{w:type=paragraph,w:styleId=Heading1}/w:name{w:val=heading 1}", ), ] ) diff --git a/tests/oxml/test_table.py b/tests/oxml/test_table.py index bc40b5fb..2c9e0534 100644 --- a/tests/oxml/test_table.py +++ b/tests/oxml/test_table.py @@ -1,181 +1,84 @@ -# encoding: utf-8 +# pyright: reportPrivateUsage=false -"""Test suite for the docx.oxml.text module""" +"""Test suite for the docx.oxml.text module.""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import annotations + +from typing import cast import pytest from docx.exceptions import InvalidSpanError -from docx.oxml import parse_xml -from docx.oxml.table import CT_Row, CT_Tc +from docx.oxml.parser import parse_xml +from docx.oxml.table import CT_Row, CT_Tbl, CT_Tc +from docx.oxml.text.paragraph import CT_P from ..unitutil.cxml import element, xml from ..unitutil.file import snippet_seq -from ..unitutil.mock import call, instance_mock, method_mock, property_mock - - -class DescribeCT_Row(object): - def it_can_add_a_trPr(self, add_trPr_fixture): - tr, expected_xml = add_trPr_fixture - tr._add_trPr() - assert tr.xml == expected_xml +from ..unitutil.mock import FixtureRequest, Mock, call, instance_mock, method_mock, property_mock - def it_raises_on_tc_at_grid_col(self, tc_raise_fixture): - tr, idx = tc_raise_fixture - with pytest.raises(ValueError): - tr.tc_at_grid_col(idx) - # fixtures ------------------------------------------------------- - - @pytest.fixture( - params=[ +class DescribeCT_Row: + @pytest.mark.parametrize( + ("tr_cxml", "expected_cxml"), + [ ("w:tr", "w:tr/w:trPr"), ("w:tr/w:tblPrEx", "w:tr/(w:tblPrEx,w:trPr)"), ("w:tr/w:tc", "w:tr/(w:trPr,w:tc)"), ("w:tr/(w:sdt,w:del,w:tc)", "w:tr/(w:trPr,w:sdt,w:del,w:tc)"), - ] + ], ) - def add_trPr_fixture(self, request): - tr_cxml, expected_cxml = request.param - tr = element(tr_cxml) - expected_xml = xml(expected_cxml) - return tr, expected_xml - - @pytest.fixture(params=[(0, 0, 3), (1, 0, 1)]) - def tc_raise_fixture(self, request): - snippet_idx, row_idx, col_idx = request.param - tbl = parse_xml(snippet_seq("tbl-cells")[snippet_idx]) - tr = tbl.tr_lst[row_idx] - return tr, col_idx + def it_can_add_a_trPr(self, tr_cxml: str, expected_cxml: str): + tr = cast(CT_Row, element(tr_cxml)) + tr._add_trPr() + assert tr.xml == xml(expected_cxml) + + @pytest.mark.parametrize(("snippet_idx", "row_idx", "col_idx"), [(0, 0, 3), (1, 0, 1)]) + def it_raises_on_tc_at_grid_col(self, snippet_idx: int, row_idx: int, col_idx: int): + tr = cast(CT_Tbl, parse_xml(snippet_seq("tbl-cells")[snippet_idx])).tr_lst[row_idx] + with pytest.raises(ValueError, match=f"no `tc` element at grid_offset={col_idx}"): + tr.tc_at_grid_offset(col_idx) + + +class DescribeCT_Tc: + """Unit-test suite for `docx.oxml.table.CT_Tc` objects.""" + + @pytest.mark.parametrize( + ("tr_cxml", "tc_idx", "expected_value"), + [ + ("w:tr/(w:tc/w:p,w:tc/w:p)", 0, 0), + ("w:tr/(w:tc/w:p,w:tc/w:p)", 1, 1), + ("w:tr/(w:trPr/w:gridBefore{w:val=2},w:tc/w:p,w:tc/w:p)", 0, 2), + ("w:tr/(w:trPr/w:gridBefore{w:val=2},w:tc/w:p,w:tc/w:p)", 1, 3), + ("w:tr/(w:trPr/w:gridBefore{w:val=4},w:tc/w:p,w:tc/w:p,w:tc/w:p,w:tc/w:p)", 2, 6), + ], + ) + def it_knows_its_grid_offset(self, tr_cxml: str, tc_idx: int, expected_value: int): + tr = cast(CT_Row, element(tr_cxml)) + tc = tr.tc_lst[tc_idx] + assert tc.grid_offset == expected_value -class DescribeCT_Tc(object): def it_can_merge_to_another_tc( - self, tr_, _span_dimensions_, _tbl_, _grow_to_, top_tc_ + self, tr_: Mock, _span_dimensions_: Mock, _tbl_: Mock, _grow_to_: Mock, top_tc_: Mock ): top_tr_ = tr_ - tc, other_tc = element("w:tc"), element("w:tc") + tc, other_tc = cast(CT_Tc, element("w:tc")), cast(CT_Tc, element("w:tc")) top, left, height, width = 0, 1, 2, 3 _span_dimensions_.return_value = top, left, height, width _tbl_.return_value.tr_lst = [tr_] - tr_.tc_at_grid_col.return_value = top_tc_ + tr_.tc_at_grid_offset.return_value = top_tc_ merged_tc = tc.merge(other_tc) _span_dimensions_.assert_called_once_with(tc, other_tc) - top_tr_.tc_at_grid_col.assert_called_once_with(left) + top_tr_.tc_at_grid_offset.assert_called_once_with(left) top_tc_._grow_to.assert_called_once_with(width, height) assert merged_tc is top_tc_ - def it_knows_its_extents_to_help(self, extents_fixture): - tc, attr_name, expected_value = extents_fixture - extent = getattr(tc, attr_name) - assert extent == expected_value - - def it_calculates_the_dimensions_of_a_span_to_help(self, span_fixture): - tc, other_tc, expected_dimensions = span_fixture - dimensions = tc._span_dimensions(other_tc) - assert dimensions == expected_dimensions - - def it_raises_on_invalid_span(self, span_raise_fixture): - tc, other_tc = span_raise_fixture - with pytest.raises(InvalidSpanError): - tc._span_dimensions(other_tc) - - def it_can_grow_itself_to_help_merge(self, grow_to_fixture): - tc, width, height, top_tc, expected_calls = grow_to_fixture - tc._grow_to(width, height, top_tc) - assert tc._span_to_width.call_args_list == expected_calls - - def it_can_extend_its_horz_span_to_help_merge( - self, top_tc_, grid_span_, _move_content_to_, _swallow_next_tc_ - ): - grid_span_.side_effect = [1, 3, 4] - grid_width, vMerge = 4, "continue" - tc = element("w:tc") - - tc._span_to_width(grid_width, top_tc_, vMerge) - - _move_content_to_.assert_called_once_with(tc, top_tc_) - assert _swallow_next_tc_.call_args_list == [ - call(tc, grid_width, top_tc_), - call(tc, grid_width, top_tc_), - ] - assert tc.vMerge == vMerge - - def it_can_swallow_the_next_tc_help_merge(self, swallow_fixture): - tc, grid_width, top_tc, tr, expected_xml = swallow_fixture - tc._swallow_next_tc(grid_width, top_tc) - assert tr.xml == expected_xml - - def it_adds_cell_widths_on_swallow(self, add_width_fixture): - tc, grid_width, top_tc, tr, expected_xml = add_width_fixture - tc._swallow_next_tc(grid_width, top_tc) - assert tr.xml == expected_xml - - def it_raises_on_invalid_swallow(self, swallow_raise_fixture): - tc, grid_width, top_tc, tr = swallow_raise_fixture - with pytest.raises(InvalidSpanError): - tc._swallow_next_tc(grid_width, top_tc) - - def it_can_move_its_content_to_help_merge(self, move_fixture): - tc, tc_2, expected_tc_xml, expected_tc_2_xml = move_fixture - tc._move_content_to(tc_2) - assert tc.xml == expected_tc_xml - assert tc_2.xml == expected_tc_2_xml - - def it_raises_on_tr_above(self, tr_above_raise_fixture): - tc = tr_above_raise_fixture - with pytest.raises(ValueError): - tc._tr_above - - # fixtures ------------------------------------------------------- - - @pytest.fixture( - params=[ - # both cells have a width - ( - "w:tr/(w:tc/(w:tcPr/w:tcW{w:w=1440,w:type=dxa},w:p)," - "w:tc/(w:tcPr/w:tcW{w:w=1440,w:type=dxa},w:p))", - 0, - 2, - "w:tr/(w:tc/(w:tcPr/(w:tcW{w:w=2880,w:type=dxa}," - "w:gridSpan{w:val=2}),w:p))", - ), - # neither have a width - ( - "w:tr/(w:tc/w:p,w:tc/w:p)", - 0, - 2, - "w:tr/(w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p))", - ), - # only second one has a width - ( - "w:tr/(w:tc/w:p," "w:tc/(w:tcPr/w:tcW{w:w=1440,w:type=dxa},w:p))", - 0, - 2, - "w:tr/(w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p))", - ), - # only first one has a width - ( - "w:tr/(w:tc/(w:tcPr/w:tcW{w:w=1440,w:type=dxa},w:p)," "w:tc/w:p)", - 0, - 2, - "w:tr/(w:tc/(w:tcPr/(w:tcW{w:w=1440,w:type=dxa}," - "w:gridSpan{w:val=2}),w:p))", - ), - ] - ) - def add_width_fixture(self, request): - tr_cxml, tc_idx, grid_width, expected_tr_cxml = request.param - tr = element(tr_cxml) - tc = top_tc = tr[tc_idx] - expected_tr_xml = xml(expected_tr_cxml) - return tc, grid_width, top_tc, tr, expected_tr_xml - - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("snippet_idx", "row", "col", "attr_name", "expected_value"), + [ (0, 0, 0, "top", 0), (2, 0, 1, "top", 0), (2, 1, 1, "top", 0), @@ -190,63 +93,22 @@ def add_width_fixture(self, request): (4, 1, 1, "bottom", 3), (0, 0, 0, "right", 1), (1, 0, 0, "right", 2), - (0, 0, 0, "right", 1), (4, 2, 1, "right", 3), - ] + ], ) - def extents_fixture(self, request): - snippet_idx, row, col, attr_name, expected_value = request.param + def it_knows_its_extents_to_help( + self, snippet_idx: int, row: int, col: int, attr_name: str, expected_value: int + ): tbl = self._snippet_tbl(snippet_idx) tc = tbl.tr_lst[row].tc_lst[col] - return tc, attr_name, expected_value - @pytest.fixture( - params=[ - (0, 0, 0, 2, 1), - (0, 0, 1, 1, 2), - (0, 1, 1, 2, 2), - (1, 0, 0, 2, 2), - (2, 0, 0, 2, 2), - (2, 1, 2, 1, 2), - ] - ) - def grow_to_fixture(self, request, _span_to_width_): - snippet_idx, row, col, width, height = request.param - tbl = self._snippet_tbl(snippet_idx) - tc = tbl.tr_lst[row].tc_lst[col] - start = 0 if height == 1 else 1 - end = start + height - expected_calls = [ - call(width, tc, None), - call(width, tc, "restart"), - call(width, tc, "continue"), - call(width, tc, "continue"), - ][start:end] - return tc, width, height, None, expected_calls - - @pytest.fixture( - params=[ - ("w:tc/w:p", "w:tc/w:p", "w:tc/w:p", "w:tc/w:p"), - ("w:tc/w:p", "w:tc/w:p/w:r", "w:tc/w:p", "w:tc/w:p/w:r"), - ("w:tc/w:p/w:r", "w:tc/w:p", "w:tc/w:p", "w:tc/w:p/w:r"), - ("w:tc/(w:p/w:r,w:sdt)", "w:tc/w:p", "w:tc/w:p", "w:tc/(w:p/w:r,w:sdt)"), - ( - "w:tc/(w:p/w:r,w:sdt)", - "w:tc/(w:tbl,w:p)", - "w:tc/w:p", - "w:tc/(w:tbl,w:p/w:r,w:sdt)", - ), - ] - ) - def move_fixture(self, request): - tc_cxml, tc_2_cxml, expected_tc_cxml, expected_tc_2_cxml = request.param - tc, tc_2 = element(tc_cxml), element(tc_2_cxml) - expected_tc_xml = xml(expected_tc_cxml) - expected_tc_2_xml = xml(expected_tc_2_cxml) - return tc, tc_2, expected_tc_xml, expected_tc_2_xml - - @pytest.fixture( - params=[ + extent = getattr(tc, attr_name) + + assert extent == expected_value + + @pytest.mark.parametrize( + ("snippet_idx", "row", "col", "row_2", "col_2", "expected_value"), + [ (0, 0, 0, 0, 1, (0, 0, 1, 2)), (0, 0, 1, 2, 1, (0, 1, 3, 1)), (0, 2, 2, 1, 1, (1, 1, 2, 2)), @@ -257,17 +119,28 @@ def move_fixture(self, request): (2, 0, 1, 1, 0, (0, 0, 2, 2)), (2, 1, 2, 0, 1, (0, 1, 2, 2)), (4, 0, 1, 0, 0, (0, 0, 1, 3)), - ] + ], ) - def span_fixture(self, request): - snippet_idx, row, col, row_2, col_2, expected_value = request.param + def it_calculates_the_dimensions_of_a_span_to_help( + self, + snippet_idx: int, + row: int, + col: int, + row_2: int, + col_2: int, + expected_value: tuple[int, int, int, int], + ): tbl = self._snippet_tbl(snippet_idx) tc = tbl.tr_lst[row].tc_lst[col] - tc_2 = tbl.tr_lst[row_2].tc_lst[col_2] - return tc, tc_2, expected_value + other_tc = tbl.tr_lst[row_2].tc_lst[col_2] + + dimensions = tc._span_dimensions(other_tc) + + assert dimensions == expected_value - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("snippet_idx", "row", "col", "row_2", "col_2"), + [ (1, 0, 0, 1, 0), # inverted-L horz (1, 1, 0, 0, 0), # same in opposite order (2, 0, 2, 0, 1), # inverted-L vert @@ -275,17 +148,72 @@ def span_fixture(self, request): (5, 1, 0, 2, 1), # same, opposite side (6, 1, 0, 0, 1), # tee-shape vert bar (6, 0, 1, 1, 2), # same, opposite side - ] + ], + ) + def it_raises_on_invalid_span( + self, snippet_idx: int, row: int, col: int, row_2: int, col_2: int + ): + tbl = self._snippet_tbl(snippet_idx) + tc = tbl.tr_lst[row].tc_lst[col] + other_tc = tbl.tr_lst[row_2].tc_lst[col_2] + + with pytest.raises(InvalidSpanError): + tc._span_dimensions(other_tc) + + @pytest.mark.parametrize( + ("snippet_idx", "row", "col", "width", "height"), + [ + (0, 0, 0, 2, 1), + (0, 0, 1, 1, 2), + (0, 1, 1, 2, 2), + (1, 0, 0, 2, 2), + (2, 0, 0, 2, 2), + (2, 1, 2, 1, 2), + ], ) - def span_raise_fixture(self, request): - snippet_idx, row, col, row_2, col_2 = request.param + def it_can_grow_itself_to_help_merge( + self, snippet_idx: int, row: int, col: int, width: int, height: int, _span_to_width_: Mock + ): tbl = self._snippet_tbl(snippet_idx) tc = tbl.tr_lst[row].tc_lst[col] - tc_2 = tbl.tr_lst[row_2].tc_lst[col_2] - return tc, tc_2 + start = 0 if height == 1 else 1 + end = start + height + + tc._grow_to(width, height, None) - @pytest.fixture( - params=[ + assert ( + _span_to_width_.call_args_list + == [ + call(width, tc, None), + call(width, tc, "restart"), + call(width, tc, "continue"), + call(width, tc, "continue"), + ][start:end] + ) + + def it_can_extend_its_horz_span_to_help_merge( + self, top_tc_: Mock, grid_span_: Mock, _move_content_to_: Mock, _swallow_next_tc_: Mock + ): + grid_span_.side_effect = [1, 3, 4] + grid_width, vMerge = 4, "continue" + tc = cast(CT_Tc, element("w:tc")) + + tc._span_to_width(grid_width, top_tc_, vMerge) + + _move_content_to_.assert_called_once_with(tc, top_tc_) + assert _swallow_next_tc_.call_args_list == [ + call(tc, grid_width, top_tc_), + call(tc, grid_width, top_tc_), + ] + assert tc.vMerge == vMerge + + def it_knows_its_inner_content_block_item_elements(self): + tc = cast(CT_Tc, element("w:tc/(w:p,w:tbl,w:p)")) + assert [type(e) for e in tc.inner_content_elements] == [CT_P, CT_Tbl, CT_P] + + @pytest.mark.parametrize( + ("tr_cxml", "tc_idx", "grid_width", "expected_cxml"), + [ ( "w:tr/(w:tc/w:p,w:tc/w:p)", 0, @@ -302,8 +230,7 @@ def span_raise_fixture(self, request): 'w:tr/(w:tc/w:p/w:r/w:t"a",w:tc/w:p/w:r/w:t"b")', 0, 2, - 'w:tr/(w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p/w:r/w:t"a",' - 'w:p/w:r/w:t"b"))', + 'w:tr/(w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p/w:r/w:t"a",w:p/w:r/w:t"b"))', ), ( "w:tr/(w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p),w:tc/w:p)", @@ -317,75 +244,145 @@ def span_raise_fixture(self, request): 3, "w:tr/(w:tc/(w:tcPr/w:gridSpan{w:val=3},w:p))", ), - ] + ], ) - def swallow_fixture(self, request): - tr_cxml, tc_idx, grid_width, expected_tr_cxml = request.param - tr = element(tr_cxml) - tc = top_tc = tr[tc_idx] - expected_tr_xml = xml(expected_tr_cxml) - return tc, grid_width, top_tc, tr, expected_tr_xml - - @pytest.fixture( - params=[ + def it_can_swallow_the_next_tc_help_merge( + self, tr_cxml: str, tc_idx: int, grid_width: int, expected_cxml: str + ): + tr = cast(CT_Row, element(tr_cxml)) + tc = top_tc = tr.tc_lst[tc_idx] + + tc._swallow_next_tc(grid_width, top_tc) + + assert tr.xml == xml(expected_cxml) + + @pytest.mark.parametrize( + ("tr_cxml", "tc_idx", "grid_width", "expected_cxml"), + [ + # both cells have a width + ( + "w:tr/(w:tc/(w:tcPr/w:tcW{w:w=1440,w:type=dxa},w:p)," + "w:tc/(w:tcPr/w:tcW{w:w=1440,w:type=dxa},w:p))", + 0, + 2, + "w:tr/(w:tc/(w:tcPr/(w:tcW{w:w=2880,w:type=dxa},w:gridSpan{w:val=2}),w:p))", + ), + # neither have a width + ( + "w:tr/(w:tc/w:p,w:tc/w:p)", + 0, + 2, + "w:tr/(w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p))", + ), + # only second one has a width + ( + "w:tr/(w:tc/w:p,w:tc/(w:tcPr/w:tcW{w:w=1440,w:type=dxa},w:p))", + 0, + 2, + "w:tr/(w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p))", + ), + # only first one has a width + ( + "w:tr/(w:tc/(w:tcPr/w:tcW{w:w=1440,w:type=dxa},w:p),w:tc/w:p)", + 0, + 2, + "w:tr/(w:tc/(w:tcPr/(w:tcW{w:w=1440,w:type=dxa},w:gridSpan{w:val=2}),w:p))", + ), + ], + ) + def it_adds_cell_widths_on_swallow( + self, tr_cxml: str, tc_idx: int, grid_width: int, expected_cxml: str + ): + tr = cast(CT_Row, element(tr_cxml)) + tc = top_tc = tr.tc_lst[tc_idx] + tc._swallow_next_tc(grid_width, top_tc) + assert tr.xml == xml(expected_cxml) + + @pytest.mark.parametrize( + ("tr_cxml", "tc_idx", "grid_width"), + [ ("w:tr/w:tc/w:p", 0, 2), ("w:tr/(w:tc/w:p,w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p))", 0, 2), - ] + ], ) - def swallow_raise_fixture(self, request): - tr_cxml, tc_idx, grid_width = request.param - tr = element(tr_cxml) - tc = top_tc = tr[tc_idx] - return tc, grid_width, top_tc, tr - - @pytest.fixture(params=[(0, 0, 0), (4, 0, 0)]) - def tr_above_raise_fixture(self, request): - snippet_idx, row_idx, col_idx = request.param - tbl = parse_xml(snippet_seq("tbl-cells")[snippet_idx]) + def it_raises_on_invalid_swallow(self, tr_cxml: str, tc_idx: int, grid_width: int): + tr = cast(CT_Row, element(tr_cxml)) + tc = top_tc = tr.tc_lst[tc_idx] + + with pytest.raises(InvalidSpanError): + tc._swallow_next_tc(grid_width, top_tc) + + @pytest.mark.parametrize( + ("tc_cxml", "tc_2_cxml", "expected_tc_cxml", "expected_tc_2_cxml"), + [ + ("w:tc/w:p", "w:tc/w:p", "w:tc/w:p", "w:tc/w:p"), + ("w:tc/w:p", "w:tc/w:p/w:r", "w:tc/w:p", "w:tc/w:p/w:r"), + ("w:tc/w:p/w:r", "w:tc/w:p", "w:tc/w:p", "w:tc/w:p/w:r"), + ("w:tc/(w:p/w:r,w:sdt)", "w:tc/w:p", "w:tc/w:p", "w:tc/(w:p/w:r,w:sdt)"), + ( + "w:tc/(w:p/w:r,w:sdt)", + "w:tc/(w:tbl,w:p)", + "w:tc/w:p", + "w:tc/(w:tbl,w:p/w:r,w:sdt)", + ), + ], + ) + def it_can_move_its_content_to_help_merge( + self, tc_cxml: str, tc_2_cxml: str, expected_tc_cxml: str, expected_tc_2_cxml: str + ): + tc, tc_2 = cast(CT_Tc, element(tc_cxml)), cast(CT_Tc, element(tc_2_cxml)) + + tc._move_content_to(tc_2) + + assert tc.xml == xml(expected_tc_cxml) + assert tc_2.xml == xml(expected_tc_2_cxml) + + @pytest.mark.parametrize(("snippet_idx", "row_idx", "col_idx"), [(0, 0, 0), (4, 0, 0)]) + def it_raises_on_tr_above(self, snippet_idx: int, row_idx: int, col_idx: int): + tbl = cast(CT_Tbl, parse_xml(snippet_seq("tbl-cells")[snippet_idx])) tc = tbl.tr_lst[row_idx].tc_lst[col_idx] - return tc - # fixture components --------------------------------------------- + with pytest.raises(ValueError, match="no tr above topmost tr"): + tc._tr_above + + # fixtures ------------------------------------------------------- @pytest.fixture - def grid_span_(self, request): + def grid_span_(self, request: FixtureRequest): return property_mock(request, CT_Tc, "grid_span") @pytest.fixture - def _grow_to_(self, request): + def _grow_to_(self, request: FixtureRequest): return method_mock(request, CT_Tc, "_grow_to") @pytest.fixture - def _move_content_to_(self, request): + def _move_content_to_(self, request: FixtureRequest): return method_mock(request, CT_Tc, "_move_content_to") @pytest.fixture - def _span_dimensions_(self, request): + def _span_dimensions_(self, request: FixtureRequest): return method_mock(request, CT_Tc, "_span_dimensions") @pytest.fixture - def _span_to_width_(self, request): + def _span_to_width_(self, request: FixtureRequest): return method_mock(request, CT_Tc, "_span_to_width", autospec=False) - def _snippet_tbl(self, idx): - """ - Return a element for snippet at *idx* in 'tbl-cells' snippet - file. - """ - return parse_xml(snippet_seq("tbl-cells")[idx]) + def _snippet_tbl(self, idx: int) -> CT_Tbl: + """A element for snippet at `idx` in 'tbl-cells' snippet file.""" + return cast(CT_Tbl, parse_xml(snippet_seq("tbl-cells")[idx])) @pytest.fixture - def _swallow_next_tc_(self, request): + def _swallow_next_tc_(self, request: FixtureRequest): return method_mock(request, CT_Tc, "_swallow_next_tc") @pytest.fixture - def _tbl_(self, request): + def _tbl_(self, request: FixtureRequest): return property_mock(request, CT_Tc, "_tbl") @pytest.fixture - def top_tc_(self, request): + def top_tc_(self, request: FixtureRequest): return instance_mock(request, CT_Tc) @pytest.fixture - def tr_(self, request): + def tr_(self, request: FixtureRequest): return instance_mock(request, CT_Row) diff --git a/tests/oxml/test_xmlchemy.py b/tests/oxml/test_xmlchemy.py index 15f68fac..66f197cd 100644 --- a/tests/oxml/test_xmlchemy.py +++ b/tests/oxml/test_xmlchemy.py @@ -1,37 +1,36 @@ -# encoding: utf-8 - -""" -Test suite for docx.oxml.xmlchemy -""" - -from __future__ import absolute_import, print_function, unicode_literals +"""Test suite for docx.oxml.xmlchemy.""" import pytest -from docx.compat import Unicode -from docx.oxml import parse_xml, register_element_cls from docx.oxml.exceptions import InvalidXmlError from docx.oxml.ns import qn +from docx.oxml.parser import parse_xml, register_element_cls from docx.oxml.simpletypes import BaseIntType from docx.oxml.xmlchemy import ( BaseOxmlElement, Choice, - serialize_for_reading, - OneOrMore, OneAndOnlyOne, + OneOrMore, OptionalAttribute, RequiredAttribute, + XmlString, ZeroOrMore, ZeroOrOne, ZeroOrOneChoice, - XmlString, + serialize_for_reading, ) from ..unitdata import BaseBuilder from .unitdata.text import a_b, a_u, an_i, an_rPr -class DescribeBaseOxmlElement(object): +class DescribeBaseOxmlElement: + def it_can_call_xpath_with_custom_namespaces(self): + element = CT_ParentBuilder().with_nsdecls().element + # -- this should not raise TypeError -- + results = element.xpath(".//w:zooChild", namespaces={"w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main"}) + assert results == [] + def it_can_find_the_first_of_its_children_named_in_a_sequence(self, first_fixture): element, tagnames, matching_child = first_fixture assert element.first_child_found_in(*tagnames) is matching_child @@ -123,7 +122,7 @@ def rPr_bldr(self, children): return rPr_bldr -class DescribeSerializeForReading(object): +class DescribeSerializeForReading: def it_pretty_prints_an_lxml_element(self, pretty_fixture): element, expected_xml_text = pretty_fixture xml_text = serialize_for_reading(element) @@ -132,13 +131,13 @@ def it_pretty_prints_an_lxml_element(self, pretty_fixture): def it_returns_unicode_text(self, type_fixture): element = type_fixture xml_text = serialize_for_reading(element) - assert isinstance(xml_text, Unicode) + assert isinstance(xml_text, str) # fixtures --------------------------------------------- @pytest.fixture def pretty_fixture(self, element): - expected_xml_text = "\n" " text\n" "\n" + expected_xml_text = "\n text\n\n" return element, expected_xml_text @pytest.fixture @@ -152,7 +151,7 @@ def element(self): return parse_xml("text") -class DescribeXmlString(object): +class DescribeXmlString: def it_parses_a_line_to_help_compare(self, parse_fixture): """ This internal function is important to test separately because if it @@ -183,8 +182,7 @@ def it_knows_if_two_xml_lines_are_equivalent(self, xml_line_case): ('', "", None), ("t", "", "t"), ( - '2013-12-23T23:15:00Z", + '2013-12-23T23:15:00Z', "", @@ -243,7 +241,7 @@ def xml_line_case(self, request): return line, other, differs -class DescribeChoice(object): +class DescribeChoice: def it_adds_a_getter_property_for_the_choice_element(self, getter_fixture): parent, expected_choice = getter_fixture assert parent.choice is expected_choice @@ -257,22 +255,16 @@ def it_adds_an_insert_method_for_the_child_element(self, insert_fixture): parent, choice, expected_xml = insert_fixture parent._insert_choice(choice) assert parent.xml == expected_xml - assert parent._insert_choice.__doc__.startswith( - "Return the passed ```` " - ) + assert parent._insert_choice.__doc__.startswith("Return the passed ```` ") def it_adds_an_add_method_for_the_child_element(self, add_fixture): parent, expected_xml = add_fixture choice = parent._add_choice() assert parent.xml == expected_xml assert isinstance(choice, CT_Choice) - assert parent._add_choice.__doc__.startswith( - "Add a new ```` child element " - ) + assert parent._add_choice.__doc__.startswith("Add a new ```` child element ") - def it_adds_a_get_or_change_to_method_for_the_child_element( - self, get_or_change_to_fixture - ): + def it_adds_a_get_or_change_to_method_for_the_child_element(self, get_or_change_to_fixture): parent, expected_xml = get_or_change_to_fixture choice = parent.get_or_change_to_choice() assert isinstance(choice, CT_Choice) @@ -309,10 +301,7 @@ def getter_fixture(self, request): @pytest.fixture def insert_fixture(self): parent = ( - a_parent() - .with_nsdecls() - .with_child(an_oomChild()) - .with_child(an_oooChild()) + a_parent().with_nsdecls().with_child(an_oomChild()).with_child(an_oooChild()) ).element choice = a_choice().with_nsdecls().element expected_xml = ( @@ -341,7 +330,7 @@ def parent_bldr(self, choice_tag=None): return parent_bldr -class DescribeOneAndOnlyOne(object): +class DescribeOneAndOnlyOne: def it_adds_a_getter_property_for_the_child_element(self, getter_fixture): parent, oooChild = getter_fixture assert parent.oooChild is oooChild @@ -355,7 +344,7 @@ def getter_fixture(self): return parent, oooChild -class DescribeOneOrMore(object): +class DescribeOneOrMore: def it_adds_a_getter_property_for_the_child_element_list(self, getter_fixture): parent, oomChild = getter_fixture assert parent.oomChild_lst[0] is oomChild @@ -369,27 +358,21 @@ def it_adds_an_insert_method_for_the_child_element(self, insert_fixture): parent, oomChild, expected_xml = insert_fixture parent._insert_oomChild(oomChild) assert parent.xml == expected_xml - assert parent._insert_oomChild.__doc__.startswith( - "Return the passed ```` " - ) + assert parent._insert_oomChild.__doc__.startswith("Return the passed ```` ") def it_adds_a_private_add_method_for_the_child_element(self, add_fixture): parent, expected_xml = add_fixture oomChild = parent._add_oomChild() assert parent.xml == expected_xml assert isinstance(oomChild, CT_OomChild) - assert parent._add_oomChild.__doc__.startswith( - "Add a new ```` child element " - ) + assert parent._add_oomChild.__doc__.startswith("Add a new ```` child element ") def it_adds_a_public_add_method_for_the_child_element(self, add_fixture): parent, expected_xml = add_fixture oomChild = parent.add_oomChild() assert parent.xml == expected_xml assert isinstance(oomChild, CT_OomChild) - assert parent._add_oomChild.__doc__.startswith( - "Add a new ```` child element " - ) + assert parent._add_oomChild.__doc__.startswith("Add a new ```` child element ") # fixtures ------------------------------------------------------- @@ -440,7 +423,7 @@ def parent_bldr(self, oomChild_is_present): return parent_bldr -class DescribeOptionalAttribute(object): +class DescribeOptionalAttribute: def it_adds_a_getter_property_for_the_attr_value(self, getter_fixture): parent, optAttr_python_value = getter_fixture assert parent.optAttr == optAttr_python_value @@ -451,9 +434,7 @@ def it_adds_a_setter_property_for_the_attr(self, setter_fixture): assert parent.xml == expected_xml def it_adds_a_docstring_for_the_property(self): - assert CT_Parent.optAttr.__doc__.startswith( - "ST_IntegerType type-converted value of " - ) + assert CT_Parent.optAttr.__doc__.startswith("ST_IntegerType type-converted value of ") # fixtures ------------------------------------------------------- @@ -473,7 +454,7 @@ def setter_fixture(self, request): return parent, value, expected_xml -class DescribeRequiredAttribute(object): +class DescribeRequiredAttribute: def it_adds_a_getter_property_for_the_attr_value(self, getter_fixture): parent, reqAttr_python_value = getter_fixture assert parent.reqAttr == reqAttr_python_value @@ -484,9 +465,7 @@ def it_adds_a_setter_property_for_the_attr(self, setter_fixture): assert parent.xml == expected_xml def it_adds_a_docstring_for_the_property(self): - assert CT_Parent.reqAttr.__doc__.startswith( - "ST_IntegerType type-converted value of " - ) + assert CT_Parent.reqAttr.__doc__.startswith("ST_IntegerType type-converted value of ") def it_raises_on_get_when_attribute_not_present(self): parent = a_parent().with_nsdecls().element @@ -525,7 +504,7 @@ def setter_fixture(self): return parent, value, expected_xml -class DescribeZeroOrMore(object): +class DescribeZeroOrMore: def it_adds_a_getter_property_for_the_child_element_list(self, getter_fixture): parent, zomChild = getter_fixture assert parent.zomChild_lst[0] is zomChild @@ -539,27 +518,21 @@ def it_adds_an_insert_method_for_the_child_element(self, insert_fixture): parent, zomChild, expected_xml = insert_fixture parent._insert_zomChild(zomChild) assert parent.xml == expected_xml - assert parent._insert_zomChild.__doc__.startswith( - "Return the passed ```` " - ) + assert parent._insert_zomChild.__doc__.startswith("Return the passed ```` ") def it_adds_an_add_method_for_the_child_element(self, add_fixture): parent, expected_xml = add_fixture zomChild = parent._add_zomChild() assert parent.xml == expected_xml assert isinstance(zomChild, CT_ZomChild) - assert parent._add_zomChild.__doc__.startswith( - "Add a new ```` child element " - ) + assert parent._add_zomChild.__doc__.startswith("Add a new ```` child element ") def it_adds_a_public_add_method_for_the_child_element(self, add_fixture): parent, expected_xml = add_fixture zomChild = parent.add_zomChild() assert parent.xml == expected_xml assert isinstance(zomChild, CT_ZomChild) - assert parent._add_zomChild.__doc__.startswith( - "Add a new ```` child element " - ) + assert parent._add_zomChild.__doc__.startswith("Add a new ```` child element ") def it_removes_the_property_root_name_used_for_declaration(self): assert not hasattr(CT_Parent, "zomChild") @@ -611,7 +584,7 @@ def parent_bldr(self, zomChild_is_present): return parent_bldr -class DescribeZeroOrOne(object): +class DescribeZeroOrOne: def it_adds_a_getter_property_for_the_child_element(self, getter_fixture): parent, zooChild = getter_fixture assert parent.zooChild is zooChild @@ -621,17 +594,13 @@ def it_adds_an_add_method_for_the_child_element(self, add_fixture): zooChild = parent._add_zooChild() assert parent.xml == expected_xml assert isinstance(zooChild, CT_ZooChild) - assert parent._add_zooChild.__doc__.startswith( - "Add a new ```` child element " - ) + assert parent._add_zooChild.__doc__.startswith("Add a new ```` child element ") def it_adds_an_insert_method_for_the_child_element(self, insert_fixture): parent, zooChild, expected_xml = insert_fixture parent._insert_zooChild(zooChild) assert parent.xml == expected_xml - assert parent._insert_zooChild.__doc__.startswith( - "Return the passed ```` " - ) + assert parent._insert_zooChild.__doc__.startswith("Return the passed ```` ") def it_adds_a_get_or_add_method_for_the_child_element(self, get_or_add_fixture): parent, expected_xml = get_or_add_fixture @@ -702,7 +671,7 @@ def parent_bldr(self, zooChild_is_present): return parent_bldr -class DescribeZeroOrOneChoice(object): +class DescribeZeroOrOneChoice: def it_adds_a_getter_for_the_current_choice(self, getter_fixture): parent, expected_choice = getter_fixture assert parent.eg_zooChoice is expected_choice @@ -750,9 +719,7 @@ class CT_Parent(BaseOxmlElement): (Choice("w:choice"), Choice("w:choice2")), successors=("w:oomChild", "w:oooChild"), ) - oomChild = OneOrMore( - "w:oomChild", successors=("w:oooChild", "w:zomChild", "w:zooChild") - ) + oomChild = OneOrMore("w:oomChild", successors=("w:oooChild", "w:zomChild", "w:zooChild")) oooChild = OneAndOnlyOne("w:oooChild") zomChild = ZeroOrMore("w:zomChild", successors=("w:zooChild",)) zooChild = ZeroOrOne("w:zooChild", successors=()) diff --git a/tests/oxml/text/test_hyperlink.py b/tests/oxml/text/test_hyperlink.py new file mode 100644 index 00000000..f5cec476 --- /dev/null +++ b/tests/oxml/text/test_hyperlink.py @@ -0,0 +1,45 @@ +"""Test suite for the docx.oxml.text.hyperlink module.""" + +from typing import cast + +import pytest + +from docx.oxml.text.hyperlink import CT_Hyperlink +from docx.oxml.text.run import CT_R + +from ...unitutil.cxml import element + + +class DescribeCT_Hyperlink: + """Unit-test suite for the CT_Hyperlink () element.""" + + def it_has_a_relationship_that_contains_the_hyperlink_address(self): + cxml = 'w:hyperlink{r:id=rId6}/w:r/w:t"post"' + hyperlink = cast(CT_Hyperlink, element(cxml)) + + rId = hyperlink.rId + + assert rId == "rId6" + + @pytest.mark.parametrize( + ("cxml", "expected_value"), + [ + # -- default (when omitted) is True, somewhat surprisingly -- + ("w:hyperlink{r:id=rId6}", True), + ("w:hyperlink{r:id=rId6,w:history=0}", False), + ("w:hyperlink{r:id=rId6,w:history=1}", True), + ], + ) + def it_knows_whether_it_has_been_clicked_on_aka_visited(self, cxml: str, expected_value: bool): + hyperlink = cast(CT_Hyperlink, element(cxml)) + assert hyperlink.history is expected_value + + def it_has_zero_or_more_runs_containing_the_hyperlink_text(self): + cxml = 'w:hyperlink{r:id=rId6,w:history=1}/(w:r/w:t"blog",w:r/w:t" post")' + hyperlink = cast(CT_Hyperlink, element(cxml)) + + rs = hyperlink.r_lst + + assert [type(r) for r in rs] == [CT_R, CT_R] + assert rs[0].text == "blog" + assert rs[1].text == " post" diff --git a/tests/oxml/text/test_run.py b/tests/oxml/text/test_run.py index 4d1a8c15..d4884837 100644 --- a/tests/oxml/text/test_run.py +++ b/tests/oxml/text/test_run.py @@ -1,21 +1,20 @@ -""" -Test suite for the docx.oxml.text.run module. -""" +"""Test suite for the docx.oxml.text.run module.""" + +from typing import cast + import pytest -from ...unitutil.cxml import element, xml +from docx.oxml.text.run import CT_R +from ...unitutil.cxml import element, xml -class DescribeCT_R(object): - def it_can_add_a_t_preserving_edge_whitespace(self, add_t_fixture): - r, text, expected_xml = add_t_fixture - r.add_t(text) - assert r.xml == expected_xml - # fixtures ------------------------------------------------------- +class DescribeCT_R: + """Unit-test suite for the CT_R (run, ) element.""" - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("initial_cxml", "text", "expected_cxml"), + [ ("w:r", "foobar", 'w:r/w:t"foobar"'), ("w:r", "foobar ", 'w:r/w:t{xml:space=preserve}"foobar "'), ( @@ -23,43 +22,29 @@ def it_can_add_a_t_preserving_edge_whitespace(self, add_t_fixture): "foobar", 'w:r/(w:rPr/w:rStyle{w:val=emphasis}, w:cr, w:t"foobar")', ), - ] + ], ) - def add_t_fixture(self, request): - initial_cxml, text, expected_cxml = request.param - r = element(initial_cxml) + def it_can_add_a_t_preserving_edge_whitespace( + self, initial_cxml: str, text: str, expected_cxml: str + ): + r = cast(CT_R, element(initial_cxml)) expected_xml = xml(expected_cxml) - return r, text, expected_xml + r.add_t(text) -class TestCT_R: - def test_texts(self, texts_item): - element, ret = texts_item - assert element.texts == ret + assert r.xml == expected_xml - def test_itertext(self, itertext_item): - element, ret = itertext_item - assert "".join(element.itertext()) == ret + def it_can_assemble_the_text_in_the_run(self): + cxml = 'w:r/(w:br,w:cr,w:noBreakHyphen,w:ptab,w:t"foobar",w:tab)' + r = cast(CT_R, element(cxml)) - def load_params(self, request): - xml, expected_text = request.param - ctr = element(xml) - return ctr, expected_text + assert r.text == "\n\n-\tfoobar\t" - @pytest.fixture( - params=[ - ('w:r/w:t"foobar"', "foobar"), - ('w:r/(w:t"abc", w:tab, w:t"def", w:cr)', "abcdef"), - ] - ) - def itertext_item(self, request): - return self.load_params(request) + def it_provides_texts_alias_for_text(self): + r = cast(CT_R, element('w:r/w:t"alias"')) - @pytest.fixture( - params=[ - ('w:r/w:t"foobar"', "foobar"), - ('w:r/(w:t"abc", w:tab, w:t"def", w:cr)', "abc\tdef\n"), - ] - ) - def texts_item(self, request): - return self.load_params(request) + assert r.texts == "alias" + + r.texts = "updated" + + assert r.text == "updated" diff --git a/tests/oxml/unitdata/numbering.py b/tests/oxml/unitdata/numbering.py index 92f943fd..386ec611 100644 --- a/tests/oxml/unitdata/numbering.py +++ b/tests/oxml/unitdata/numbering.py @@ -1,8 +1,4 @@ -# encoding: utf-8 - -""" -Test data builders for numbering part XML elements -""" +"""Test data builders for numbering part XML elements.""" from ...unitdata import BaseBuilder diff --git a/tests/oxml/unitdata/section.py b/tests/oxml/unitdata/section.py index 13194f4c..397ade7d 100644 --- a/tests/oxml/unitdata/section.py +++ b/tests/oxml/unitdata/section.py @@ -1,8 +1,4 @@ -# encoding: utf-8 - -""" -Test data builders for section-related XML elements -""" +"""Test data builders for section-related XML elements.""" from ...unitdata import BaseBuilder diff --git a/tests/oxml/unitdata/shared.py b/tests/oxml/unitdata/shared.py index a7007862..bf67463e 100644 --- a/tests/oxml/unitdata/shared.py +++ b/tests/oxml/unitdata/shared.py @@ -1,8 +1,4 @@ -# encoding: utf-8 - -""" -Test data builders shared by more than one other module -""" +"""Test data builders shared by more than one other module.""" from ...unitdata import BaseBuilder diff --git a/tests/oxml/unitdata/styles.py b/tests/oxml/unitdata/styles.py index 0411c93e..24acd5ed 100644 --- a/tests/oxml/unitdata/styles.py +++ b/tests/oxml/unitdata/styles.py @@ -1,8 +1,4 @@ -# encoding: utf-8 - -""" -Test data builders for styles part XML elements -""" +"""Test data builders for styles part XML elements.""" from ...unitdata import BaseBuilder diff --git a/tests/oxml/unitdata/text.py b/tests/oxml/unitdata/text.py index de1d984d..8bf60bbe 100644 --- a/tests/oxml/unitdata/text.py +++ b/tests/oxml/unitdata/text.py @@ -1,8 +1,4 @@ -# encoding: utf-8 - -""" -Test data builders for text XML elements -""" +"""Test data builders for text XML elements.""" from ...unitdata import BaseBuilder from .shared import CT_OnOffBuilder, CT_StringBuilder diff --git a/tests/parts/test_comments.py b/tests/parts/test_comments.py new file mode 100644 index 00000000..049c9e73 --- /dev/null +++ b/tests/parts/test_comments.py @@ -0,0 +1,87 @@ +"""Unit test suite for the docx.parts.hdrftr module.""" + +from __future__ import annotations + +from typing import cast + +import pytest + +from docx.comments import Comments +from docx.opc.constants import CONTENT_TYPE as CT +from docx.opc.constants import RELATIONSHIP_TYPE as RT +from docx.opc.packuri import PackURI +from docx.opc.part import PartFactory +from docx.oxml.comments import CT_Comments +from docx.package import Package +from docx.parts.comments import CommentsPart + +from ..unitutil.cxml import element +from ..unitutil.mock import FixtureRequest, Mock, class_mock, instance_mock, method_mock + + +class DescribeCommentsPart: + """Unit test suite for `docx.parts.comments.CommentsPart` objects.""" + + def it_is_used_by_the_part_loader_to_construct_a_comments_part( + self, package_: Mock, CommentsPart_load_: Mock, comments_part_: Mock + ): + partname = PackURI("/word/comments.xml") + content_type = CT.WML_COMMENTS + reltype = RT.COMMENTS + blob = b"" + CommentsPart_load_.return_value = comments_part_ + + part = PartFactory(partname, content_type, reltype, blob, package_) + + CommentsPart_load_.assert_called_once_with(partname, content_type, blob, package_) + assert part is comments_part_ + + def it_provides_access_to_its_comments_collection( + self, Comments_: Mock, comments_: Mock, package_: Mock + ): + Comments_.return_value = comments_ + comments_elm = cast(CT_Comments, element("w:comments")) + comments_part = CommentsPart( + PackURI("/word/comments.xml"), CT.WML_COMMENTS, comments_elm, package_ + ) + + comments = comments_part.comments + + Comments_.assert_called_once_with(comments_part.element, comments_part) + assert comments is comments_ + + def it_constructs_a_default_comments_part_to_help(self): + package = Package() + + comments_part = CommentsPart.default(package) + + assert isinstance(comments_part, CommentsPart) + assert comments_part.partname == "/word/comments.xml" + assert comments_part.content_type == CT.WML_COMMENTS + assert comments_part.package is package + assert comments_part.element.tag == ( + "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}comments" + ) + assert len(comments_part.element) == 0 + + # -- fixtures -------------------------------------------------------------------------------- + + @pytest.fixture + def Comments_(self, request: FixtureRequest) -> Mock: + return class_mock(request, "docx.parts.comments.Comments") + + @pytest.fixture + def comments_(self, request: FixtureRequest) -> Mock: + return instance_mock(request, Comments) + + @pytest.fixture + def comments_part_(self, request: FixtureRequest) -> Mock: + return instance_mock(request, CommentsPart) + + @pytest.fixture + def CommentsPart_load_(self, request: FixtureRequest) -> Mock: + return method_mock(request, CommentsPart, "load", autospec=False) + + @pytest.fixture + def package_(self, request: FixtureRequest) -> Mock: + return instance_mock(request, Package) diff --git a/tests/parts/test_document.py b/tests/parts/test_document.py index f4e1e06a..8b2b78ce 100644 --- a/tests/parts/test_document.py +++ b/tests/parts/test_document.py @@ -1,15 +1,17 @@ -# encoding: utf-8 +# pyright: reportPrivateUsage=false -"""Unit test suite for the docx.parts.document module""" - -from __future__ import absolute_import, division, print_function, unicode_literals +"""Unit test suite for the docx.parts.document module.""" import pytest +from docx.comments import Comments from docx.enum.style import WD_STYLE_TYPE +from docx.opc.constants import CONTENT_TYPE as CT from docx.opc.constants import RELATIONSHIP_TYPE as RT from docx.opc.coreprops import CoreProperties +from docx.opc.packuri import PackURI from docx.package import Package +from docx.parts.comments import CommentsPart from docx.parts.document import DocumentPart from docx.parts.hdrftr import FooterPart, HeaderPart from docx.parts.numbering import NumberingPart @@ -19,15 +21,26 @@ from docx.styles.style import BaseStyle from docx.styles.styles import Styles -from ..oxml.parts.unitdata.document import a_body, a_document -from ..unitutil.mock import class_mock, instance_mock, method_mock, property_mock +from ..unitutil.cxml import element +from ..unitutil.mock import ( + FixtureRequest, + Mock, + class_mock, + instance_mock, + method_mock, + property_mock, +) -class DescribeDocumentPart(object): - def it_can_add_a_footer_part(self, package_, FooterPart_, footer_part_, relate_to_): +class DescribeDocumentPart: + def it_can_add_a_footer_part( + self, package_: Mock, FooterPart_: Mock, footer_part_: Mock, relate_to_: Mock + ): FooterPart_.new.return_value = footer_part_ relate_to_.return_value = "rId12" - document_part = DocumentPart(None, None, None, package_) + document_part = DocumentPart( + PackURI("/word/document.xml"), CT.WML_DOCUMENT, element("w:document"), package_ + ) footer_part, rId = document_part.add_footer_part() @@ -36,10 +49,14 @@ def it_can_add_a_footer_part(self, package_, FooterPart_, footer_part_, relate_t assert footer_part is footer_part_ assert rId == "rId12" - def it_can_add_a_header_part(self, package_, HeaderPart_, header_part_, relate_to_): + def it_can_add_a_header_part( + self, package_: Mock, HeaderPart_: Mock, header_part_: Mock, relate_to_: Mock + ): HeaderPart_.new.return_value = header_part_ relate_to_.return_value = "rId7" - document_part = DocumentPart(None, None, None, package_) + document_part = DocumentPart( + PackURI("/word/document.xml"), CT.WML_DOCUMENT, element("w:document"), package_ + ) header_part, rId = document_part.add_header_part() @@ -48,19 +65,23 @@ def it_can_add_a_header_part(self, package_, HeaderPart_, header_part_, relate_t assert header_part is header_part_ assert rId == "rId7" - def it_can_drop_a_specified_header_part(self, drop_rel_): - document_part = DocumentPart(None, None, None, None) + def it_can_drop_a_specified_header_part(self, drop_rel_: Mock, package_: Mock): + document_part = DocumentPart( + PackURI("/word/document.xml"), CT.WML_DOCUMENT, element("w:document"), package_ + ) document_part.drop_header_part("rId42") drop_rel_.assert_called_once_with(document_part, "rId42") def it_provides_access_to_a_footer_part_by_rId( - self, related_parts_prop_, related_parts_, footer_part_ + self, related_parts_prop_: Mock, related_parts_: Mock, footer_part_: Mock, package_: Mock ): related_parts_prop_.return_value = related_parts_ related_parts_.__getitem__.return_value = footer_part_ - document_part = DocumentPart(None, None, None, None) + document_part = DocumentPart( + PackURI("/word/document.xml"), CT.WML_DOCUMENT, element("w:document"), package_ + ) footer_part = document_part.footer_part("rId9") @@ -68,50 +89,90 @@ def it_provides_access_to_a_footer_part_by_rId( assert footer_part is footer_part_ def it_provides_access_to_a_header_part_by_rId( - self, related_parts_prop_, related_parts_, header_part_ + self, related_parts_prop_: Mock, related_parts_: Mock, header_part_: Mock, package_: Mock ): related_parts_prop_.return_value = related_parts_ related_parts_.__getitem__.return_value = header_part_ - document_part = DocumentPart(None, None, None, None) + document_part = DocumentPart( + PackURI("/word/document.xml"), CT.WML_DOCUMENT, element("w:document"), package_ + ) header_part = document_part.header_part("rId11") related_parts_.__getitem__.assert_called_once_with("rId11") assert header_part is header_part_ - def it_can_save_the_package_to_a_file(self, save_fixture): - document, file_ = save_fixture - document.save(file_) - document._package.save.assert_called_once_with(file_) + def it_can_save_the_package_to_a_file(self, package_: Mock): + document_part = DocumentPart( + PackURI("/word/document.xml"), CT.WML_DOCUMENT, element("w:document"), package_ + ) + + document_part.save("foobar.docx") + + package_.save.assert_called_once_with("foobar.docx") - def it_provides_access_to_the_document_settings(self, settings_fixture): - document_part, settings_ = settings_fixture - settings = document_part.settings - assert settings is settings_ + def it_provides_access_to_the_comments_added_to_the_document( + self, _comments_part_prop_: Mock, comments_part_: Mock, comments_: Mock, package_: Mock + ): + comments_part_.comments = comments_ + _comments_part_prop_.return_value = comments_part_ + document_part = DocumentPart( + PackURI("/word/document.xml"), CT.WML_DOCUMENT, element("w:document"), package_ + ) + + assert document_part.comments is comments_ - def it_provides_access_to_the_document_styles(self, styles_fixture): - document_part, styles_ = styles_fixture - styles = document_part.styles - assert styles is styles_ + def it_provides_access_to_the_document_settings( + self, _settings_part_prop_: Mock, settings_part_: Mock, settings_: Mock, package_: Mock + ): + settings_part_.settings = settings_ + _settings_part_prop_.return_value = settings_part_ + document_part = DocumentPart( + PackURI("/word/document.xml"), CT.WML_DOCUMENT, element("w:document"), package_ + ) - def it_provides_access_to_its_core_properties(self, core_props_fixture): - document_part, core_properties_ = core_props_fixture - core_properties = document_part.core_properties - assert core_properties is core_properties_ + assert document_part.settings is settings_ + + def it_provides_access_to_the_document_styles( + self, _styles_part_prop_: Mock, styles_part_: Mock, styles_: Mock, package_: Mock + ): + styles_part_.styles = styles_ + _styles_part_prop_.return_value = styles_part_ + document_part = DocumentPart( + PackURI("/word/document.xml"), CT.WML_DOCUMENT, element("w:document"), package_ + ) + + assert document_part.styles is styles_ + + def it_provides_access_to_its_core_properties(self, package_: Mock, core_properties_: Mock): + document_part = DocumentPart( + PackURI("/word/document.xml"), CT.WML_DOCUMENT, element("w:document"), package_ + ) + package_.core_properties = core_properties_ + + assert document_part.core_properties is core_properties_ def it_provides_access_to_the_inline_shapes_in_the_document( - self, inline_shapes_fixture + self, InlineShapes_: Mock, package_: Mock ): - document, InlineShapes_, body_elm = inline_shapes_fixture - inline_shapes = document.inline_shapes - InlineShapes_.assert_called_once_with(body_elm, document) + document_elm = element("w:document/w:body") + body_elm = document_elm[0] + document_part = DocumentPart( + PackURI("/word/document.xml"), CT.WML_DOCUMENT, document_elm, package_ + ) + + inline_shapes = document_part.inline_shapes + + InlineShapes_.assert_called_once_with(body_elm, document_part) assert inline_shapes is InlineShapes_.return_value def it_provides_access_to_the_numbering_part( - self, part_related_by_, numbering_part_ + self, part_related_by_: Mock, numbering_part_: Mock, package_: Mock ): part_related_by_.return_value = numbering_part_ - document_part = DocumentPart(None, None, None, None) + document_part = DocumentPart( + PackURI("/word/document.xml"), CT.WML_DOCUMENT, element("w:document"), package_ + ) numbering_part = document_part.numbering_part @@ -119,43 +180,93 @@ def it_provides_access_to_the_numbering_part( assert numbering_part is numbering_part_ def and_it_creates_a_numbering_part_if_not_present( - self, part_related_by_, relate_to_, NumberingPart_, numbering_part_ + self, + part_related_by_: Mock, + relate_to_: Mock, + NumberingPart_: Mock, + numbering_part_: Mock, + package_: Mock, ): part_related_by_.side_effect = KeyError NumberingPart_.default.return_value = numbering_part_ - document_part = DocumentPart(None, None, None, None) + document_part = DocumentPart( + PackURI("/word/document.xml"), CT.WML_DOCUMENT, element("w:document"), package_ + ) numbering_part = document_part.numbering_part - NumberingPart_.default.assert_called_once_with(None) + NumberingPart_.default.assert_called_once_with(package_) relate_to_.assert_called_once_with(document_part, numbering_part_, RT.NUMBERING) assert numbering_part is numbering_part_ - def it_can_get_a_style_by_id(self, styles_prop_, styles_, style_): + def it_can_get_a_style_by_id( + self, styles_prop_: Mock, styles_: Mock, style_: Mock, package_: Mock + ): styles_prop_.return_value = styles_ styles_.get_by_id.return_value = style_ - document_part = DocumentPart(None, None, None, None) + document_part = DocumentPart( + PackURI("/word/document.xml"), CT.WML_DOCUMENT, element("w:document"), package_ + ) style = document_part.get_style("BodyText", WD_STYLE_TYPE.PARAGRAPH) styles_.get_by_id.assert_called_once_with("BodyText", WD_STYLE_TYPE.PARAGRAPH) assert style is style_ - def it_can_get_the_id_of_a_style(self, style_, styles_prop_, styles_): + def it_can_get_the_id_of_a_style( + self, style_: Mock, styles_prop_: Mock, styles_: Mock, package_: Mock + ): styles_prop_.return_value = styles_ styles_.get_style_id.return_value = "BodyCharacter" - document_part = DocumentPart(None, None, None, None) + document_part = DocumentPart( + PackURI("/word/document.xml"), CT.WML_DOCUMENT, element("w:document"), package_ + ) style_id = document_part.get_style_id(style_, WD_STYLE_TYPE.CHARACTER) styles_.get_style_id.assert_called_once_with(style_, WD_STYLE_TYPE.CHARACTER) assert style_id == "BodyCharacter" + def it_provides_access_to_its_comments_part_to_help( + self, package_: Mock, part_related_by_: Mock, comments_part_: Mock + ): + part_related_by_.return_value = comments_part_ + document_part = DocumentPart( + PackURI("/word/document.xml"), CT.WML_DOCUMENT, element("w:document"), package_ + ) + + comments_part = document_part._comments_part + + part_related_by_.assert_called_once_with(document_part, RT.COMMENTS) + assert comments_part is comments_part_ + + def and_it_creates_a_default_comments_part_if_not_present( + self, + package_: Mock, + part_related_by_: Mock, + CommentsPart_: Mock, + comments_part_: Mock, + relate_to_: Mock, + ): + part_related_by_.side_effect = KeyError + CommentsPart_.default.return_value = comments_part_ + document_part = DocumentPart( + PackURI("/word/document.xml"), CT.WML_DOCUMENT, element("w:document"), package_ + ) + + comments_part = document_part._comments_part + + CommentsPart_.default.assert_called_once_with(package_) + relate_to_.assert_called_once_with(document_part, comments_part_, RT.COMMENTS) + assert comments_part is comments_part_ + def it_provides_access_to_its_settings_part_to_help( - self, part_related_by_, settings_part_ + self, part_related_by_: Mock, settings_part_: Mock, package_: Mock ): part_related_by_.return_value = settings_part_ - document_part = DocumentPart(None, None, None, None) + document_part = DocumentPart( + PackURI("/word/document.xml"), CT.WML_DOCUMENT, element("w:document"), package_ + ) settings_part = document_part._settings_part @@ -163,11 +274,18 @@ def it_provides_access_to_its_settings_part_to_help( assert settings_part is settings_part_ def and_it_creates_a_default_settings_part_if_not_present( - self, package_, part_related_by_, SettingsPart_, settings_part_, relate_to_ + self, + package_: Mock, + part_related_by_: Mock, + SettingsPart_: Mock, + settings_part_: Mock, + relate_to_: Mock, ): part_related_by_.side_effect = KeyError SettingsPart_.default.return_value = settings_part_ - document_part = DocumentPart(None, None, None, package_) + document_part = DocumentPart( + PackURI("/word/document.xml"), CT.WML_DOCUMENT, element("w:document"), package_ + ) settings_part = document_part._settings_part @@ -176,10 +294,12 @@ def and_it_creates_a_default_settings_part_if_not_present( assert settings_part is settings_part_ def it_provides_access_to_its_styles_part_to_help( - self, part_related_by_, styles_part_ + self, part_related_by_: Mock, styles_part_: Mock, package_: Mock ): part_related_by_.return_value = styles_part_ - document_part = DocumentPart(None, None, None, None) + document_part = DocumentPart( + PackURI("/word/document.xml"), CT.WML_DOCUMENT, element("w:document"), package_ + ) styles_part = document_part._styles_part @@ -187,11 +307,18 @@ def it_provides_access_to_its_styles_part_to_help( assert styles_part is styles_part_ def and_it_creates_a_default_styles_part_if_not_present( - self, package_, part_related_by_, StylesPart_, styles_part_, relate_to_ + self, + package_: Mock, + part_related_by_: Mock, + StylesPart_: Mock, + styles_part_: Mock, + relate_to_: Mock, ): part_related_by_.side_effect = KeyError StylesPart_.default.return_value = styles_part_ - document_part = DocumentPart(None, None, None, package_) + document_part = DocumentPart( + PackURI("/word/document.xml"), CT.WML_DOCUMENT, element("w:document"), package_ + ) styles_part = document_part._styles_part @@ -199,135 +326,116 @@ def and_it_creates_a_default_styles_part_if_not_present( relate_to_.assert_called_once_with(document_part, styles_part_, RT.STYLES) assert styles_part is styles_part_ - # fixtures ------------------------------------------------------- + # -- fixtures -------------------------------------------------------------------------------- @pytest.fixture - def core_props_fixture(self, package_, core_properties_): - document_part = DocumentPart(None, None, None, package_) - package_.core_properties = core_properties_ - return document_part, core_properties_ + def comments_(self, request: FixtureRequest) -> Mock: + return instance_mock(request, Comments) @pytest.fixture - def inline_shapes_fixture(self, request, InlineShapes_): - document_elm = (a_document().with_nsdecls().with_child(a_body())).element - body_elm = document_elm[0] - document = DocumentPart(None, None, document_elm, None) - return document, InlineShapes_, body_elm + def CommentsPart_(self, request: FixtureRequest) -> Mock: + return class_mock(request, "docx.parts.document.CommentsPart") @pytest.fixture - def save_fixture(self, package_): - document_part = DocumentPart(None, None, None, package_) - file_ = "foobar.docx" - return document_part, file_ + def comments_part_(self, request: FixtureRequest) -> Mock: + return instance_mock(request, CommentsPart) @pytest.fixture - def settings_fixture(self, _settings_part_prop_, settings_part_, settings_): - document_part = DocumentPart(None, None, None, None) - _settings_part_prop_.return_value = settings_part_ - settings_part_.settings = settings_ - return document_part, settings_ - - @pytest.fixture - def styles_fixture(self, _styles_part_prop_, styles_part_, styles_): - document_part = DocumentPart(None, None, None, None) - _styles_part_prop_.return_value = styles_part_ - styles_part_.styles = styles_ - return document_part, styles_ - - # fixture components --------------------------------------------- + def _comments_part_prop_(self, request: FixtureRequest) -> Mock: + return property_mock(request, DocumentPart, "_comments_part") @pytest.fixture - def core_properties_(self, request): + def core_properties_(self, request: FixtureRequest): return instance_mock(request, CoreProperties) @pytest.fixture - def drop_rel_(self, request): + def drop_rel_(self, request: FixtureRequest): return method_mock(request, DocumentPart, "drop_rel", autospec=True) @pytest.fixture - def FooterPart_(self, request): + def FooterPart_(self, request: FixtureRequest): return class_mock(request, "docx.parts.document.FooterPart") @pytest.fixture - def footer_part_(self, request): + def footer_part_(self, request: FixtureRequest): return instance_mock(request, FooterPart) @pytest.fixture - def HeaderPart_(self, request): + def HeaderPart_(self, request: FixtureRequest): return class_mock(request, "docx.parts.document.HeaderPart") @pytest.fixture - def header_part_(self, request): + def header_part_(self, request: FixtureRequest): return instance_mock(request, HeaderPart) @pytest.fixture - def InlineShapes_(self, request): + def InlineShapes_(self, request: FixtureRequest): return class_mock(request, "docx.parts.document.InlineShapes") @pytest.fixture - def NumberingPart_(self, request): + def NumberingPart_(self, request: FixtureRequest): return class_mock(request, "docx.parts.document.NumberingPart") @pytest.fixture - def numbering_part_(self, request): + def numbering_part_(self, request: FixtureRequest): return instance_mock(request, NumberingPart) @pytest.fixture - def package_(self, request): + def package_(self, request: FixtureRequest): return instance_mock(request, Package) @pytest.fixture - def part_related_by_(self, request): + def part_related_by_(self, request: FixtureRequest): return method_mock(request, DocumentPart, "part_related_by") @pytest.fixture - def relate_to_(self, request): + def relate_to_(self, request: FixtureRequest): return method_mock(request, DocumentPart, "relate_to") @pytest.fixture - def related_parts_(self, request): + def related_parts_(self, request: FixtureRequest): return instance_mock(request, dict) @pytest.fixture - def related_parts_prop_(self, request): + def related_parts_prop_(self, request: FixtureRequest): return property_mock(request, DocumentPart, "related_parts") @pytest.fixture - def SettingsPart_(self, request): + def SettingsPart_(self, request: FixtureRequest): return class_mock(request, "docx.parts.document.SettingsPart") @pytest.fixture - def settings_(self, request): + def settings_(self, request: FixtureRequest): return instance_mock(request, Settings) @pytest.fixture - def settings_part_(self, request): + def settings_part_(self, request: FixtureRequest): return instance_mock(request, SettingsPart) @pytest.fixture - def _settings_part_prop_(self, request): + def _settings_part_prop_(self, request: FixtureRequest): return property_mock(request, DocumentPart, "_settings_part") @pytest.fixture - def style_(self, request): + def style_(self, request: FixtureRequest): return instance_mock(request, BaseStyle) @pytest.fixture - def styles_(self, request): + def styles_(self, request: FixtureRequest): return instance_mock(request, Styles) @pytest.fixture - def StylesPart_(self, request): + def StylesPart_(self, request: FixtureRequest): return class_mock(request, "docx.parts.document.StylesPart") @pytest.fixture - def styles_part_(self, request): + def styles_part_(self, request: FixtureRequest): return instance_mock(request, StylesPart) @pytest.fixture - def styles_prop_(self, request): + def styles_prop_(self, request: FixtureRequest): return property_mock(request, DocumentPart, "styles") @pytest.fixture - def _styles_part_prop_(self, request): + def _styles_part_prop_(self, request: FixtureRequest): return property_mock(request, DocumentPart, "_styles_part") diff --git a/tests/parts/test_hdrftr.py b/tests/parts/test_hdrftr.py index 815b207c..bb98acea 100644 --- a/tests/parts/test_hdrftr.py +++ b/tests/parts/test_hdrftr.py @@ -1,12 +1,9 @@ -# encoding: utf-8 - -"""Unit test suite for the docx.parts.hdrftr module""" - -from __future__ import absolute_import, division, print_function, unicode_literals +"""Unit test suite for the docx.parts.hdrftr module.""" import pytest -from docx.opc.constants import CONTENT_TYPE as CT, RELATIONSHIP_TYPE as RT +from docx.opc.constants import CONTENT_TYPE as CT +from docx.opc.constants import RELATIONSHIP_TYPE as RT from docx.opc.part import PartFactory from docx.package import Package from docx.parts.hdrftr import FooterPart, HeaderPart @@ -15,7 +12,7 @@ from ..unitutil.mock import function_mock, initializer_mock, instance_mock, method_mock -class DescribeFooterPart(object): +class DescribeFooterPart: def it_is_used_by_loader_to_construct_footer_part( self, package_, FooterPart_load_, footer_part_ ): @@ -30,9 +27,7 @@ def it_is_used_by_loader_to_construct_footer_part( FooterPart_load_.assert_called_once_with(partname, content_type, blob, package_) assert part is footer_part_ - def it_can_create_a_new_footer_part( - self, package_, _default_footer_xml_, parse_xml_, _init_ - ): + def it_can_create_a_new_footer_part(self, package_, _default_footer_xml_, parse_xml_, _init_): ftr = element("w:ftr") package_.next_partname.return_value = "/word/footer24.xml" _default_footer_xml_.return_value = "" @@ -83,7 +78,7 @@ def parse_xml_(self, request): return function_mock(request, "docx.parts.hdrftr.parse_xml") -class DescribeHeaderPart(object): +class DescribeHeaderPart: def it_is_used_by_loader_to_construct_header_part( self, package_, HeaderPart_load_, header_part_ ): @@ -98,9 +93,7 @@ def it_is_used_by_loader_to_construct_header_part( HeaderPart_load_.assert_called_once_with(partname, content_type, blob, package_) assert part is header_part_ - def it_can_create_a_new_header_part( - self, package_, _default_header_xml_, parse_xml_, _init_ - ): + def it_can_create_a_new_header_part(self, package_, _default_header_xml_, parse_xml_, _init_): hdr = element("w:hdr") package_.next_partname.return_value = "/word/header42.xml" _default_header_xml_.return_value = "" diff --git a/tests/parts/test_image.py b/tests/parts/test_image.py index c94fb167..395f5772 100644 --- a/tests/parts/test_image.py +++ b/tests/parts/test_image.py @@ -1,23 +1,20 @@ -# encoding: utf-8 - -"""Unit test suite for docx.parts.image module""" - -from __future__ import absolute_import, division, print_function, unicode_literals +"""Unit test suite for docx.parts.image module.""" import pytest from docx.image.image import Image -from docx.opc.constants import CONTENT_TYPE as CT, RELATIONSHIP_TYPE as RT +from docx.opc.constants import CONTENT_TYPE as CT +from docx.opc.constants import RELATIONSHIP_TYPE as RT from docx.opc.packuri import PackURI from docx.opc.part import PartFactory from docx.package import Package from docx.parts.image import ImagePart -from ..unitutil.file import testfile +from ..unitutil.file import test_file from ..unitutil.mock import ANY, initializer_mock, instance_mock, method_mock -class DescribeImagePart(object): +class DescribeImagePart: def it_is_used_by_PartFactory_to_construct_image_part( self, image_part_load_, partname_, blob_, package_, image_part_ ): @@ -27,17 +24,13 @@ def it_is_used_by_PartFactory_to_construct_image_part( part = PartFactory(partname_, content_type, reltype, blob_, package_) - image_part_load_.assert_called_once_with( - partname_, content_type, blob_, package_ - ) + image_part_load_.assert_called_once_with(partname_, content_type, blob_, package_) assert part is image_part_ def it_can_construct_from_an_Image_instance(self, image_, partname_, _init_): image_part = ImagePart.from_image(image_, partname_) - _init_.assert_called_once_with( - ANY, partname_, image_.content_type, image_.blob, image_ - ) + _init_.assert_called_once_with(ANY, partname_, image_.content_type, image_.blob, image_) assert isinstance(image_part, ImagePart) def it_knows_its_default_dimensions_in_EMU(self, dimensions_fixture): @@ -62,7 +55,7 @@ def blob_(self, request): @pytest.fixture(params=["loaded", "new"]) def dimensions_fixture(self, request): - image_file_path = testfile("monty-truth.png") + image_file_path = test_file("monty-truth.png") image = Image.from_file(image_file_path) expected_cx, expected_cy = 1905000, 2717800 diff --git a/tests/parts/test_numbering.py b/tests/parts/test_numbering.py index 44dedde7..1ed0f2a0 100644 --- a/tests/parts/test_numbering.py +++ b/tests/parts/test_numbering.py @@ -1,10 +1,4 @@ -# encoding: utf-8 - -""" -Test suite for the docx.parts.numbering module -""" - -from __future__ import absolute_import, print_function, unicode_literals +"""Test suite for the docx.parts.numbering module.""" import pytest @@ -15,7 +9,7 @@ from ..unitutil.mock import class_mock, instance_mock -class DescribeNumberingPart(object): +class DescribeNumberingPart: def it_provides_access_to_the_numbering_definitions(self, num_defs_fixture): ( numbering_part, @@ -30,9 +24,7 @@ def it_provides_access_to_the_numbering_definitions(self, num_defs_fixture): # fixtures ------------------------------------------------------- @pytest.fixture - def num_defs_fixture( - self, _NumberingDefinitions_, numbering_elm_, numbering_definitions_ - ): + def num_defs_fixture(self, _NumberingDefinitions_, numbering_elm_, numbering_definitions_): numbering_part = NumberingPart(None, None, numbering_elm_, None) return ( numbering_part, @@ -60,7 +52,7 @@ def numbering_elm_(self, request): return instance_mock(request, CT_Numbering) -class Describe_NumberingDefinitions(object): +class Describe_NumberingDefinitions: def it_knows_how_many_numbering_definitions_it_contains(self, len_fixture): numbering_definitions, numbering_definition_count = len_fixture assert len(numbering_definitions) == numbering_definition_count diff --git a/tests/parts/test_settings.py b/tests/parts/test_settings.py index 21ba2ec4..73b8a5e9 100644 --- a/tests/parts/test_settings.py +++ b/tests/parts/test_settings.py @@ -1,9 +1,5 @@ -# encoding: utf-8 - """Unit test suite for the docx.parts.settings module""" -from __future__ import absolute_import, division, print_function, unicode_literals - import pytest from docx.opc.constants import CONTENT_TYPE as CT @@ -17,10 +13,8 @@ from ..unitutil.mock import class_mock, instance_mock, method_mock -class DescribeSettingsPart(object): - def it_is_used_by_loader_to_construct_settings_part( - self, load_, package_, settings_part_ - ): +class DescribeSettingsPart: + def it_is_used_by_loader_to_construct_settings_part(self, load_, package_, settings_part_): partname, blob = "partname", "blob" content_type = CT.WML_SETTINGS load_.return_value = settings_part_ @@ -65,9 +59,7 @@ def package_(self, request): @pytest.fixture def Settings_(self, request, settings_): - return class_mock( - request, "docx.parts.settings.Settings", return_value=settings_ - ) + return class_mock(request, "docx.parts.settings.Settings", return_value=settings_) @pytest.fixture def settings_(self, request): diff --git a/tests/parts/test_story.py b/tests/parts/test_story.py index 67154758..9a1dc7fa 100644 --- a/tests/parts/test_story.py +++ b/tests/parts/test_story.py @@ -1,8 +1,4 @@ -# encoding: utf-8 - -"""Unit test suite for the docx.parts.story module""" - -from __future__ import absolute_import, division, print_function, unicode_literals +"""Unit test suite for the docx.parts.story module.""" import pytest @@ -12,7 +8,7 @@ from docx.package import Package from docx.parts.document import DocumentPart from docx.parts.image import ImagePart -from docx.parts.story import BaseStoryPart +from docx.parts.story import StoryPart from docx.styles.style import BaseStyle from ..unitutil.cxml import element @@ -20,12 +16,12 @@ from ..unitutil.mock import instance_mock, method_mock, property_mock -class DescribeBaseStoryPart(object): +class DescribeStoryPart: def it_can_get_or_add_an_image(self, package_, image_part_, image_, relate_to_): package_.get_or_add_image_part.return_value = image_part_ relate_to_.return_value = "rId42" image_part_.image = image_ - story_part = BaseStoryPart(None, None, None, package_) + story_part = StoryPart(None, None, None, package_) rId, image = story_part.get_or_add_image("image.png") @@ -34,14 +30,12 @@ def it_can_get_or_add_an_image(self, package_, image_part_, image_, relate_to_): assert rId == "rId42" assert image is image_ - def it_can_get_a_style_by_id_and_type( - self, _document_part_prop_, document_part_, style_ - ): + def it_can_get_a_style_by_id_and_type(self, _document_part_prop_, document_part_, style_): style_id = "BodyText" style_type = WD_STYLE_TYPE.PARAGRAPH _document_part_prop_.return_value = document_part_ document_part_.get_style.return_value = style_ - story_part = BaseStoryPart(None, None, None, None) + story_part = StoryPart(None, None, None, None) style = story_part.get_style(style_id, style_type) @@ -54,7 +48,7 @@ def it_can_get_a_style_id_by_style_or_name_and_type( style_type = WD_STYLE_TYPE.PARAGRAPH _document_part_prop_.return_value = document_part_ document_part_.get_style_id.return_value = "BodyText" - story_part = BaseStoryPart(None, None, None, None) + story_part = StoryPart(None, None, None, None) style_id = story_part.get_style_id(style_, style_type) @@ -67,7 +61,7 @@ def it_can_create_a_new_pic_inline(self, get_or_add_image_, image_, next_id_prop image_.filename = "bar.png" next_id_prop_.return_value = 24 expected_xml = snippet_text("inline") - story_part = BaseStoryPart(None, None, None, None) + story_part = StoryPart(None, None, None, None) inline = story_part.new_pic_inline("foo/bar.png", width=100, height=200) @@ -77,7 +71,7 @@ def it_can_create_a_new_pic_inline(self, get_or_add_image_, image_, next_id_prop def it_knows_the_next_available_xml_id(self, next_id_fixture): story_element, expected_value = next_id_fixture - story_part = BaseStoryPart(None, None, story_element, None) + story_part = StoryPart(None, None, story_element, None) next_id = story_part.next_id @@ -85,7 +79,7 @@ def it_knows_the_next_available_xml_id(self, next_id_fixture): def it_knows_the_main_document_part_to_help(self, package_, document_part_): package_.main_document_part = document_part_ - story_part = BaseStoryPart(None, None, None, package_) + story_part = StoryPart(None, None, None, package_) document_part = story_part._document_part @@ -119,11 +113,11 @@ def document_part_(self, request): @pytest.fixture def _document_part_prop_(self, request): - return property_mock(request, BaseStoryPart, "_document_part") + return property_mock(request, StoryPart, "_document_part") @pytest.fixture def get_or_add_image_(self, request): - return method_mock(request, BaseStoryPart, "get_or_add_image") + return method_mock(request, StoryPart, "get_or_add_image") @pytest.fixture def image_(self, request): @@ -135,7 +129,7 @@ def image_part_(self, request): @pytest.fixture def next_id_prop_(self, request): - return property_mock(request, BaseStoryPart, "next_id") + return property_mock(request, StoryPart, "next_id") @pytest.fixture def package_(self, request): @@ -143,7 +137,7 @@ def package_(self, request): @pytest.fixture def relate_to_(self, request): - return method_mock(request, BaseStoryPart, "relate_to") + return method_mock(request, StoryPart, "relate_to") @pytest.fixture def style_(self, request): diff --git a/tests/parts/test_styles.py b/tests/parts/test_styles.py index 0f2a7b11..d0f63cfb 100644 --- a/tests/parts/test_styles.py +++ b/tests/parts/test_styles.py @@ -1,10 +1,4 @@ -# encoding: utf-8 - -""" -Test suite for the docx.parts.styles module -""" - -from __future__ import absolute_import, print_function, unicode_literals +"""Test suite for the docx.parts.styles module.""" import pytest @@ -17,7 +11,7 @@ from ..unitutil.mock import class_mock, instance_mock -class DescribeStylesPart(object): +class DescribeStylesPart: def it_provides_access_to_its_styles(self, styles_fixture): styles_part, Styles_, styles_ = styles_fixture styles = styles_part.styles diff --git a/tests/styles/test_latent.py b/tests/styles/test_latent.py index ee4bead8..9479d6b4 100644 --- a/tests/styles/test_latent.py +++ b/tests/styles/test_latent.py @@ -1,19 +1,13 @@ -# encoding: utf-8 - -""" -Unit test suite for the docx.styles.latent module -""" - -from __future__ import absolute_import, division, print_function, unicode_literals +"""Unit test suite for the docx.styles.latent module.""" import pytest -from docx.styles.latent import _LatentStyle, LatentStyles +from docx.styles.latent import LatentStyles, _LatentStyle from ..unitutil.cxml import element, xml -class DescribeLatentStyle(object): +class DescribeLatentStyle: def it_can_delete_itself(self, delete_fixture): latent_style, latent_styles, expected_xml = delete_fixture latent_style.delete() @@ -135,7 +129,7 @@ def priority_set_fixture(self, request): return latent_style, new_value, expected_xml -class DescribeLatentStyles(object): +class DescribeLatentStyles: def it_can_add_a_latent_style(self, add_fixture): latent_styles, name, expected_xml = add_fixture @@ -151,7 +145,7 @@ def it_knows_how_many_latent_styles_it_contains(self, len_fixture): def it_can_iterate_over_its_latent_styles(self, iter_fixture): latent_styles, expected_count = iter_fixture - lst = [ls for ls in latent_styles] + lst = list(latent_styles) assert len(lst) == expected_count for latent_style in lst: assert isinstance(latent_style, _LatentStyle) diff --git a/tests/styles/test_style.py b/tests/styles/test_style.py index caa281db..6201f992 100644 --- a/tests/styles/test_style.py +++ b/tests/styles/test_style.py @@ -1,20 +1,14 @@ -# encoding: utf-8 - -""" -Test suite for the docx.styles.style module -""" - -from __future__ import absolute_import, division, print_function, unicode_literals +"""Test suite for the docx.styles.style module.""" import pytest from docx.enum.style import WD_STYLE_TYPE from docx.styles.style import ( BaseStyle, - _CharacterStyle, - _ParagraphStyle, - _NumberingStyle, + CharacterStyle, + ParagraphStyle, StyleFactory, + _NumberingStyle, _TableStyle, ) from docx.text.font import Font @@ -24,7 +18,7 @@ from ..unitutil.mock import call, class_mock, function_mock, instance_mock -class DescribeStyleFactory(object): +class DescribeStyleFactory: def it_constructs_the_right_type_of_style(self, factory_fixture): style_elm, StyleCls_, style_ = factory_fixture style = StyleFactory(style_elm) @@ -38,9 +32,9 @@ def factory_fixture( self, request, paragraph_style_, - _ParagraphStyle_, + ParagraphStyle_, character_style_, - _CharacterStyle_, + CharacterStyle_, table_style_, _TableStyle_, numbering_style_, @@ -48,8 +42,8 @@ def factory_fixture( ): type_attr_val = request.param StyleCls_, style_mock = { - "paragraph": (_ParagraphStyle_, paragraph_style_), - "character": (_CharacterStyle_, character_style_), + "paragraph": (ParagraphStyle_, paragraph_style_), + "character": (CharacterStyle_, character_style_), "table": (_TableStyle_, table_style_), "numbering": (_NumberingStyle_, numbering_style_), }[request.param] @@ -60,30 +54,28 @@ def factory_fixture( # fixture components ----------------------------------- @pytest.fixture - def _ParagraphStyle_(self, request, paragraph_style_): + def ParagraphStyle_(self, request, paragraph_style_): return class_mock( - request, "docx.styles.style._ParagraphStyle", return_value=paragraph_style_ + request, "docx.styles.style.ParagraphStyle", return_value=paragraph_style_ ) @pytest.fixture def paragraph_style_(self, request): - return instance_mock(request, _ParagraphStyle) + return instance_mock(request, ParagraphStyle) @pytest.fixture - def _CharacterStyle_(self, request, character_style_): + def CharacterStyle_(self, request, character_style_): return class_mock( - request, "docx.styles.style._CharacterStyle", return_value=character_style_ + request, "docx.styles.style.CharacterStyle", return_value=character_style_ ) @pytest.fixture def character_style_(self, request): - return instance_mock(request, _CharacterStyle) + return instance_mock(request, CharacterStyle) @pytest.fixture def _TableStyle_(self, request, table_style_): - return class_mock( - request, "docx.styles.style._TableStyle", return_value=table_style_ - ) + return class_mock(request, "docx.styles.style._TableStyle", return_value=table_style_) @pytest.fixture def table_style_(self, request): @@ -100,7 +92,7 @@ def numbering_style_(self, request): return instance_mock(request, _NumberingStyle) -class DescribeBaseStyle(object): +class DescribeBaseStyle: def it_knows_its_style_id(self, id_get_fixture): style, expected_value = id_get_fixture assert style.style_id == expected_value @@ -402,7 +394,7 @@ def unhide_set_fixture(self, request): return style, value, expected_xml -class Describe_CharacterStyle(object): +class DescribeCharacterStyle: def it_knows_which_style_it_is_based_on(self, base_get_fixture): style, StyleFactory_, StyleFactory_calls, base_style_ = base_get_fixture base_style = style.base_style @@ -433,7 +425,7 @@ def it_provides_access_to_its_font(self, font_fixture): def base_get_fixture(self, request, StyleFactory_): styles_cxml, style_idx, base_style_idx = request.param styles = element(styles_cxml) - style = _CharacterStyle(styles[style_idx]) + style = CharacterStyle(styles[style_idx]) if base_style_idx >= 0: base_style = styles[base_style_idx] StyleFactory_calls = [call(base_style)] @@ -452,7 +444,7 @@ def base_get_fixture(self, request, StyleFactory_): ) def base_set_fixture(self, request, style_): style_cxml, base_style_id, expected_style_cxml = request.param - style = _CharacterStyle(element(style_cxml)) + style = CharacterStyle(element(style_cxml)) style_.style_id = base_style_id base_style = style_ if base_style_id is not None else None expected_xml = xml(expected_style_cxml) @@ -460,7 +452,7 @@ def base_set_fixture(self, request, style_): @pytest.fixture def font_fixture(self, Font_, font_): - style = _CharacterStyle(element("w:style")) + style = CharacterStyle(element("w:style")) return style, Font_, font_ # fixture components --------------------------------------------- @@ -482,7 +474,7 @@ def StyleFactory_(self, request): return function_mock(request, "docx.styles.style.StyleFactory") -class Describe_ParagraphStyle(object): +class DescribeParagraphStyle: def it_knows_its_next_paragraph_style(self, next_get_fixture): style, expected_value = next_get_fixture assert style.next_paragraph_style == expected_value @@ -521,11 +513,8 @@ def next_get_fixture(self, request): style_names = ["H1", "H2", "Body", "Foo", "Char"] style_elm = styles[style_names.index(style_name)] next_style_elm = styles[style_names.index(next_style_name)] - style = _ParagraphStyle(style_elm) - if style_name == "H1": - next_style = _ParagraphStyle(next_style_elm) - else: - next_style = style + style = ParagraphStyle(style_elm) + next_style = ParagraphStyle(next_style_elm) if style_name == "H1" else style return style, next_style @pytest.fixture( @@ -538,23 +527,17 @@ def next_get_fixture(self, request): def next_set_fixture(self, request): style_name, next_style_name, style_cxml = request.param styles = element( - "w:styles/(" - "w:style{w:type=paragraph,w:styleId=H}," - "w:style{w:type=paragraph,w:styleId=B})" + "w:styles/(w:style{w:type=paragraph,w:styleId=H},w:style{w:type=paragraph,w:styleId=B})" ) style_elms = {"H": styles[0], "B": styles[1]} - style = _ParagraphStyle(style_elms[style_name]) - next_style = ( - None - if next_style_name is None - else _ParagraphStyle(style_elms[next_style_name]) - ) + style = ParagraphStyle(style_elms[style_name]) + next_style = ParagraphStyle(style_elms[next_style_name]) if next_style_name else None expected_xml = xml(style_cxml) return style, next_style, expected_xml @pytest.fixture def parfmt_fixture(self, ParagraphFormat_, paragraph_format_): - style = _ParagraphStyle(element("w:style")) + style = ParagraphStyle(element("w:style")) return style, ParagraphFormat_, paragraph_format_ # fixture components --------------------------------------------- diff --git a/tests/styles/test_styles.py b/tests/styles/test_styles.py index c01d2138..7493388d 100644 --- a/tests/styles/test_styles.py +++ b/tests/styles/test_styles.py @@ -1,8 +1,4 @@ -# encoding: utf-8 - -"""Unit test suite for the docx.styles.styles module""" - -from __future__ import absolute_import, division, print_function, unicode_literals +"""Unit test suite for the docx.styles.styles module.""" import pytest @@ -16,7 +12,7 @@ from ..unitutil.mock import call, class_mock, function_mock, instance_mock, method_mock -class DescribeStyles(object): +class DescribeStyles: def it_supports_the_in_operator_on_style_name(self, in_fixture): styles, name, expected_value = in_fixture assert (name in styles) is expected_value @@ -56,15 +52,13 @@ def it_can_add_a_new_style(self, add_fixture): style = styles.add_style(name, style_type, builtin) - styles._element.add_style_of_type.assert_called_once_with( - name_, style_type, builtin - ) + styles._element.add_style_of_type.assert_called_once_with(name_, style_type, builtin) StyleFactory_.assert_called_once_with(style_elm_) assert style is style_ def it_raises_when_style_name_already_used(self, add_raises_fixture): styles, name = add_raises_fixture - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="document already contains style 'Hea"): styles.add_style(name, None) def it_can_get_the_default_style_for_a_type(self, default_fixture): @@ -114,9 +108,7 @@ def and_it_can_get_a_style_id_from_a_style_name(self, _get_style_id_from_name_): style_id = styles.get_style_id("Style Name", style_type) - _get_style_id_from_name_.assert_called_once_with( - styles, "Style Name", style_type - ) + _get_style_id_from_name_.assert_called_once_with(styles, "Style Name", style_type) assert style_id == "StyleId" def but_it_returns_None_for_a_style_or_name_of_None(self): @@ -136,9 +128,7 @@ def it_gets_a_style_by_id_to_help(self, _get_by_id_fixture): assert StyleFactory_.call_args_list == StyleFactory_calls assert style is style_ - def it_gets_a_style_id_from_a_name_to_help( - self, _getitem_, _get_style_id_from_style_, style_ - ): + def it_gets_a_style_id_from_a_name_to_help(self, _getitem_, _get_style_id_from_style_, style_): style_name, style_type, style_id_ = "Foo Bar", 1, "FooBar" _getitem_.return_value = style_ _get_style_id_from_style_.return_value = style_id_ @@ -160,7 +150,7 @@ def it_gets_a_style_id_from_a_style_to_help(self, id_style_fixture): def it_raises_on_style_type_mismatch(self, id_style_raises_fixture): styles, style_, style_type = id_style_raises_fixture - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="assigned style is type 1, need type 2"): styles._get_style_id_from_style(style_, style_type) def it_provides_access_to_the_latent_styles(self, latent_styles_fixture): @@ -177,9 +167,7 @@ def it_provides_access_to_the_latent_styles(self, latent_styles_fixture): ("Heading 1", "heading 1", WD_STYLE_TYPE.PARAGRAPH, True), ] ) - def add_fixture( - self, request, styles_elm_, _getitem_, style_elm_, StyleFactory_, style_ - ): + def add_fixture(self, request, styles_elm_, _getitem_, style_elm_, StyleFactory_, style_): name, name_, style_type, builtin = request.param styles = Styles(styles_elm_) _getitem_.return_value = None @@ -211,8 +199,7 @@ def add_raises_fixture(self, _getitem_): WD_STYLE_TYPE.PARAGRAPH, ), ( - "w:styles/(w:style{w:type=table,w:default=1},w:style{w:type=table,w" - ":default=1})", + "w:styles/(w:style{w:type=table,w:default=1},w:style{w:type=table,w:default=1})", True, WD_STYLE_TYPE.TABLE, ), @@ -391,9 +378,7 @@ def _get_style_id_from_style_(self, request): @pytest.fixture def LatentStyles_(self, request, latent_styles_): - return class_mock( - request, "docx.styles.styles.LatentStyles", return_value=latent_styles_ - ) + return class_mock(request, "docx.styles.styles.LatentStyles", return_value=latent_styles_) @pytest.fixture def latent_styles_(self, request): diff --git a/tests/test_api.py b/tests/test_api.py index 23251cf3..6b5d3ae0 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1,74 +1,56 @@ -# encoding: utf-8 - -""" -Test suite for the docx.api module -""" - -from __future__ import absolute_import, division, print_function, unicode_literals +"""Test suite for the docx.api module.""" import pytest -import docx - -from docx.api import Document +from docx.api import Document as DocumentFactoryFn +from docx.document import Document as DocumentCls from docx.opc.constants import CONTENT_TYPE as CT -from .unitutil.mock import function_mock, instance_mock, class_mock +from .unitutil.mock import FixtureRequest, Mock, class_mock, function_mock, instance_mock -class DescribeDocument(object): - def it_opens_a_docx_file(self, open_fixture): - docx, Package_, document_ = open_fixture - document = Document(docx) - Package_.open.assert_called_once_with(docx) - assert document is document_ +class DescribeDocument: + """Unit-test suite for `docx.api.Document` factory function.""" - def it_opens_the_default_docx_if_none_specified(self, default_fixture): - docx, Package_, document_ = default_fixture - document = Document() - Package_.open.assert_called_once_with(docx) - assert document is document_ - - def it_raises_on_not_a_Word_file(self, raise_fixture): - not_a_docx = raise_fixture - with pytest.raises(ValueError): - Document(not_a_docx) - - # fixtures ------------------------------------------------------- - - @pytest.fixture - def default_fixture(self, _default_docx_path_, Package_, document_): - docx = "barfoo.docx" - _default_docx_path_.return_value = docx + def it_opens_a_docx_file(self, Package_: Mock, document_: Mock): document_part = Package_.open.return_value.main_document_part document_part.document = document_ document_part.content_type = CT.WML_DOCUMENT_MAIN - return docx, Package_, document_ - @pytest.fixture - def open_fixture(self, Package_, document_): - docx = "foobar.docx" + document = DocumentFactoryFn("foobar.docx") + + Package_.open.assert_called_once_with("foobar.docx") + assert document is document_ + + def it_opens_the_default_docx_if_none_specified( + self, _default_docx_path_: Mock, Package_: Mock, document_: Mock + ): + _default_docx_path_.return_value = "default-document.docx" document_part = Package_.open.return_value.main_document_part document_part.document = document_ document_part.content_type = CT.WML_DOCUMENT_MAIN - return docx, Package_, document_ - @pytest.fixture - def raise_fixture(self, Package_): - not_a_docx = "foobar.xlsx" + document = DocumentFactoryFn() + + Package_.open.assert_called_once_with("default-document.docx") + assert document is document_ + + def it_raises_on_not_a_Word_file(self, Package_: Mock): Package_.open.return_value.main_document_part.content_type = "BOGUS" - return not_a_docx - # fixture components --------------------------------------------- + with pytest.raises(ValueError, match="file 'foobar.xlsx' is not a Word file,"): + DocumentFactoryFn("foobar.xlsx") + + # -- fixtures -------------------------------------------------------------------------------- @pytest.fixture - def _default_docx_path_(self, request): + def _default_docx_path_(self, request: FixtureRequest): return function_mock(request, "docx.api._default_docx_path") @pytest.fixture - def document_(self, request): - return instance_mock(request, docx.document.Document) + def document_(self, request: FixtureRequest): + return instance_mock(request, DocumentCls) @pytest.fixture - def Package_(self, request): + def Package_(self, request: FixtureRequest): return class_mock(request, "docx.api.Package") diff --git a/tests/test_blkcntnr.py b/tests/test_blkcntnr.py index 3fe2d0ff..ab463663 100644 --- a/tests/test_blkcntnr.py +++ b/tests/test_blkcntnr.py @@ -1,136 +1,151 @@ -# encoding: utf-8 +# pyright: reportPrivateUsage=false -"""Test suite for the docx.blkcntnr (block item container) module""" +"""Test suite for the docx.blkcntnr (block item container) module.""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import annotations + +from typing import cast import pytest +import docx from docx.blkcntnr import BlockItemContainer +from docx.document import Document +from docx.oxml.document import CT_Body from docx.shared import Inches from docx.table import Table from docx.text.paragraph import Paragraph from .unitutil.cxml import element, xml -from .unitutil.file import snippet_seq -from .unitutil.mock import call, instance_mock, method_mock +from .unitutil.file import snippet_seq, test_file +from .unitutil.mock import FixtureRequest, Mock, call, instance_mock, method_mock + +class DescribeBlockItemContainer: + """Unit-test suite for `docx.blkcntnr.BlockItemContainer`.""" -class DescribeBlockItemContainer(object): - def it_can_add_a_paragraph(self, add_paragraph_fixture, _add_paragraph_): - text, style, paragraph_, add_run_calls = add_paragraph_fixture + @pytest.mark.parametrize( + ("text", "style"), [("", None), ("Foo", None), ("", "Bar"), ("Foo", "Bar")] + ) + def it_can_add_a_paragraph( + self, + text: str, + style: str | None, + blkcntnr: BlockItemContainer, + _add_paragraph_: Mock, + paragraph_: Mock, + ): + paragraph_.style = None _add_paragraph_.return_value = paragraph_ - blkcntnr = BlockItemContainer(None, None) paragraph = blkcntnr.add_paragraph(text, style) _add_paragraph_.assert_called_once_with(blkcntnr) - assert paragraph.add_run.call_args_list == add_run_calls + assert paragraph_.add_run.call_args_list == ([call(text)] if text else []) assert paragraph.style == style assert paragraph is paragraph_ - def it_can_add_a_table(self, add_table_fixture): - blkcntnr, rows, cols, width, expected_xml = add_table_fixture + def it_can_add_a_table(self, blkcntnr: BlockItemContainer): + rows, cols, width = 2, 2, Inches(2) + table = blkcntnr.add_table(rows, cols, width) + assert isinstance(table, Table) - assert table._element.xml == expected_xml + assert table._element.xml == snippet_seq("new-tbl")[0] assert table._parent is blkcntnr - def it_provides_access_to_the_paragraphs_it_contains(self, paragraphs_fixture): - # test len(), iterable, and indexed access - blkcntnr, expected_count = paragraphs_fixture - paragraphs = blkcntnr.paragraphs - assert len(paragraphs) == expected_count - count = 0 - for idx, paragraph in enumerate(paragraphs): - assert isinstance(paragraph, Paragraph) - assert paragraphs[idx] is paragraph - count += 1 - assert count == expected_count - - def it_provides_access_to_the_tables_it_contains(self, tables_fixture): - # test len(), iterable, and indexed access - blkcntnr, expected_count = tables_fixture - tables = blkcntnr.tables - assert len(tables) == expected_count - count = 0 - for idx, table in enumerate(tables): - assert isinstance(table, Table) - assert tables[idx] is table - count += 1 - assert count == expected_count - - def it_adds_a_paragraph_to_help(self, _add_paragraph_fixture): - blkcntnr, expected_xml = _add_paragraph_fixture - new_paragraph = blkcntnr._add_paragraph() - assert isinstance(new_paragraph, Paragraph) - assert new_paragraph._parent == blkcntnr - assert blkcntnr._element.xml == expected_xml - - # fixtures ------------------------------------------------------- - - @pytest.fixture( - params=[ - ("", None), - ("Foo", None), - ("", "Bar"), - ("Foo", "Bar"), - ] - ) - def add_paragraph_fixture(self, request, paragraph_): - text, style = request.param - paragraph_.style = None - add_run_calls = [call(text)] if text else [] - return text, style, paragraph_, add_run_calls - - @pytest.fixture - def _add_paragraph_fixture(self, request): - blkcntnr_cxml, after_cxml = "w:body", "w:body/w:p" - blkcntnr = BlockItemContainer(element(blkcntnr_cxml), None) - expected_xml = xml(after_cxml) - return blkcntnr, expected_xml - - @pytest.fixture - def add_table_fixture(self): - blkcntnr = BlockItemContainer(element("w:body"), None) - rows, cols, width = 2, 2, Inches(2) - expected_xml = snippet_seq("new-tbl")[0] - return blkcntnr, rows, cols, width, expected_xml - - @pytest.fixture( - params=[ + def it_can_iterate_its_inner_content(self): + document = docx.Document(test_file("blk-inner-content.docx")) + + inner_content = document.iter_inner_content() + + para = next(inner_content) + assert isinstance(para, Paragraph) + assert para.text == "P1" + # -- + t = next(inner_content) + assert isinstance(t, Table) + assert t.rows[0].cells[0].text == "T2" + # -- + para = next(inner_content) + assert isinstance(para, Paragraph) + assert para.text == "P3" + # -- + with pytest.raises(StopIteration): + next(inner_content) + + @pytest.mark.parametrize( + ("blkcntnr_cxml", "expected_count"), + [ ("w:body", 0), ("w:body/w:p", 1), ("w:body/(w:p,w:p)", 2), ("w:body/(w:p,w:tbl)", 1), ("w:body/(w:p,w:tbl,w:p)", 2), - ] + ], ) - def paragraphs_fixture(self, request): - blkcntnr_cxml, expected_count = request.param - blkcntnr = BlockItemContainer(element(blkcntnr_cxml), None) - return blkcntnr, expected_count + def it_provides_access_to_the_paragraphs_it_contains( + self, blkcntnr_cxml: str, expected_count: int, document_: Mock + ): + blkcntnr = BlockItemContainer(cast(CT_Body, element(blkcntnr_cxml)), document_) + + paragraphs = blkcntnr.paragraphs - @pytest.fixture( - params=[ + # -- supports len() -- + assert len(paragraphs) == expected_count + # -- is iterable -- + assert all(isinstance(p, Paragraph) for p in paragraphs) + # -- is indexable -- + assert all(p is paragraphs[idx] for idx, p in enumerate(paragraphs)) + + @pytest.mark.parametrize( + ("blkcntnr_cxml", "expected_count"), + [ ("w:body", 0), ("w:body/w:tbl", 1), ("w:body/(w:tbl,w:tbl)", 2), ("w:body/(w:p,w:tbl)", 1), ("w:body/(w:tbl,w:tbl,w:p)", 2), - ] + ], ) - def tables_fixture(self, request): - blkcntnr_cxml, expected_count = request.param - blkcntnr = BlockItemContainer(element(blkcntnr_cxml), None) - return blkcntnr, expected_count + def it_provides_access_to_the_tables_it_contains( + self, blkcntnr_cxml: str, expected_count: int, document_: Mock + ): + blkcntnr = BlockItemContainer(cast(CT_Body, element(blkcntnr_cxml)), document_) + + tables = blkcntnr.tables + + # -- supports len() -- + assert len(tables) == expected_count + # -- is iterable -- + assert all(isinstance(t, Table) for t in tables) + # -- is indexable -- + assert all(t is tables[idx] for idx, t in enumerate(tables)) - # fixture components --------------------------------------------- + def it_adds_a_paragraph_to_help(self, document_: Mock): + blkcntnr = BlockItemContainer(cast(CT_Body, element("w:body")), document_) + + new_paragraph = blkcntnr._add_paragraph() + + assert isinstance(new_paragraph, Paragraph) + assert new_paragraph._parent == blkcntnr + assert blkcntnr._element.xml == xml("w:body/w:p") + + # -- fixtures -------------------------------------------------------------------------------- @pytest.fixture - def _add_paragraph_(self, request): + def _add_paragraph_(self, request: FixtureRequest): return method_mock(request, BlockItemContainer, "_add_paragraph") @pytest.fixture - def paragraph_(self, request): + def blkcntnr(self, document_: Mock): + blkcntnr_elm = cast(CT_Body, element("w:body")) + return BlockItemContainer(blkcntnr_elm, document_) + + @pytest.fixture + def document_(self, request: FixtureRequest): + return instance_mock(request, Document) + + @pytest.fixture + def paragraph_(self, request: FixtureRequest): return instance_mock(request, Paragraph) diff --git a/tests/test_comments.py b/tests/test_comments.py new file mode 100644 index 00000000..0f292ec8 --- /dev/null +++ b/tests/test_comments.py @@ -0,0 +1,275 @@ +# pyright: reportPrivateUsage=false + +"""Unit test suite for the `docx.comments` module.""" + +from __future__ import annotations + +import datetime as dt +from typing import cast + +import pytest + +from docx.comments import Comment, Comments +from docx.opc.constants import CONTENT_TYPE as CT +from docx.opc.packuri import PackURI +from docx.oxml.comments import CT_Comment, CT_Comments +from docx.oxml.ns import qn +from docx.package import Package +from docx.parts.comments import CommentsPart + +from .unitutil.cxml import element +from .unitutil.mock import FixtureRequest, Mock, instance_mock + + +class DescribeComments: + """Unit-test suite for `docx.comments.Comments` objects.""" + + @pytest.mark.parametrize( + ("cxml", "count"), + [ + ("w:comments", 0), + ("w:comments/w:comment", 1), + ("w:comments/(w:comment,w:comment,w:comment)", 3), + ], + ) + def it_knows_how_many_comments_it_contains(self, cxml: str, count: int, package_: Mock): + comments_elm = cast(CT_Comments, element(cxml)) + comments = Comments( + comments_elm, + CommentsPart( + PackURI("/word/comments.xml"), + CT.WML_COMMENTS, + comments_elm, + package_, + ), + ) + + assert len(comments) == count + + def it_is_iterable_over_the_comments_it_contains(self, package_: Mock): + comments_elm = cast(CT_Comments, element("w:comments/(w:comment,w:comment)")) + comments = Comments( + comments_elm, + CommentsPart( + PackURI("/word/comments.xml"), + CT.WML_COMMENTS, + comments_elm, + package_, + ), + ) + + comment_iter = iter(comments) + + comment1 = next(comment_iter) + assert type(comment1) is Comment, "expected a `Comment` object" + comment2 = next(comment_iter) + assert type(comment2) is Comment, "expected a `Comment` object" + with pytest.raises(StopIteration): + next(comment_iter) + + def it_can_get_a_comment_by_id(self, package_: Mock): + comments_elm = cast( + CT_Comments, + element("w:comments/(w:comment{w:id=1},w:comment{w:id=2},w:comment{w:id=3})"), + ) + comments = Comments( + comments_elm, + CommentsPart( + PackURI("/word/comments.xml"), + CT.WML_COMMENTS, + comments_elm, + package_, + ), + ) + + comment = comments.get(2) + + assert type(comment) is Comment, "expected a `Comment` object" + assert comment._comment_elm is comments_elm.comment_lst[1] + + def but_it_returns_None_when_no_comment_with_that_id_exists(self, package_: Mock): + comments_elm = cast( + CT_Comments, + element("w:comments/(w:comment{w:id=1},w:comment{w:id=2},w:comment{w:id=3})"), + ) + comments = Comments( + comments_elm, + CommentsPart( + PackURI("/word/comments.xml"), + CT.WML_COMMENTS, + comments_elm, + package_, + ), + ) + + comment = comments.get(4) + + assert comment is None, "expected None when no comment with that id exists" + + def it_can_add_a_new_comment(self, package_: Mock): + comments_elm = cast(CT_Comments, element("w:comments")) + comments_part = CommentsPart( + PackURI("/word/comments.xml"), + CT.WML_COMMENTS, + comments_elm, + package_, + ) + now_before = dt.datetime.now(dt.timezone.utc).replace(microsecond=0) + comments = Comments(comments_elm, comments_part) + + comment = comments.add_comment() + + now_after = dt.datetime.now(dt.timezone.utc).replace(microsecond=0) + # -- a comment is unconditionally added, and returned for any further adjustment -- + assert isinstance(comment, Comment) + # -- it is "linked" to the comments part so it can add images and hyperlinks, etc. -- + assert comment.part is comments_part + # -- comment numbering starts at 0, and is incremented for each new comment -- + assert comment.comment_id == 0 + # -- author is a required attribut, but is the empty string by default -- + assert comment.author == "" + # -- initials is an optional attribute, but defaults to the empty string, same as Word -- + assert comment.initials == "" + # -- timestamp is also optional, but defaults to now-UTC -- + assert comment.timestamp is not None + assert now_before <= comment.timestamp <= now_after + # -- by default, a new comment contains a single empty paragraph -- + assert [p.text for p in comment.paragraphs] == [""] + # -- that paragraph has the "CommentText" style, same as Word applies -- + comment_elm = comment._comment_elm + assert len(comment_elm.p_lst) == 1 + p = comment_elm.p_lst[0] + assert p.style == "CommentText" + # -- and that paragraph contains a single run with the necessary annotation reference -- + assert len(p.r_lst) == 1 + r = comment_elm.p_lst[0].r_lst[0] + assert r.style == "CommentReference" + assert r[-1].tag == qn("w:annotationRef") + + def and_it_can_add_text_to_the_comment_when_adding_it(self, comments: Comments, package_: Mock): + comment = comments.add_comment(text="para 1\n\npara 2") + + assert len(comment.paragraphs) == 3 + assert [p.text for p in comment.paragraphs] == ["para 1", "", "para 2"] + assert all(p._p.style == "CommentText" for p in comment.paragraphs) + + def and_it_sets_the_author_and_their_initials_when_adding_a_comment_when_provided( + self, comments: Comments, package_: Mock + ): + comment = comments.add_comment(author="Steve Canny", initials="SJC") + + assert comment.author == "Steve Canny" + assert comment.initials == "SJC" + + # -- fixtures -------------------------------------------------------------------------------- + + @pytest.fixture + def comments(self, package_: Mock) -> Comments: + comments_elm = cast(CT_Comments, element("w:comments")) + comments_part = CommentsPart( + PackURI("/word/comments.xml"), + CT.WML_COMMENTS, + comments_elm, + package_, + ) + return Comments(comments_elm, comments_part) + + @pytest.fixture + def package_(self, request: FixtureRequest): + return instance_mock(request, Package) + + +class DescribeComment: + """Unit-test suite for `docx.comments.Comment`.""" + + def it_knows_its_comment_id(self, comments_part_: Mock): + comment_elm = cast(CT_Comment, element("w:comment{w:id=42}")) + comment = Comment(comment_elm, comments_part_) + + assert comment.comment_id == 42 + + def it_knows_its_author(self, comments_part_: Mock): + comment_elm = cast(CT_Comment, element("w:comment{w:id=42,w:author=Steve Canny}")) + comment = Comment(comment_elm, comments_part_) + + assert comment.author == "Steve Canny" + + def it_knows_the_initials_of_its_author(self, comments_part_: Mock): + comment_elm = cast(CT_Comment, element("w:comment{w:id=42,w:initials=SJC}")) + comment = Comment(comment_elm, comments_part_) + + assert comment.initials == "SJC" + + def it_knows_the_date_and_time_it_was_authored(self, comments_part_: Mock): + comment_elm = cast( + CT_Comment, + element("w:comment{w:id=42,w:date=2023-10-01T12:34:56Z}"), + ) + comment = Comment(comment_elm, comments_part_) + + assert comment.timestamp == dt.datetime(2023, 10, 1, 12, 34, 56, tzinfo=dt.timezone.utc) + + @pytest.mark.parametrize( + ("cxml", "expected_value"), + [ + ("w:comment{w:id=42}", ""), + ('w:comment{w:id=42}/w:p/w:r/w:t"Comment text."', "Comment text."), + ( + 'w:comment{w:id=42}/(w:p/w:r/w:t"First para",w:p/w:r/w:t"Second para")', + "First para\nSecond para", + ), + ( + 'w:comment{w:id=42}/(w:p/w:r/w:t"First para",w:p,w:p/w:r/w:t"Second para")', + "First para\n\nSecond para", + ), + ], + ) + def it_can_summarize_its_content_as_text( + self, cxml: str, expected_value: str, comments_part_: Mock + ): + assert Comment(cast(CT_Comment, element(cxml)), comments_part_).text == expected_value + + def it_provides_access_to_the_paragraphs_it_contains(self, comments_part_: Mock): + comment_elm = cast( + CT_Comment, + element('w:comment{w:id=42}/(w:p/w:r/w:t"First para",w:p/w:r/w:t"Second para")'), + ) + comment = Comment(comment_elm, comments_part_) + + paragraphs = comment.paragraphs + + assert len(paragraphs) == 2 + assert [para.text for para in paragraphs] == ["First para", "Second para"] + + def it_can_update_the_comment_author(self, comments_part_: Mock): + comment_elm = cast(CT_Comment, element("w:comment{w:id=42,w:author=Old Author}")) + comment = Comment(comment_elm, comments_part_) + + comment.author = "New Author" + + assert comment.author == "New Author" + + @pytest.mark.parametrize( + "initials", + [ + # -- valid initials -- + "XYZ", + # -- empty string is valid + "", + # -- None is valid, removes existing initials + None, + ], + ) + def it_can_update_the_comment_initials(self, initials: str | None, comments_part_: Mock): + comment_elm = cast(CT_Comment, element("w:comment{w:id=42,w:initials=ABC}")) + comment = Comment(comment_elm, comments_part_) + + comment.initials = initials + + assert comment.initials == initials + + # -- fixtures -------------------------------------------------------------------------------- + + @pytest.fixture + def comments_part_(self, request: FixtureRequest): + return instance_mock(request, CommentsPart) diff --git a/tests/test_document.py b/tests/test_document.py index 3e61d943..2a399b12 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -1,10 +1,20 @@ -"""Unit test suite for the docx.document module""" +# pyright: reportPrivateUsage=false +# pyright: reportUnknownMemberType=false + +"""Unit test suite for the docx.document module.""" + +from __future__ import annotations + +from typing import cast + import pytest +from docx.comments import Comment, Comments from docx.document import Document, _Body from docx.enum.section import WD_SECTION from docx.enum.text import WD_BREAK from docx.opc.coreprops import CoreProperties +from docx.oxml.document import CT_Body, CT_Document from docx.oxml.shape import CT_Anchor from docx.parts.document import DocumentPart from docx.section import Section, Sections @@ -17,32 +27,63 @@ from docx.text.run import Run from .unitutil.cxml import element, xml -from .unitutil.mock import (class_mock, instance_mock, method_mock, - property_mock) +from .unitutil.mock import ( + FixtureRequest, + Mock, + class_mock, + instance_mock, + method_mock, + property_mock, +) + + +class DescribeDocument: + """Unit-test suite for `docx.document.Document`.""" + + def it_can_add_a_comment( + self, + document_part_: Mock, + comments_prop_: Mock, + comments_: Mock, + comment_: Mock, + run_mark_comment_range_: Mock, + ): + comment_.comment_id = 42 + comments_.add_comment.return_value = comment_ + comments_prop_.return_value = comments_ + document = Document(cast(CT_Document, element("w:document/w:body/w:p/w:r")), document_part_) + run = document.paragraphs[0].runs[0] + comment = document.add_comment(run, "Comment text.") -class DescribeDocument(object): - def it_can_add_a_heading(self, add_heading_fixture, add_paragraph_, paragraph_): - level, style = add_heading_fixture + comments_.add_comment.assert_called_once_with("Comment text.", "", "") + run_mark_comment_range_.assert_called_once_with(run, run, 42) + assert comment is comment_ + + @pytest.mark.parametrize( + ("level", "style"), [(0, "Title"), (1, "Heading 1"), (2, "Heading 2"), (9, "Heading 9")] + ) + def it_can_add_a_heading( + self, level: int, style: str, document: Document, add_paragraph_: Mock, paragraph_: Mock + ): add_paragraph_.return_value = paragraph_ - document = Document(None, None) paragraph = document.add_heading("Spam vs. Bacon", level) add_paragraph_.assert_called_once_with(document, "Spam vs. Bacon", style) assert paragraph is paragraph_ - def it_raises_on_heading_level_out_of_range(self): - document = Document(None, None) - with pytest.raises(ValueError): + def it_raises_on_heading_level_out_of_range(self, document: Document): + with pytest.raises(ValueError, match="level must be in range 0-9, got -1"): document.add_heading(level=-1) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="level must be in range 0-9, got 10"): document.add_heading(level=10) - def it_can_add_a_page_break(self, add_paragraph_, paragraph_, run_): + def it_can_add_a_page_break( + self, document: Document, add_paragraph_: Mock, paragraph_: Mock, run_: Mock + ): add_paragraph_.return_value = paragraph_ paragraph_.add_run.return_value = run_ - document = Document(None, None) paragraph = document.add_page_break() @@ -51,75 +92,159 @@ def it_can_add_a_page_break(self, add_paragraph_, paragraph_, run_): run_.add_break.assert_called_once_with(WD_BREAK.PAGE) assert paragraph is paragraph_ - def it_can_add_a_paragraph(self, add_paragraph_fixture): - document, text, style, paragraph_ = add_paragraph_fixture + @pytest.mark.parametrize( + ("text", "style"), [("", None), ("", "Heading 1"), ("foo\rbar", "Body Text")] + ) + def it_can_add_a_paragraph( + self, + text: str, + style: str | None, + document: Document, + body_: Mock, + body_prop_: Mock, + paragraph_: Mock, + ): + body_prop_.return_value = body_ + body_.add_paragraph.return_value = paragraph_ + paragraph = document.add_paragraph(text, style) - document._body.add_paragraph.assert_called_once_with(text, style) + + body_.add_paragraph.assert_called_once_with(text, style) assert paragraph is paragraph_ - def it_can_add_a_picture(self, add_picture_fixture): - document, path, width, height, run_, picture_ = add_picture_fixture + def it_can_add_a_picture( + self, document: Document, add_paragraph_: Mock, run_: Mock, picture_: Mock + ): + path, width, height = "foobar.png", 100, 200 + add_paragraph_.return_value.add_run.return_value = run_ + run_.add_picture.return_value = picture_ + picture = document.add_picture(path, width, height) + run_.add_picture.assert_called_once_with(path, width, height) assert picture is picture_ - def it_can_add_a_float_picture(self, add_float_picture_fixture): - ( - document, - path, - width, - height, - pos_x, - pos_y, - run_, - float_picture_, - ) = add_float_picture_fixture + def it_can_add_a_float_picture( + self, + document: Document, + add_paragraph_: Mock, + run_: Mock, + float_picture_: Mock, + ): + path, width, height, pos_x, pos_y = "foobar.png", 100, 200, 100000, 200000 + add_paragraph_.return_value.add_run.return_value = run_ + run_.add_float_picture.return_value = float_picture_ + anchor = document.add_float_picture(path, width, height, pos_x, pos_y) + run_.add_float_picture.assert_called_once_with(path, width, height, pos_x, pos_y) - assert anchor is float_picture_ + assert anchor is float_picture_ + @pytest.mark.parametrize( + ("sentinel_cxml", "start_type", "new_sentinel_cxml"), + [ + ("w:sectPr", WD_SECTION.EVEN_PAGE, "w:sectPr/w:type{w:val=evenPage}"), + ( + "w:sectPr/w:type{w:val=evenPage}", + WD_SECTION.ODD_PAGE, + "w:sectPr/w:type{w:val=oddPage}", + ), + ("w:sectPr/w:type{w:val=oddPage}", WD_SECTION.NEW_PAGE, "w:sectPr"), + ], + ) def it_can_add_a_section( - self, add_section_fixture, Section_, section_, document_part_ + self, + sentinel_cxml: str, + start_type: WD_SECTION, + new_sentinel_cxml: str, + Section_: Mock, + section_: Mock, + document_part_: Mock, ): - document_elm, start_type, expected_xml = add_section_fixture Section_.return_value = section_ - document = Document(document_elm, document_part_) + document = Document( + cast(CT_Document, element("w:document/w:body/(w:p,%s)" % sentinel_cxml)), + document_part_, + ) section = document.add_section(start_type) - assert document.element.xml == expected_xml + assert document.element.xml == xml( + "w:document/w:body/(w:p,w:p/w:pPr/%s,%s)" % (sentinel_cxml, new_sentinel_cxml) + ) sectPr = document.element.xpath("w:body/w:sectPr")[0] Section_.assert_called_once_with(sectPr, document_part_) assert section is section_ - def it_can_add_a_table(self, add_table_fixture): - document, rows, cols, style, width, table_ = add_table_fixture + def it_can_add_a_table( + self, + document: Document, + _block_width_prop_: Mock, + body_prop_: Mock, + body_: Mock, + table_: Mock, + ): + rows, cols, style = 4, 2, "Light Shading Accent 1" + body_prop_.return_value = body_ + body_.add_table.return_value = table_ + _block_width_prop_.return_value = width = 42 + table = document.add_table(rows, cols, style) - document._body.add_table.assert_called_once_with(rows, cols, width) + + body_.add_table.assert_called_once_with(rows, cols, width) assert table == table_ assert table.style == style - def it_can_save_the_document_to_a_file(self, save_fixture): - document, file_ = save_fixture - document.save(file_) - document._part.save.assert_called_once_with(file_) + def it_can_save_the_document_to_a_file(self, document_part_: Mock): + document = Document(cast(CT_Document, element("w:document")), document_part_) + + document.save("foobar.docx") + + document_part_.save.assert_called_once_with("foobar.docx") + + def it_provides_access_to_the_comments(self, document_part_: Mock, comments_: Mock): + document_part_.comments = comments_ + document = Document(cast(CT_Document, element("w:document")), document_part_) + + assert document.comments is comments_ + + def it_provides_access_to_its_core_properties( + self, document_part_: Mock, core_properties_: Mock + ): + document_part_.core_properties = core_properties_ + document = Document(cast(CT_Document, element("w:document")), document_part_) - def it_provides_access_to_its_core_properties(self, core_props_fixture): - document, core_properties_ = core_props_fixture core_properties = document.core_properties + assert core_properties is core_properties_ - def it_provides_access_to_its_inline_shapes(self, inline_shapes_fixture): - document, inline_shapes_ = inline_shapes_fixture + def it_provides_access_to_its_inline_shapes(self, document_part_: Mock, inline_shapes_: Mock): + document_part_.inline_shapes = inline_shapes_ + document = Document(cast(CT_Document, element("w:document")), document_part_) + assert document.inline_shapes is inline_shapes_ - def it_provides_access_to_its_paragraphs(self, paragraphs_fixture): - document, paragraphs_ = paragraphs_fixture + def it_can_iterate_the_inner_content_of_the_document( + self, body_prop_: Mock, body_: Mock, document_part_: Mock + ): + body_prop_.return_value = body_ + body_.iter_inner_content.return_value = iter((1, 2, 3)) + document = Document(cast(CT_Document, element("w:document")), document_part_) + + assert list(document.iter_inner_content()) == [1, 2, 3] + + def it_provides_access_to_its_paragraphs( + self, document: Document, body_prop_: Mock, body_: Mock, paragraphs_: Mock + ): + body_prop_.return_value = body_ + body_.paragraphs = paragraphs_ paragraphs = document.paragraphs assert paragraphs is paragraphs_ - def it_provides_access_to_its_sections(self, document_part_, Sections_, sections_): - document_elm = element("w:document") + def it_provides_access_to_its_sections( + self, document_part_: Mock, Sections_: Mock, sections_: Mock + ): + document_elm = cast(CT_Document, element("w:document")) Sections_.return_value = sections_ document = Document(document_elm, document_part_) @@ -128,279 +253,195 @@ def it_provides_access_to_its_sections(self, document_part_, Sections_, sections Sections_.assert_called_once_with(document_elm, document_part_) assert sections is sections_ - def it_provides_access_to_its_settings(self, settings_fixture): - document, settings_ = settings_fixture + def it_provides_access_to_its_settings(self, document_part_: Mock, settings_: Mock): + document_part_.settings = settings_ + document = Document(cast(CT_Document, element("w:document")), document_part_) + assert document.settings is settings_ - def it_provides_access_to_its_styles(self, styles_fixture): - document, styles_ = styles_fixture + def it_provides_access_to_its_styles(self, styles_prop_, styles_): + styles_prop_.return_value = styles_ + document = Document(None, None) assert document.styles is styles_ - def it_provides_access_to_its_tables(self, tables_fixture): - document, tables_ = tables_fixture - tables = document.tables - assert tables is tables_ - - def it_provides_access_to_the_document_part(self, part_fixture): - document, part_ = part_fixture - assert document.part is part_ - - def it_provides_access_to_the_document_body(self, body_fixture): - document, body_elm, _Body_, body_ = body_fixture - body = document._body - _Body_.assert_called_once_with(body_elm, document) - assert body is body_ - - def it_determines_block_width_to_help(self, block_width_fixture): - document, expected_value = block_width_fixture - width = document._block_width - assert isinstance(width, Length) - assert width == expected_value - - # fixtures ------------------------------------------------------- + def it_provides_access_to_its_tables( + self, document: Document, body_prop_: Mock, body_: Mock, tables_: Mock + ): + body_prop_.return_value = body_ + body_.tables = tables_ - @pytest.fixture( - params=[ - (0, "Title"), - (1, "Heading 1"), - (2, "Heading 2"), - (9, "Heading 9"), - ] - ) - def add_heading_fixture(self, request): - level, style = request.param - return level, style - - @pytest.fixture( - params=[ - ("", None), - ("", "Heading 1"), - ("foo\rbar", "Body Text"), - ] - ) - def add_paragraph_fixture(self, request, body_prop_, paragraph_): - text, style = request.param - document = Document(None, None) - body_prop_.return_value.add_paragraph.return_value = paragraph_ - return document, text, style, paragraph_ + assert document.tables is tables_ - @pytest.fixture - def add_picture_fixture(self, request, add_paragraph_, run_, picture_): - document = Document(None, None) - path, width, height = "foobar.png", 100, 200 - add_paragraph_.return_value.add_run.return_value = run_ - run_.add_picture.return_value = picture_ - return document, path, width, height, run_, picture_ + def it_provides_access_to_the_document_part(self, document_part_: Mock): + document = Document(cast(CT_Document, element("w:document")), document_part_) + assert document.part is document_part_ - @pytest.fixture - def add_float_picture_fixture(self, add_paragraph_, run_, float_picture_): - document = Document(None, None) - path, width, height, pos_x, pos_y = "foobar.png", 100, 200, 100000, 200000 - add_paragraph_.return_value.add_run.return_value = run_ - run_.add_float_picture.return_value = float_picture_ - return document, path, width, height, pos_x, pos_y, run_, float_picture_ + def it_provides_access_to_the_document_body( + self, _Body_: Mock, body_: Mock, document_part_: Mock + ): + _Body_.return_value = body_ + document_elm = cast(CT_Document, element("w:document/w:body")) + body_elm = document_elm[0] + document = Document(document_elm, document_part_) - @pytest.fixture( - params=[ - ("w:sectPr", WD_SECTION.EVEN_PAGE, "w:sectPr/w:type{w:val=evenPage}"), - ( - "w:sectPr/w:type{w:val=evenPage}", - WD_SECTION.ODD_PAGE, - "w:sectPr/w:type{w:val=oddPage}", - ), - ("w:sectPr/w:type{w:val=oddPage}", WD_SECTION.NEW_PAGE, "w:sectPr"), - ] - ) - def add_section_fixture(self, request): - sentinel, start_type, new_sentinel = request.param - document_elm = element("w:document/w:body/(w:p,%s)" % sentinel) - expected_xml = xml( - "w:document/w:body/(w:p,w:p/w:pPr/%s,%s)" % (sentinel, new_sentinel) - ) - return document_elm, start_type, expected_xml + body = document._body - @pytest.fixture - def add_table_fixture(self, _block_width_prop_, body_prop_, table_): - document = Document(None, None) - rows, cols, style = 4, 2, "Light Shading Accent 1" - body_prop_.return_value.add_table.return_value = table_ - _block_width_prop_.return_value = width = 42 - return document, rows, cols, style, width, table_ + _Body_.assert_called_once_with(body_elm, document) + assert body is body_ - @pytest.fixture - def block_width_fixture(self, sections_prop_, section_): - document = Document(None, None) + def it_determines_block_width_to_help( + self, document: Document, sections_prop_: Mock, section_: Mock + ): sections_prop_.return_value = [None, section_] section_.page_width = 6000 section_.left_margin = 1500 section_.right_margin = 1000 - expected_value = 3500 - return document, expected_value - - @pytest.fixture - def body_fixture(self, _Body_, body_): - document_elm = element("w:document/w:body") - body_elm = document_elm[0] - document = Document(document_elm, None) - return document, body_elm, _Body_, body_ - @pytest.fixture - def core_props_fixture(self, document_part_, core_properties_): - document = Document(None, document_part_) - document_part_.core_properties = core_properties_ - return document, core_properties_ - - @pytest.fixture - def inline_shapes_fixture(self, document_part_, inline_shapes_): - document = Document(None, document_part_) - document_part_.inline_shapes = inline_shapes_ - return document, inline_shapes_ + width = document._block_width - @pytest.fixture - def paragraphs_fixture(self, body_prop_, paragraphs_): - document = Document(None, None) - body_prop_.return_value.paragraphs = paragraphs_ - return document, paragraphs_ + assert isinstance(width, Length) + assert width == 3500 - @pytest.fixture - def part_fixture(self, document_part_): - document = Document(None, document_part_) - return document, document_part_ + # -- fixtures -------------------------------------------------------------------------------- @pytest.fixture - def save_fixture(self, document_part_): - document = Document(None, document_part_) - file_ = "foobar.docx" - return document, file_ + def add_paragraph_(self, request: FixtureRequest): + return method_mock(request, Document, "add_paragraph") @pytest.fixture - def settings_fixture(self, document_part_, settings_): - document = Document(None, document_part_) - document_part_.settings = settings_ - return document, settings_ + def _Body_(self, request: FixtureRequest): + return class_mock(request, "docx.document._Body") @pytest.fixture - def styles_fixture(self, document_part_, styles_): - document = Document(None, document_part_) - document_part_.styles = styles_ - return document, styles_ + def body_(self, request: FixtureRequest): + return instance_mock(request, _Body) @pytest.fixture - def tables_fixture(self, body_prop_, tables_): - document = Document(None, None) - body_prop_.return_value.tables = tables_ - return document, tables_ - - # fixture components --------------------------------------------- + def _block_width_prop_(self, request: FixtureRequest): + return property_mock(request, Document, "_block_width") @pytest.fixture - def add_paragraph_(self, request): - return method_mock(request, Document, "add_paragraph") + def body_prop_(self, request: FixtureRequest): + return property_mock(request, Document, "_body") @pytest.fixture - def _Body_(self, request, body_): - return class_mock(request, "docx.document._Body", return_value=body_) + def comment_(self, request: FixtureRequest): + return instance_mock(request, Comment) @pytest.fixture - def body_(self, request): - return instance_mock(request, _Body) + def comments_(self, request: FixtureRequest): + return instance_mock(request, Comments) @pytest.fixture - def _block_width_prop_(self, request): - return property_mock(request, Document, "_block_width") + def comments_prop_(self, request: FixtureRequest): + return property_mock(request, Document, "comments") @pytest.fixture - def body_prop_(self, request, body_): - return property_mock(request, Document, "_body", return_value=body_) + def core_properties_(self, request: FixtureRequest): + return instance_mock(request, CoreProperties) @pytest.fixture - def core_properties_(self, request): - return instance_mock(request, CoreProperties) + def document(self, document_part_: Mock) -> Document: + document_elm = cast(CT_Document, element("w:document")) + return Document(document_elm, document_part_) @pytest.fixture - def document_part_(self, request): + def document_part_(self, request: FixtureRequest): return instance_mock(request, DocumentPart) @pytest.fixture - def inline_shapes_(self, request): + def inline_shapes_(self, request: FixtureRequest): return instance_mock(request, InlineShapes) @pytest.fixture - def paragraph_(self, request): + def paragraph_(self, request: FixtureRequest): return instance_mock(request, Paragraph) @pytest.fixture - def paragraphs_(self, request): + def paragraphs_(self, request: FixtureRequest): return instance_mock(request, list) @pytest.fixture - def picture_(self, request): + def picture_(self, request: FixtureRequest): return instance_mock(request, InlineShape) @pytest.fixture - def float_picture_(self, request): + def float_picture_(self, request: FixtureRequest): return instance_mock(request, CT_Anchor) @pytest.fixture - def run_(self, request): + def run_(self, request: FixtureRequest): return instance_mock(request, Run) @pytest.fixture - def Section_(self, request): + def run_mark_comment_range_(self, request: FixtureRequest): + return method_mock(request, Run, "mark_comment_range") + + @pytest.fixture + def Section_(self, request: FixtureRequest): return class_mock(request, "docx.document.Section") @pytest.fixture - def section_(self, request): + def section_(self, request: FixtureRequest): return instance_mock(request, Section) @pytest.fixture - def Sections_(self, request): + def Sections_(self, request: FixtureRequest): return class_mock(request, "docx.document.Sections") @pytest.fixture - def sections_(self, request): + def sections_(self, request: FixtureRequest): return instance_mock(request, Sections) @pytest.fixture - def sections_prop_(self, request): + def sections_prop_(self, request: FixtureRequest): return property_mock(request, Document, "sections") @pytest.fixture - def settings_(self, request): + def settings_(self, request: FixtureRequest): return instance_mock(request, Settings) @pytest.fixture - def styles_(self, request): + def styles_(self, request: FixtureRequest): return instance_mock(request, Styles) @pytest.fixture - def table_(self, request): - return instance_mock(request, Table, style="UNASSIGNED") + def styles_prop_(self, request: FixtureRequest): + return property_mock(request, Document, "styles") @pytest.fixture - def tables_(self, request): - return instance_mock(request, list) + def table_(self, request: FixtureRequest): + return instance_mock(request, Table) + @pytest.fixture + def tables_(self, request: FixtureRequest): + return instance_mock(request, list) -class Describe_Body(object): - def it_can_clear_itself_of_all_content_it_holds(self, clear_fixture): - body, expected_xml = clear_fixture - _body = body.clear_content() - assert body._body.xml == expected_xml - assert _body is body - # fixtures ------------------------------------------------------- +class Describe_Body: + """Unit-test suite for `docx.document._Body`.""" - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("cxml", "expected_cxml"), + [ ("w:body", "w:body"), ("w:body/w:p", "w:body"), ("w:body/w:sectPr", "w:body/w:sectPr"), ("w:body/(w:p, w:sectPr)", "w:body/w:sectPr"), - ] + ], ) - def clear_fixture(self, request): - before_cxml, after_cxml = request.param - body = _Body(element(before_cxml), None) - expected_xml = xml(after_cxml) - return body, expected_xml + def it_can_clear_itself_of_all_content_it_holds( + self, cxml: str, expected_cxml: str, document_: Mock + ): + body = _Body(cast(CT_Body, element(cxml)), document_) + + _body = body.clear_content() + + assert body._body.xml == xml(expected_cxml) + assert _body is body + + # -- fixtures -------------------------------------------------------------------------------- + + @pytest.fixture + def document_(self, request: FixtureRequest): + return instance_mock(request, Document) diff --git a/tests/test_drawing.py b/tests/test_drawing.py new file mode 100644 index 00000000..c8fedb1a --- /dev/null +++ b/tests/test_drawing.py @@ -0,0 +1,74 @@ +# pyright: reportPrivateUsage=false + +"""Unit test suite for the `docx.drawing` module.""" + +from __future__ import annotations + +from typing import cast + +import pytest + +from docx.drawing import Drawing +from docx.image.image import Image +from docx.oxml.drawing import CT_Drawing +from docx.parts.document import DocumentPart +from docx.parts.image import ImagePart + +from .unitutil.cxml import element +from .unitutil.mock import FixtureRequest, Mock, instance_mock + + +class DescribeDrawing: + """Unit-test suite for `docx.drawing.Drawing` objects.""" + + @pytest.mark.parametrize( + ("cxml", "expected_value"), + [ + ("w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic", True), + ("w:drawing/wp:anchor/a:graphic/a:graphicData/pic:pic", True), + ("w:drawing/wp:inline/a:graphic/a:graphicData/a:grpSp", False), + ("w:drawing/wp:anchor/a:graphic/a:graphicData/a:chart", False), + ], + ) + def it_knows_when_it_contains_a_Picture( + self, cxml: str, expected_value: bool, document_part_: Mock + ): + drawing = Drawing(cast(CT_Drawing, element(cxml)), document_part_) + assert drawing.has_picture == expected_value + + def it_provides_access_to_the_image_in_a_Picture_drawing( + self, document_part_: Mock, image_part_: Mock, image_: Mock + ): + image_part_.image = image_ + document_part_.part.related_parts = {"rId1": image_part_} + cxml = ( + "w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill/a:blip{r:embed=rId1}" + ) + drawing = Drawing(cast(CT_Drawing, element(cxml)), document_part_) + + image = drawing.image + + assert image is image_ + + def but_it_raises_when_the_drawing_does_not_contain_a_Picture(self, document_part_: Mock): + drawing = Drawing( + cast(CT_Drawing, element("w:drawing/wp:inline/a:graphic/a:graphicData/a:grpSp")), + document_part_, + ) + + with pytest.raises(ValueError, match="drawing does not contain a picture"): + drawing.image + + # -- fixtures -------------------------------------------------------------------------------- + + @pytest.fixture + def document_part_(self, request: FixtureRequest): + return instance_mock(request, DocumentPart) + + @pytest.fixture + def image_(self, request: FixtureRequest): + return instance_mock(request, Image) + + @pytest.fixture + def image_part_(self, request: FixtureRequest): + return instance_mock(request, ImagePart) diff --git a/tests/test_enum.py b/tests/test_enum.py index a07795ed..79607a7e 100644 --- a/tests/test_enum.py +++ b/tests/test_enum.py @@ -1,102 +1,92 @@ -# encoding: utf-8 +"""Test suite for docx.enum module, focused on base classes. -""" -Test suite for docx.enum module, focused on base classes. Configured a little -differently because of the meta-programming, the two enumeration classes at -the top constitute the entire fixture and the tests themselves just make +Configured a little differently because of the meta-programming, the two enumeration +classes at the top constitute the entire fixture and the tests themselves just make assertions on those. """ -from __future__ import absolute_import, print_function +import enum import pytest -from docx.enum.base import ( - alias, - Enumeration, - EnumMember, - ReturnValueOnlyEnumMember, - XmlEnumeration, - XmlMappedEnumMember, -) +from docx.enum.base import BaseXmlEnum + + +class SomeXmlAttr(BaseXmlEnum): + """SomeXmlAttr docstring.""" + + FOO = (1, "foo", "Do foo instead of bar.") + """Do foo instead of bar.""" + BAR = (2, "bar", "Do bar instead of foo.") + """Do bar instead of foo.""" -@alias("BARFOO") -class FOOBAR(Enumeration): - """ - Enumeration docstring - """ + BAZ = (3, None, "Maps to the value assumed when the attribute is omitted.") + """Maps to the value assumed when the attribute is omitted.""" - __ms_name__ = "MsoFoobar" - __url__ = "http://msdn.microsoft.com/foobar.aspx" +class DescribeBaseXmlEnum: + """Unit-test suite for `docx.enum.base.BaseXmlEnum`.""" - __members__ = ( - EnumMember(None, None, "No setting/remove setting"), - EnumMember("READ_WRITE", 1, "Readable and settable"), - ReturnValueOnlyEnumMember("READ_ONLY", -2, "Return value only"), - ) + def it_is_an_instance_of_EnumMeta_just_like_a_regular_Enum(self): + assert type(SomeXmlAttr) is enum.EnumMeta + def it_has_the_same_repr_as_a_regular_Enum(self): + assert repr(SomeXmlAttr) == "" -@alias("XML-FU") -class XMLFOO(XmlEnumeration): - """ - XmlEnumeration docstring - """ + def it_has_an_MRO_that_goes_through_the_base_class_int_and_Enum(self): + assert SomeXmlAttr.__mro__ == ( + SomeXmlAttr, + BaseXmlEnum, + int, + enum.Enum, + object, + ), f"got: {SomeXmlAttr.__mro__}" - __ms_name__ = "MsoXmlFoobar" + def it_knows_the_XML_value_for_each_member_by_the_member_instance(self): + assert SomeXmlAttr.to_xml(SomeXmlAttr.FOO) == "foo" - __url__ = "http://msdn.microsoft.com/msoxmlfoobar.aspx" + def it_knows_the_XML_value_for_each_member_by_the_member_value(self): + assert SomeXmlAttr.to_xml(2) == "bar" - __members__ = ( - XmlMappedEnumMember(None, None, None, "No setting"), - XmlMappedEnumMember("XML_RW", 42, "attrVal", "Read/write setting"), - ReturnValueOnlyEnumMember("RO", -2, "Return value only;"), - ) + def but_it_raises_when_there_is_no_such_member(self): + with pytest.raises(ValueError, match="42 is not a valid SomeXmlAttr"): + SomeXmlAttr.to_xml(42) + def it_can_find_the_member_from_the_XML_attr_value(self): + assert SomeXmlAttr.from_xml("bar") == SomeXmlAttr.BAR -class DescribeEnumeration(object): - def it_has_the_right_metaclass(self): - assert type(FOOBAR).__name__ == "MetaEnumeration" + def and_it_can_find_the_member_from_None_when_a_member_maps_that(self): + assert SomeXmlAttr.from_xml(None) == SomeXmlAttr.BAZ - def it_provides_an_EnumValue_instance_for_each_named_member(self): - with pytest.raises(AttributeError): - getattr(FOOBAR, "None") - for obj in (FOOBAR.READ_WRITE, FOOBAR.READ_ONLY): - assert type(obj).__name__ == "EnumValue" + def but_it_raises_when_there_is_no_such_mapped_XML_value(self): + with pytest.raises(ValueError, match="SomeXmlAttr has no XML mapping for 'baz'"): + SomeXmlAttr.from_xml("baz") - def it_provides_the_enumeration_value_for_each_named_member(self): - assert FOOBAR.READ_WRITE == 1 - assert FOOBAR.READ_ONLY == -2 - def it_knows_if_a_setting_is_valid(self): - FOOBAR.validate(None) - FOOBAR.validate(FOOBAR.READ_WRITE) - with pytest.raises(ValueError): - FOOBAR.validate("foobar") - with pytest.raises(ValueError): - FOOBAR.validate(FOOBAR.READ_ONLY) +class DescribeBaseXmlEnumMembers: + """Unit-test suite for `docx.enum.base.BaseXmlEnum`.""" - def it_can_be_referred_to_by_a_convenience_alias_if_defined(self): - assert BARFOO is FOOBAR # noqa + def it_is_an_instance_of_its_XmlEnum_subtype_class(self): + assert type(SomeXmlAttr.FOO) is SomeXmlAttr + def it_has_the_default_Enum_repr(self): + assert repr(SomeXmlAttr.BAR) == "" -class DescribeEnumValue(object): - def it_provides_its_symbolic_name_as_its_string_value(self): - assert ("%s" % FOOBAR.READ_WRITE) == "READ_WRITE (1)" + def but_its_str_value_is_customized(self): + assert str(SomeXmlAttr.FOO) == "FOO (1)" - def it_provides_its_description_as_its_docstring(self): - assert FOOBAR.READ_ONLY.__doc__ == "Return value only" + def its_value_is_the_same_int_as_its_corresponding_MS_API_enum_member(self): + assert SomeXmlAttr.FOO.value == 1 + def its_name_is_its_member_name_the_same_as_a_regular_Enum(self): + assert SomeXmlAttr.FOO.name == "FOO" -class DescribeXmlEnumeration(object): - def it_knows_the_XML_value_for_each_of_its_xml_members(self): - assert XMLFOO.to_xml(XMLFOO.XML_RW) == "attrVal" - assert XMLFOO.to_xml(42) == "attrVal" - with pytest.raises(ValueError): - XMLFOO.to_xml(XMLFOO.RO) + def it_has_an_individual_member_specific_docstring(self): + assert SomeXmlAttr.FOO.__doc__ == "Do foo instead of bar." - def it_can_map_each_of_its_xml_members_from_the_XML_value(self): - assert XMLFOO.from_xml(None) is None - assert XMLFOO.from_xml("attrVal") == XMLFOO.XML_RW - assert str(XMLFOO.from_xml("attrVal")) == "XML_RW (42)" + def it_is_equivalent_to_its_int_value(self): + assert SomeXmlAttr.FOO == 1 + assert SomeXmlAttr.FOO != 2 + assert SomeXmlAttr.BAR == 2 + assert SomeXmlAttr.BAR != 1 diff --git a/tests/test_files/blk-inner-content.docx b/tests/test_files/blk-inner-content.docx new file mode 100644 index 0000000000000000000000000000000000000000..1edfb41977970ba897ade620b1361df205742a12 GIT binary patch literal 11949 zcmeHtg;$(O_I49of(ExV!GgO53GM`UhsNC@ND|!L-AT~k?(XjH4#AzTGrO~s$J^iL6o5-_80)^&*%z zj#hpT7U$y&<;SR=#;0bC7jjAvkq8zfWX#vg%*x%~WAjNC@Mu-eWCz$hai62LP1&jE zW;SWP3~|ZVVi=bB``A8NurxN|O0hvOys7Gl8d5;`kdmF^jj4JA2&0M(S0;4}WhU}@ zz+zs#Zd!(nUnaA8`=JUJA6YvC9WlCmhSkGLj0DGU&VEAGI9AF>xAIlszWd%}dW?I# zY=qr{w>{x$7#Qg=m7*SfMC8kq%x)eEIuvdX)8 zS|NIf$l=ALtYX#7rL<>C*t}4PMsDGa1wxd!k*j!scRMmZm{NSDB0mNiF>u zw-@d$Zy*7H=VwTO?B86HC=##c1Z-zAV2?utyQGdC$ikkU?x*~pEB+t$zhC}(QB<2* z2Lsak6Yodwu_n3sHk@o3dV|pgoHqyDlS4NNhZ^YmBdk3pw294msMBW4> z47FlxQ3+jbXpkxY>`eei+vi!HDmB zJTq-Xc>8j>R;S{AbS+b;+1pDRJPQVTvXn^uA_TnC#<6|3?3VnlKwld8O!z?hdv_yE zboHm5plw_}wiBRQrOui)eu@_VIe20EZ~vG!tdP3^cLpQadk6q<5YEf+!(_tXMYZqA0|LvzJY5;67;JMrP$veS=_ML~Uz@~)+aAEopAWXzpKm$K? zvDQ*5CVnugTYqX-l3+jbiEUw|Eyy`!@?(BRuN~@cNa@EJDwnTBrN{iJ<|^g~gj6_@ zx*FQr7HOkqGLn;*pM|nGsY2ozh;KAd&FKEHK09vnJ~8|zMj!#y`#b(xXQ=SLsx;7~(K zv7X2;Oq+;6AOmJ`10jt?bL`(e+^iW*pm1t4Mis!kMxR^Baak3T$n}_sYb8;#j#~6!LtAUYqkN8E_FZ zK~+Z}=Ae$eu)i;CYI16_K0F^*51_hdC(nMc>vcLt5CCFvN6MufQ>RSjer70-xcn+z zgj?m7JXxqp=T)C3LLLKM7Ig3WfXkYePVP2@K#_&^F_?;upwyH{FT%I0y-L6yRkL&* zS|7p_ezeWDE2bI=LwXiPmB@ya6J??rr_Mn5tMzynXzq;WhKknY2dFYW>x%tO`)5>{YZ)S;+B>$kb0(Yl?XFyD30!Oe5~aJzh(TyVFTH z9av-ztjaGv?|NiHdkKmQ#-oVfM2`mLcST|9msvcIi=LNMq|4(Pt> z&~%U#p_v|68>TZ}-ZiW_kX=`{0=M@1#ao$2XBkGwXIAT?;=MtMXRTfYif1K7 zDS0i2*^TT9zim{98Kf^(JwgsRjbkbNX!|OYLT%@WMHlqmUkN*PEBMlHdD|T9goG=ap0Q9{E05JdbQwI}}C5ZkH$@p__ zKU9+p#ur6xhCL(ps~d0|+SMy!9Tz(@pJ7|B@(yp3H_t0hGaXx+uVV1iO}B%GN{J9e zs@p;pKw|9Nj3PED6Hg(I+$R!eroHS8*YbvM_@czu{Ozg!TYWu?{o49t0+(n4VtZ7W z29Js@VM@qs0;yh4lLrG$m8PgzOb8kX{<8Xq_nQN$ z5Do3^1RrZ+G!R1aS!sJZI;t{uZnd);rb{6dtu|nW_zgx?4<-OCcx^HYba}%@w5M^i z1eBKQ4%f+#Zd0v07c(`dS~?y`jWD^=)`)xrFo`eiGb;D2*B-SSX4o&yW#=s{){P zvZv)~t8m8a;Z|oqm;a!_xHO&b%-^$Z% z5^j5tR`Rv#OgVuf)5Df`WWx&RV5sqK_Vi4b*SnU2EtcQsWfJ?_S^{5=wsARoi=gkq zhjc(ct?S+Z<~H*2I>{6w66I)u2*Ec=Oqm0uFfB9|P;D!ImRH9dJR+9+_cy&l?Q`!Z z^UxJKLgGg?vu68ox>&*&g_+7D7j;e}^=yD`6TrMd+>r06Y>D{pdZSG+rrpO^JoN$6 zr16Gkg2yD?XT7}1Fla%>%EP3AXS3A$2*99}WGQuVhI5|+-Wv!q-{WS%vbE!y^rM9c zze9*DqwPf}QU>OcjW05&)o)MEX2rg1$rO!^CHsq*oajr9G2$5+q+4mLM86i7cH9(uM@lO_uI>`y{p%8pF5w1t2y6Ks=h`{ zfP_-=qh0zEu=XS+L`Xr)R?{y%D41NA*(i6>N$P42T`6~eLtJ|G8DV1zCT z)@Vg8;XcEP=C|#Z%B&C@24{QNtR5^Mtn_O|X+|rOwu|y^S7um*cW#TKI13Gjsc;*5 zMGFke*M<3BsPpWOsjs)^^I{0>HEYT?QajAOSv?H*XDE25Zt@smip6hVm+~2rbKKIO z`4&2I%+trHOiHN~H7IvqmV=o*!)ClgdCBa{@CFZ?jA-H1l)W_SdnSDUc5_x_P?D4= z{?H-BvU=08?;Za^(5EO5V)VK$DRf7~z-_ZrTGESQ8DHUr_N?4V?DA0^$ceGgN^Vn=nZUJUckUnoF>(Z&(g$F>d;xhFoCoeEJmw{KR_*`*Jh+NGk?w zBRoj6UghPFKlTXeAIqW(7VRv(j}FnOnpXVyAkC3*~o~tOROhM6#YClCH^J{x4R@j#*>OK~X-7zJnI{H*j3c_ptt`j%@Ary(&I6g{O$5MH-+aV~yIYs`)GROc6w2Q(26Tb)4pz&trcaIwtJa;b zks$`SO(y-0+!|&ms}7d*`VOwubDc(aWA8#U=7_H#Tc(J39a7)CysE!!HAhm<6=8*w z(9X`+8GOA%ctw)Kk_Dd~oR@t6vbb9*7&1%F@mqrMSo`VtY1=Q@= zMFL5NKIk5JuxaeJZg`B&W_{6V?I6;4fk62h@<2+-sEwx)^ssjhe!-@DF8xx$&7W#}GD9~vTBI`~r7f}Gy(@;3Y-^8k2a0?`iv zL>@YyPo4t&5C%O)iiY2W>xiIo0~0oLTyT4Gc5uA6aKqc_vjb^Exfma&(BHa=o4wmj zGeqwzvAJ(7=dN3@2g->633^Z9-G&-rH=q0~SsizL@#i1MJv(&IM`EomkvXjmY^+~-ST#)RjyAlKS{-%z`ADp-^0XV>k=0!EI8rYduOrKIJP>)s8_Whg zI=O-|^%F@=DlK(_Z3`p&{K?j^Mi`{<-NSMmjreDd09~lL_+pLFQsb)fs7l4Qrqd3= zo1UvjteX|`2|Opnb@O#TTj}zXO8#ufos2CtqLGY!2)JvCVHoS@wm6QrwA z+-Mk7NA--n&#nwJmgr&BbV0^$nX$g!H09+c5nakyDCL2%(&}>%MqxQVeD9fOLDcln zxmj&pN1yo6=JJ6QHXD0^ppMR#eFlkF4#v>o-dN-MUO0o{Q39LJvPEV4+R(>V71tt@%5%VLpnk2r#L=}0q#&?h87je;}!Ao5$1!{UL8^QElcmB2Uxqw;rm>S46=`pEG{>h z2qTXJRTakEyD1|@W(gDWvRcyERoG)Pc8q#rS!S_q4V+{1NEv%=jD1vSNW z=id#AV+Ks?A`+&VJc^n$IW`Qd0ns{=tMFWsyg3cdx}e3pZLlnljMo@9LeZ&Wc4&?& z-JogmA%YNFC0ecU3|N`UWpDkw?eL6T+gIfVuq7%fTiCm~nw37kDgv%Kl78O6OD^u2 zd+lLbi>!vC**49O;IOC~;~GF%`;C%%){nLW?-@F|C)S8ju5vLmBmx-u(r$>gU_-o% z2-W{Rtac^EV=G}NJ~GgU9O|kTgy~@zf~muf&qe84tEGrFbDb^Usl9j4M0H-#o<)LA zL3sZ84f;+BhMSQ$B(@BzWVw7)(|+kFftV>P?fOEfnBU4+rzQul^i$XOOkEP zMpVG+$IKH{yO|>ST$&Prw{hAMnMaVFheduyOhAl=`F!g|Gq2NiZ2|H=_dcIQTBqGk zSfT1oYEC>X`A_VM8Z9N83kP;K)X)@1=10APWY?{Bj4jPcRUpJdY_YfLhLM;fWJwZM z@(8)|7HprA{9m>14Ed4l$8^*x7i`?KAtC9F_LUS>n3i@6GscRNYiG$$s6t*FR>Sc+ z-co%TAaPxuZKWt~5;A`~4UB@=)v=w!16XHQM$3 zEY7Fv4kHy>e2+Vk4W3_#{WFP~IT;&8XT?9~xodt5a@#78X%X4n7lI}3?f{)H0$)W5 z-@{7=IY+Ad6(A4HbDE{66WL`vRgFC${!_g?aJ2#QKtA((Gfy(kJmCs zR>dwA`L5PRL?_aa?Dxxt={Q+VPO&P&iN+?m3iH*44^_=NnpHOPEQHE5_UIyfh}2$uEg~7YTlOG6u$pBqe|2`mhClszNc0oBg`6i; zDsm$foBwISk%<9KuQIA7YV$j{WK@e>hT6QtMl^DgGU6B0CD-jy1j$t6AHz$Vot!&x z!>C*O)Vfn;mZlLoUFs6@Q(1K-X{gHiI1}JpGFH$AUw>$*7IsX!UBEfMW^0zz*1{t5 zSb=?K`|6_`!#^7-j;X0P2yCP?U?WBQ)kqDj?f#hZ|7WFO69qpZQPLm4cN=~uVh{dQ z*KB)KZHiT?P$m@QKt`x_EOcu`bKV%kgS(Ty`QmI7SgY!lnQ#k=uEW;{CMeVJ#S$^( zP{J7r+XBUs7u6{}3a>anVCGjT%VuE_Bq`OfLo;(uU}+bz={5ndp`+|LnaSo|tnESw z7e3|C!6RdK##Tq&Ma;9Z#aQm)o%%$)qiIu+;pr09wSXbv0&?O<7#SZRx8nNYky4)6 zB<0+!U+U&I%#XfpNs+&qZdE!^BUpr`fH9b05s!A9X7CE)!x|}F`u1J6M}zUbQk&Yb zZ)qmgDH&4af`

    xreKmz#xrmsU6>s&qb1%UK=Hgvwi~i+5-Z-|n*68Jcr`8^O000F%1b=Yj_71KV zpg#^9jj7W13moWvCmL1HpK~XUf!`lebGn&9@A~GeY}au)qnU*Su%<~fq5EdjbXovn z;u*;qv%019fx_R2Kka(rn|SWUucVc;-1R8|4L#ZByxye>afgFQ&h9Jvt{Xn9egzTGCl+&W)wb8uraWiW#iro$rHCI)GOxao@@)7HO|_cy8r zDSgl5LC)lnh%JfN+z zqC07|l&M45Bxun*6Z${mmv5tUjibG@FXJR9yr-*UwyqB>xxLOkwy!$pSY{S0;1#Tm zcDij!Im_<6c5GCVKU~&mhlC<)5_VUpOS{qQxJUkg{9u&3Y|ECIly}j6GE*ZVmWyf6 z=K9<`$FY%Ei!R=7zY}~bPx{akwX=elW>NF}G$-Ow0gO{BdFJKjseY0O-keYvR1pz$ zvmPGY^Hf4iR1>uw<`rvpu}hDDXqp zDa_2CG26YV!sBu+_LBi8olB=8x*quO(Ouiq&4BGj07vYeY!Q~8H*73D*<|2vOz<}p zOAp4bNf<@g7{P}G5{}#u54l~a`%H@Y`?`jm0EXk^x4@8wk1%i>$1*p1i%YjWAr0?R z{cW9%Przk{p*z!(#k=YQH1wi{7C=zqK$Iw%7v2YhI-|M$AU|Vro)R(SD1d@-wGj!C zba3Kh<2!*Ov5uYd@kyOXO(8^Eowr&s;YS=JUT2E&J!q2XLvNs{w3YjrNq~&SH(#jJ zdQzCm_A=F6DvV z6u#r``koNW9Rc!@F~Y8tYM@;4fn|W^em0gXtLJ+S7Ajjy7ooHH(*UUIwb1z4P;K&L z=y^^E~}xd7Zcf_E09WVDY7+X!cUm>86~_YzrK`- zgp>KAnCj?Ov|+Mp+M)KxfDe|{1A3dA!Uq&`Pk7{NUwp4JT7s!I?YtsNpKEk8hVXrx z8SecJLY)Uz?nH^I0{MCfO~^hGo0p{c0*T6M+OkC7x6p{nw&aNE^?Fr_+TL;w+{dHC zCo2{SxL89>;8$A<)l2VF4RVUr2a?mfR!0SWH7422k6B^8XJgFr=Ml5-(Jd7 zLyLYynZ`TVq^gP`Qu|fl9E*WGN=Y};~PO*#S+=M3Z3-0WrR%MW8JkCbItGPRh@iSO?6&X<)Ekbe6LdnG%-std*17<|5z|k+|1YA z+{{OsjwK$WDC4{Npl9SHHC}mSd7K7tU7^c@1r4uItEJaiYuVsE$<9=1b8JC}b8-52 z&}&wehj5tvh?pd!0>0pqwHHVfiYDP0 zRFx=bR5?CynDYP12O|^%-v9C1OU;FkL*70JZ%r}PWsL_sUJSV6=WtUt4+!}0tOG3PgY5RL@F5TJnXt3R6dXGK5T1N`qM z9(A>&3HV-dWD4A)W(r6I$O57N)3$#>ekS2D6JX*0)A}rW-ek#`=7q!SAI3aQ&W9*1 z4pR>MDA#gU*p3_oRmZXEtPg5Fh;NCrhG9`qESngSNVdO5T)nE=DX$->su9YdbN6gG z^lI#K z!Z%xx;}YYp9sSNMH7t|Ck89`y&OQ&HUIG3iR19AePNTsiWu^aP0fUNQqMjBZogyE^ zfteVb9c!yk176k_t(S6oC4PZu;Jns)E^f|yc>WTY1RE7W#j-*m)!>v3RYyG@dRd7d zR8gU*Os}?7EjW923KetPthV;AA|SAL3V?BJ7J%TyD&$*-r`TtrBKTr@D&mtPD=AbR zo^Ct1qP7yh0$!Dc3QAg)Z0^H^4J^Gdpp}3Vl5O7{BT_*e!9lB89}r4ea#Y1Ued8P1 zjHze4?8z;>;LCeNWLSiK6ZV;z@ffhV|zTC=_bGtH{W|Asj~4cm+o(ZthCT}O8!40 zY6V>D*MYx@-x}eNEe+L1oneHl01~=xuBBF{kz{+?@>#L(LQH(x6!+nsZ0eb|R!(F) zv~JrwiNAY4WIm8;91?X`Rs3?)^9R@5Lv;)z8&6Qu%7Pi&LKypu>H$_U(1J>Pzj}S! zS0ODg3A@KC&Aq%d)MKt}=cv5;%|d~iR|D?+k;~MId8o2=izG%ak4LrK;yV$?jC-z| zX1U`MqW!1AiMyTI3*s5qEQs(SYxgN0=`_{Q@q2pLq~)@^1-q?hvwmz)le3rE3iGM{ zbE79HZAN=;aUc4y>Yaj@g{RvP^YW$SMRM@das&%}jzR4aA*F$++k2YIChOtHPs5XQ zL&x7lqfGDEvk#7}R0PXf4t5%pfFTt})q5994sK`P>*P;FI(-%4Rg^cXdXBD#k~5R( zo^y@i?|Xu}+|L*6xGvMARh9acxuNE)^vQbN2*vrkNoEW>OS==FagDTLFO6;*^xYp- zejGf5x9k5R7$IKJf@!6Hj_dt-uKM-)hbUiJ$-gW3dlcfY;OL(h6Mw}d{to&))mbAyZZo8f+dvBVG{!ZD5XMn)+wz{{bF&$!eCX+Yo z`v-pSuGOczWS?7IYoA+H`yP2INT^o;7yujq03ZRZ|$$dug&0WWl5X`^@1t`@B-Zbf7k!v8TcMMVBOAyDsmlnhZ0qzVz8T4Nb@3u zFP>g;4;IJmh3aE;PvcWF#tQ`%h$sY0QVQ1VWmeU0pRxI5OL#Pp6U6~GZ~T`S9kaKz zb2FRtUPicY)?%5K1^PHXTe3Aa;YxErFp+^eqKA|aOfNTo1z1^gFPWsozmdxO7wxy-U;*lZQRyf@*cogzMMIs$uXmGPdi zcYER9>IM=3cz%Wi$p0-QUq|89oPc>I3ywHMa7gOf8C%*jGW@jv3&sD#@%PJLFOF_A z?_ffDf8z7#GuEUq--eSd%V;>dfHMaRrzs(gu`p{s^Yq9wJNrU=PhV_cd?IGl)jn0! zVKr9!6fa)oWpESx^sP>Z=6$0xAkMEbm)UvRb{#2Y`^x08pG<(a z;!rEb7LD-LRz9K`DfP&tA$e7H+9#En>qJl1j3nl%X>)N+H`qd6k!F9w`e9s81QY&> z1XlXUi1y`5?M~(Wm|B)FbLvYvJWD1E!(F0(@fS=udPdOlp02PpyX#x4ep*qBc4gWG!&5a;_epu8eeH+w%pc*jO*I%1>AO@Ua(u40;H}Jm zvu0P|c)JzM7*`Ac01ZrrKUniCUk(!$BIY?!dsgK3o!+~wyp(_||CqV&xX>i229G)K zRvc;=9mrX22`R<@7WmuM`eTeFCz4LSj_ zi4-nL;Y}mw*J?s#WSBG<%H`3aO@vX)2Yp5S)-~C_YwQ%c`+%(2Z2BHUMy22gcir_+ zdGa!|aOfDzZ>7xHe3}gQ(hu|)K}3!|r7r8<`lJ+t*I04*^9HjaN{36s8z3 ze8%w9S)B^Avzj4x%D1{lkD!aF%QEX>q0~yx13O(pWRtCCV(3oqIF^Ci=5{kpJRDZo zIi8xpm-LIZ^eD1)2}Fc)*Br6zr>|~R9?bOP_~nr5DGvih4|!#yPJy!dzJgfO7&Qn( z0=7OFD5$V-_@DWP<)qDe%Ex>!Kkq<@MV~WObo3IINO=rQBp46)=vnAYoF$C$O@dmc zTG~y^3ya?sL*244S0R1kM5lV~Aujc1Gz%aSDMTpl6Fvvw;itW~n|1!?w6I*SPjvgxi_O(&awBL9<3C@Y(2K9xAOkP__*~uNvU>tr&R)MwBJ6nap z$x;AB_Dh=XWvvi5)JS4a<0pJ+c@AyflKD^a;nTrKLtf0)cEd}{_^g&mh~M~_PZ5As z?^TL8nvJ`X_h%?god`|D`<@zounRm6Lad-&6`Kkme`pkXO0OX!6@g}mI#pN4tV3+m zBnkX$5saqTu~(qg^xaCfdsJ+ZT!_*)(dx_!zsNcM*n2f{vd+U(83OY#G0CaxR>k^w zBB&bjP?lv7Q@CVeU-TZmIB&$)5yo)|f3a)L%}x3gcs0bp2-lHDoq&|KLBf;rVs%d} zCn~tD%x1JoNI1=;(3&ApF?9OKn+~NIR{;Kt454qeJFXJ!5U@nLDjB&-P_S$h4&z-n zup=OX;qB0{6w44MOq{}sx<`#|$}-2RW7H7OC85JN!P@Q&?i#pfT{QYF+HVANe2qx@ zUgd7eqJFPLOB;0K=j&mRf6t)3p1pV0K+LEX`G_du41t;7a&LmbhofKMnE>+hrhvJXC6=5K`S1svr_`=VmmKVYx&qQPlox30C^c&IoNE_y%tk z{^r7``oj8pHv6^p$3$+iM8x*!a7|vdPlTzVvx(&TJxv}=bRaD;@z_u_WBB7*M7qV0 zcj;b^5ML9}!Yd%pf;c0%t;x3z-RtN?nL<0cI6B}5WpE;*d>K#%48y|(Y@`Q3lDP`u zXcAhK0?Y+X%t?`Gj>xf+PNuo;@7Hum{qS%Un#+_8g#-3?N@ z$JctDdmv9vE)84^ezG5Uhuv>MLW5{zZzuFv6RU|3n$J$()6oIS*tyloZkR5EP`2KH z84@rYRX>;ju;I1IDly~@o6w)e&k|5sX#lTN9$lwecP?gXPPKJCkQ!lfWo!`n31E_5 z+Gl*an> z{f)i&D=O{?1zB!Fyr2@2t{yZpS(C~Q9q1Bk&UigObiO#T z111I#MdBdtaPv7@SKx4b`~V<2yN=-uMD3FT#>i(tQR5=I5|crCczmI%Ty>rOzCnn* z*ACOj)?$jf9C4$Cj(Do^3cr=N`(wnXgS66bpflA(%1n<>d?OpyBtRq0ceAHwdVD^$ zlpJvazAuyCQr8mrakh;s*jolyh#WGI_-kMH2C}xj8LyK{eNCzwLl7xMmduhlKn~MF zX9?A|;%{|z%*iWiwSRxpE8IT!elibTsUtLDR4Z$?AE%2gVo`*pGHOxxG)mu=q-}yE zZxA=M0+k~P-(7#S3C67Z_=>kaP=-9g$Xw`{wEL`=F9ilI*i?0xJm_qe)&PMdI5kCD zLxSntw}9^kg2L~(S*U#NxF-E*A=3X4BFkiZ(UF{qb!5X^7PXrCFLR+?YY%C=} z^y7(v^cXXq;o)MlK}S`R{(0!d6kKJ$v1QeeicxprKBfBmlAK`t5W^rQK}Vv1;?EI=fg6p9@E?8G;x!`2vOZjnBts%GkTD^+%g4a2iNY<3SeIctMjF}l&J z8Xq4c&9DUQ>r%fUa*bOBu--yPjd}W-luN6Wp$6yf%X6~6$*>*oP+cT_>~|+{5d1mXg9yE@OB&q)F=*TTl%D)z zSk_Nup*<^i61#F#SE{UaYm@j=eDPXQ6xAAa+;A&j*>h`2=^7ZtJY+RPw_rhAn!jP@ zBh0WUjb6tTx_UNCz-O#m!TsF+&q%xe1e;$h(6xthEHoPR4dni*eHj zHRKF)=i9Fw=r7Sj*q58hPhK@x8|guw^(rra{IN&a;8-4AsCZ}TeN3n(Xj<9rLAVb@ zo1V6Hp|;%T%+f~ofhpQSpFzdoD=&$%5c68y z>Tq#wRB61}nDa_Bp@Og}n#MBKtx;OLgPROx4ayMEUd_a-E~!JFYp=8Bc)@Q{n86H7 zi+F$f`%XlJQ{RrdvCE2HT;B1J){M?peU|3>CbnR>Ms=cq40E;ofT)alzB=k=yk>yO z7~!Y+nl_WkLPP@wSmEANw0&$CyJISjb&OxRC<(6x zx=vgLhEOEq;`ymu9Lf~UZi65RtU+-=HwYL=IJ ziWKh`1G|j#4pu9%rcaKGKSSl_*39STsTDainbfeK)}tg;`+qHKR@*LGc9)R7UgUM+StfkETEZ3;gQdenbKi%0+sxYD zh)S`x@a^2C%8qha+^kbd7`jJk$2ac$_;^Nl`L&WC2!@sY1wyH!s`S^d(+>MCg|qtp zlVJtSu;u8{BrntL4w%WWWsb1Cr^I7Y<+J2;cJB@I^U;*@qj-*}wL}r9V+()>(ZPkJ z(8tdoP+VjdhmEO&{q;*_gyjqnxZp}1b5!HQ9(6eYPVt+k*+K+3Ajh88mi1aOl7Xro z_B{|X=oPdo0z;re3h|oI>J9D~*VW6;x=W4%T*PgbnWKAE>P zQ22xscmprEP4|VHPn_xHgZX`R&{dRxcY)Q;40t%)66O1PTABX)FZ)^P&Gk5md#^bT zn?eYq3r5vV*lAXWvAr#*3qY)!h>2YA^kZ&`@B}%YaZ_iTC}~Ey+k&Dw0~=Mx71*%>s&8s>?bF9~4Czv%=j7h6uRo5%FsI#FbE2zX6V*bx8yjR3)Q zn(qN+d$A6?i%An_aXTX1)pURln*(0Iy)?U41?~~0kw(|7!LjG?ooW_~#R8yALEC95 z*2d?XP@iMIPc;Oadz<89N`yQ9mHNl>@{U1Rn)#S74va|kqx%epq(vbx+LjJKGNg(b zaDj$J_%-!}hbR*8D?)~v6;o>7ik~{SIzIC&U6uhD;1-=74Q|VuY`8YAM+|7}A$3t`;mSnz5Cget~S( z_Nc4f8<_tH+dE@Hg;`{KprvMlTOLn~fHCpu$Olvr%4n}zN?=v+e zrbuMhGk^PI2+8Y}LNgELkDN_-CL&m>VF2Qr>J6NbFHyJsE1a!8`rBei1h2fh#4FA! z#=6JDF34?Oo-JjDHiYLK&~4BG)jDVL7qJA!AYXe@HFGgBh0Tz)E9A| zG5EwpGV|OTu?8s8{YN%5O@_5lg4qxO){S5N$p$B51EpUc__5J_56Zna}>X-)Pn6VUAEFOIj-;-j~3U(X#zI;`X# zcOpB}Zks3|lZcgzxlwFZ;!B>pmRqpvR%L99=;ppKEKzrd@%bXjt7wsXc&T8gC=LGt z+hgZIGX#X0;~BYb5UrYG+ugqiNGd zQjmU~jZAe1DyS;NorC@isRSsw;2PBu?-WzS6C$Bb5n5H-i-L1b!O#08VU@=}huK6} ze}mLU@$7A=$ebSSdTe+6n>fT0@k#&Wy25ev8Ch%1??FQ$>(Og`nJNWuJc$S0x>L08 z7{A$7PGGO}`%v;BQ&cYp`aXPHU{l&sM6`UL36w}wtm$QhdyVIe#xCj!Q_Q%!1dVyi zRo?trh0HrL=xpQMLN6Q3y6LS(uyEU%7`;zOspQrJfKKO*B6h4xl!F1x;E^uAy4=(qsE1W8kF3E5Y57i+=YV%vD&_ z(OTQ7+&?}7)>asoO~6c@0W%ftSEd@;*!{5{{Ew>Oc>`ae(QRO=BKe<)HwwkMrF@5m zQdyAr>}Y_FE<|ii@}s((BPiNZdnK)SiJSYVb?EB(KIVu#{cxXV*1JNm??o4y0EBp6 zZREge{LG4kIZ6Dr>(i@^ zn3*r%j=KD1Z#RnlEZDWazwT;lsxn~WkilR#Grc_Txv{@Gn=ZjasB6K5RNhWCmaRqT zCrB40nj5-CVVX$@=8f@7X z1bA7xwYv-@AX#=j!NyAL;EX@m4tu^{{lYIaO>|V?o+CGMPECUmoue-;c*Z0*9=d4c z>wYALcbWeAQvb6ThRsNz*!z}=8`}65@C^UAB-i3nqn`tQ!1mY!04U%de<<+wKo?8n zKh7eJUuEnUIMMx2G(pc_awm>SDjvS(bh8@2>zfCCTF2#zVHF1J!{nLJeY0u0EdX(e zjFgO7y)woikwT)+yPo(TJ@*n;(kj{R`cz1aJUQmP-hCD3i7+NTyRYiIZWysymdVO8 za%opgIm;CxeEXPXvd`l$|k+T~D z8L&!@1t0!toayR&ZU;3dvVCLss}WqUWZ@4FYj=DJ!9z+i<3bpF*&%eZ4;Fa$DzIXt z8xihph2QB0#T<%~BZesNS4@)qlF6fK5#!r({3@@-76X^cf;m&8brLq*mItln0+emcC;EbvFx zEy~QEG2gub;c>f^_{)NePGwV(T@U>D=q~N)<|OSV00-=zY*DrzG7h$$Yzpuo5_7=c_ODQ9k|hr%w@eJ17neO<#&Ak*qPrz+PVLQ`OCA%5}bc|v}mL$eW1JPm>UU+hbbtZHB!TzRicuU2RqX9~$)h48` zWkQl38{Y{Qi+Ajtk5B4GX$d2K(xujpjX2^Q@j6pZ=s}Z0A0mUI(NXPZB_&}lx$&k= z>q%uP-^=*c>k_LrmrBf`c9<60b?)nYGc6pQQx5-8HBO2QT>y0wHzbZ=g}tx$tOHvi zl!z8Gh@p^eOSrgY;Wihy_HwtnF}!!tdmiBx%p*4&*mk=QDMMVDhXt8%`3fk*;v-QXS|` z5JzdJ|oW(6K(d|P&*^SVs5fP*WPvp=r(et7$ZU9@d4>5#AvR`v!|i-o#=1A z{*Fb?9_NyML4mCCCHo?yd=EyzAm+n40{f=Q|$bmU)GY@xj_-%=oA)bCY)-A2tdaG!t< zpTtTR+K+)Hx&?!nefGsKid*l2kQ>?Z!Rn`J;${#12*27|upSD$qpa`W0RI|n|Lb#j zYS@X5*aVlCVn9HyGRP%fAM}RNr8+wJn=^_=N7M zsm(Z|N@p!Q;WOajBkSggc0It7O#jyOUVE?)n7>u8XOnbfU2ZWbhwM6N?Mzx|xukHz z)YZ3UYluHazj4XR$lJXTCp>WGoIzoEZd9}77`Ir-L--MX!Ts&%`2Kg}x%_|#X>DMcfvF_Tcx#sut>W+S^X1cFHIp|+|D(W-A`S|<>w#z@rU?_?C4dmaPC1)!}r?YUry+!khi6#0ntZFOTYE1hvVnB72 zk6cqgQoI_k0^yVlh7tAw?z=q63;IbkT4??k6v}$9$(6+g5HU$d1^vJ+YcG%}l|M#c z(0oThqsj4w!&LlNJs6=J`2LS>FSQojhJ1Vxs6S>3LTMDBe!(i#W(-HA`Q8J5e;oiu z2>#keBb?!ffcCSiWI-#BctNB$)}K|=5qSQHnDZOH2uDI-2#KKIt3QVJ=Z$`jhvdJ9 zc+}O7Cg^v?nJIXWnkgt5C{F_YpRxT5^0Nq!nFtI2pV4PA@})?{HZL4r|1jlkaymq5 z0Zsw;QLYuNu^l)GK*w?E><=G&5vhr?hG9`qteTjSNVmU5UcCbCRMroGYJ@Ww+&vo( zz1n+nBi#2C&*^-dOb}MZgy`G2;ypIG*RcchtB7LKf zV#ds~UH;@2UTA5TGUH*dYnAXoER*+84D4Qw-l2|LtH2X{hg$Q#19L6VNu8v!dyz@l@L=%w_nSp(rc*G^O|- z6TJey>$icwncoHh%$9*_qs=hERWcU7Zmy+OrIX@#+VWko??Oy^+LZ9+n{4Wtwoy&u zIJ9ZoJ4v{EKV&iR)igBv4pj1T)bj`T+(UINGY4;Q^2&la$3pnq8TA9K5)w-qo&D7ykzVi>ooVuvM`Ui@|~l~YO;lb4_*zp^GD88D;8m@HZ4*Zxx60L3XAVV9Ww5@ zZ<-a3OJDCl4Nlzc%w7=9xMV>@4B5C(@yevBhmGGex+E``-!0f}J)8Gq8#g(5nXj;( z8ay|88mGugU{8XKg^y>q;mg&`mmH*jd({^o(nw1AA$5(_rBK zsP^OF`9B+ah!^x=ap|A4hrylxcKt&xvAopZ9sE7l@mF*V_`St1nUB8%|DFW)E3gXu z*8l&P685{N-xGuW^0fy}k^ZkVq2J-ZCmQ?(pGEpN{P(nj-(CFvn&vMTOWc61#iOsH~ep!@bCEFb;G~#1GxXj|E41T?&0qO*yjny+8(1Xaq5E0-f9-;rJOBUy literal 0 HcmV?d00001 diff --git a/tests/test_files/snippets/inline.txt b/tests/test_files/snippets/inline.txt index baf0a7d0..2a4c20fa 100644 --- a/tests/test_files/snippets/inline.txt +++ b/tests/test_files/snippets/inline.txt @@ -1,4 +1,4 @@ - + @@ -6,7 +6,7 @@ - + diff --git a/tests/test_files/sonic.emf b/tests/test_files/sonic.emf new file mode 100644 index 0000000000000000000000000000000000000000..eb336bccf1e65cffa4d164e404185c97e2cb60ed GIT binary patch literal 40 WcmZQ%U|`4rVi<4*GC&vxV0-``m;r(S literal 0 HcmV?d00001 diff --git a/tests/test_package.py b/tests/test_package.py index 4f897997..ac983982 100644 --- a/tests/test_package.py +++ b/tests/test_package.py @@ -1,25 +1,32 @@ -# encoding: utf-8 +# pyright: reportPrivateUsage=false -"""Unit test suite for docx.package module""" +"""Unit test suite for docx.package module.""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import annotations import pytest from docx.image.image import Image -from docx.opc.package import OpcPackage from docx.opc.packuri import PackURI -from docx.opc.rel import Relationships, _Relationship from docx.package import ImageParts, Package from docx.parts.image import ImagePart from .unitutil.file import docx_path -from .unitutil.mock import class_mock, instance_mock, method_mock, property_mock +from .unitutil.mock import ( + FixtureRequest, + Mock, + class_mock, + instance_mock, + method_mock, + property_mock, +) -class DescribePackage(object): +class DescribePackage: + """Unit-test suite for `docx.package.Package`.""" + def it_can_get_or_add_an_image_part_containing_a_specified_image( - self, image_parts_prop_, image_parts_, image_part_ + self, image_parts_prop_: Mock, image_parts_: Mock, image_part_: Mock ): image_parts_prop_.return_value = image_parts_ image_parts_.get_or_add_image_part.return_value = image_part_ @@ -32,29 +39,36 @@ def it_can_get_or_add_an_image_part_containing_a_specified_image( def it_gathers_package_image_parts_after_unmarshalling(self): package = Package.open(docx_path("having-images")) + image_parts = package.image_parts + assert len(image_parts) == 3 - for image_part in image_parts: - assert isinstance(image_part, ImagePart) + assert all(isinstance(p, ImagePart) for p in image_parts) # fixture components --------------------------------------------- @pytest.fixture - def image_part_(self, request): + def image_part_(self, request: FixtureRequest): return instance_mock(request, ImagePart) @pytest.fixture - def image_parts_(self, request): + def image_parts_(self, request: FixtureRequest): return instance_mock(request, ImageParts) @pytest.fixture - def image_parts_prop_(self, request): + def image_parts_prop_(self, request: FixtureRequest): return property_mock(request, Package, "image_parts") -class DescribeImageParts(object): +class DescribeImageParts: + """Unit-test suite for `docx.package.Package`.""" + def it_can_get_a_matching_image_part( - self, Image_, image_, _get_by_sha1_, image_part_ + self, + Image_: Mock, + image_: Mock, + _get_by_sha1_: Mock, + image_part_: Mock, ): Image_.from_file.return_value = image_ image_.sha1 = "f005ba11" @@ -68,7 +82,12 @@ def it_can_get_a_matching_image_part( assert image_part is image_part_ def but_it_adds_a_new_image_part_when_match_fails( - self, Image_, image_, _get_by_sha1_, _add_image_part_, image_part_ + self, + Image_: Mock, + image_: Mock, + _get_by_sha1_: Mock, + _add_image_part_: Mock, + image_part_: Mock, ): Image_.from_file.return_value = image_ image_.sha1 = "fa1afe1" @@ -83,101 +102,74 @@ def but_it_adds_a_new_image_part_when_match_fails( _add_image_part_.assert_called_once_with(image_parts, image_) assert image_part is image_part_ - def it_knows_the_next_available_image_partname(self, next_partname_fixture): - image_parts, ext, expected_partname = next_partname_fixture - assert image_parts._next_image_partname(ext) == expected_partname + @pytest.mark.parametrize( + ("existing_partname_numbers", "expected_partname_number"), + [ + ((2, 3), 1), + ((1, 3), 2), + ((1, 2), 3), + ], + ) + def it_knows_the_next_available_image_partname( + self, + request: FixtureRequest, + existing_partname_numbers: tuple[int, int], + expected_partname_number: int, + ): + image_parts = ImageParts() + for n in existing_partname_numbers: + image_parts.append( + instance_mock(request, ImagePart, partname=PackURI(f"/word/media/image{n}.png")) + ) - def it_can_really_add_a_new_image_part( - self, _next_image_partname_, partname_, image_, ImagePart_, image_part_ + next_partname = image_parts._next_image_partname("png") + + assert next_partname == PackURI("/word/media/image%d.png" % expected_partname_number) + + def it_can_add_a_new_image_part( + self, + _next_image_partname_: Mock, + image_: Mock, + ImagePart_: Mock, + image_part_: Mock, ): - _next_image_partname_.return_value = partname_ + partname = PackURI("/word/media/image7.png") + _next_image_partname_.return_value = partname ImagePart_.from_image.return_value = image_part_ image_parts = ImageParts() image_part = image_parts._add_image_part(image_) - ImagePart_.from_image.assert_called_once_with(image_, partname_) + ImagePart_.from_image.assert_called_once_with(image_, partname) assert image_part in image_parts assert image_part is image_part_ # fixtures ------------------------------------------------------- - @pytest.fixture(params=[((2, 3), 1), ((1, 3), 2), ((1, 2), 3)]) - def next_partname_fixture(self, request): - def image_part_with_partname_(n): - partname = image_partname(n) - return instance_mock(request, ImagePart, partname=partname) - - def image_partname(n): - return PackURI("/word/media/image%d.png" % n) - - existing_partname_numbers, expected_partname_number = request.param - image_parts = ImageParts() - for n in existing_partname_numbers: - image_part_ = image_part_with_partname_(n) - image_parts.append(image_part_) - ext = "png" - expected_image_partname = image_partname(expected_partname_number) - return image_parts, ext, expected_image_partname - - # fixture components --------------------------------------------- - @pytest.fixture - def _add_image_part_(self, request): + def _add_image_part_(self, request: FixtureRequest): return method_mock(request, ImageParts, "_add_image_part") @pytest.fixture - def _get_by_sha1_(self, request): + def _get_by_sha1_(self, request: FixtureRequest): return method_mock(request, ImageParts, "_get_by_sha1") @pytest.fixture - def Image_(self, request): + def Image_(self, request: FixtureRequest): return class_mock(request, "docx.package.Image") @pytest.fixture - def image_(self, request): + def image_(self, request: FixtureRequest): return instance_mock(request, Image) @pytest.fixture - def ImagePart_(self, request): + def ImagePart_(self, request: FixtureRequest): return class_mock(request, "docx.package.ImagePart") @pytest.fixture - def image_part_(self, request): + def image_part_(self, request: FixtureRequest): return instance_mock(request, ImagePart) @pytest.fixture - def _next_image_partname_(self, request): + def _next_image_partname_(self, request: FixtureRequest): return method_mock(request, ImageParts, "_next_image_partname") - - @pytest.fixture - def partname_(self, request): - return instance_mock(request, PackURI) - - -class TestOpcPackage: - def test_drop_rels(self, package_with_rels): - def cmp(rel): - return "2" in rel.reltype - - ret = package_with_rels.drop_rels(cmp) - assert len(package_with_rels.rels) == 2 - assert package_with_rels.rels["rId3"].reltype == "reltype3" - assert ret == ["rId2"] - - @pytest.fixture - def package_with_rels(self, mocker, rels): - mocker.patch( - "docx.opc.package.OpcPackage.rels", - new_callable=mocker.PropertyMock, - return_value=rels, - ) - return OpcPackage() - - @pytest.fixture - def rels(self): - rels = Relationships(None) - rels["rId1"] = _Relationship("rId1", "reltype1", "target1", "base1") - rels["rId2"] = _Relationship("rId2", "reltype2", "target2", "base2") - rels["rId3"] = _Relationship("rId3", "reltype3", "target3", "base3") - return rels diff --git a/tests/test_section.py b/tests/test_section.py index ae887a96..54d66576 100644 --- a/tests/test_section.py +++ b/tests/test_section.py @@ -1,37 +1,58 @@ -# encoding: utf-8 +# pyright: reportPrivateUsage=false -"""Unit test suite for the docx.section module""" +"""Unit test suite for the docx.section module.""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import annotations + +from typing import cast import pytest -from docx.enum.section import WD_HEADER_FOOTER, WD_ORIENT, WD_SECTION +from docx import Document +from docx.enum.section import WD_HEADER_FOOTER, WD_ORIENTATION, WD_SECTION +from docx.oxml.document import CT_Document +from docx.oxml.section import CT_SectPr from docx.parts.document import DocumentPart from docx.parts.hdrftr import FooterPart, HeaderPart -from docx.section import _BaseHeaderFooter, _Footer, _Header, Section, Sections -from docx.shared import Inches +from docx.section import Section, Sections, _BaseHeaderFooter, _Footer, _Header +from docx.shared import Inches, Length +from docx.table import Table +from docx.text.paragraph import Paragraph from .unitutil.cxml import element, xml -from .unitutil.mock import call, class_mock, instance_mock, method_mock, property_mock - - -class DescribeSections(object): - def it_knows_how_many_sections_it_contains(self): - sections = Sections( - element("w:document/w:body/(w:p/w:pPr/w:sectPr, w:sectPr)"), None +from .unitutil.file import test_file +from .unitutil.mock import ( + FixtureRequest, + Mock, + call, + class_mock, + instance_mock, + method_mock, + property_mock, +) + + +class DescribeSections: + """Unit-test suite for `docx.section.Sections`.""" + + def it_knows_how_many_sections_it_contains(self, document_part_: Mock): + document_elm = cast( + CT_Document, element("w:document/w:body/(w:p/w:pPr/w:sectPr, w:sectPr)") ) + sections = Sections(document_elm, document_part_) assert len(sections) == 2 def it_can_iterate_over_its_Section_instances( - self, Section_, section_, document_part_ + self, Section_: Mock, section_: Mock, document_part_: Mock ): - document_elm = element("w:document/w:body/(w:p/w:pPr/w:sectPr, w:sectPr)") + document_elm = cast( + CT_Document, element("w:document/w:body/(w:p/w:pPr/w:sectPr, w:sectPr)") + ) sectPrs = document_elm.xpath("//w:sectPr") Section_.return_value = section_ sections = Sections(document_elm, document_part_) - section_lst = [s for s in sections] + section_lst = list(sections) assert Section_.call_args_list == [ call(sectPrs[0], document_part_), @@ -40,10 +61,11 @@ def it_can_iterate_over_its_Section_instances( assert section_lst == [section_, section_] def it_can_access_its_Section_instances_by_index( - self, Section_, section_, document_part_ + self, Section_: Mock, section_: Mock, document_part_: Mock ): - document_elm = element( - "w:document/w:body/(w:p/w:pPr/w:sectPr,w:p/w:pPr/w:sectPr,w:sectPr)" + document_elm = cast( + CT_Document, + element("w:document/w:body/(w:p/w:pPr/w:sectPr,w:p/w:pPr/w:sectPr,w:sectPr)"), ) sectPrs = document_elm.xpath("//w:sectPr") Section_.return_value = section_ @@ -59,10 +81,11 @@ def it_can_access_its_Section_instances_by_index( assert section_lst == [section_, section_, section_] def it_can_access_its_Section_instances_by_slice( - self, Section_, section_, document_part_ + self, Section_: Mock, section_: Mock, document_part_: Mock ): - document_elm = element( - "w:document/w:body/(w:p/w:pPr/w:sectPr,w:p/w:pPr/w:sectPr,w:sectPr)" + document_elm = cast( + CT_Document, + element("w:document/w:body/(w:p/w:pPr/w:sectPr,w:p/w:pPr/w:sectPr,w:sectPr)"), ) sectPrs = document_elm.xpath("//w:sectPr") Section_.return_value = section_ @@ -76,238 +99,352 @@ def it_can_access_its_Section_instances_by_slice( ] assert section_lst == [section_, section_] - # fixture components --------------------------------------------- + # -- fixtures--------------------------------------------------------------------------------- @pytest.fixture - def document_part_(self, request): + def document_part_(self, request: FixtureRequest): return instance_mock(request, DocumentPart) @pytest.fixture - def Section_(self, request): + def Section_(self, request: FixtureRequest): return class_mock(request, "docx.section.Section") @pytest.fixture - def section_(self, request): + def section_(self, request: FixtureRequest): return instance_mock(request, Section) -class DescribeSection(object): +class DescribeSection: + """Unit-test suite for `docx.section.Section`.""" + + @pytest.mark.parametrize( + ("sectPr_cxml", "expected_value"), + [ + ("w:sectPr", False), + ("w:sectPr/w:titlePg", True), + ("w:sectPr/w:titlePg{w:val=0}", False), + ("w:sectPr/w:titlePg{w:val=1}", True), + ("w:sectPr/w:titlePg{w:val=true}", True), + ], + ) def it_knows_when_it_displays_a_distinct_first_page_header( - self, diff_first_header_get_fixture + self, sectPr_cxml: str, expected_value: bool, document_part_: Mock ): - sectPr, expected_value = diff_first_header_get_fixture - section = Section(sectPr, None) + sectPr = cast(CT_SectPr, element(sectPr_cxml)) + section = Section(sectPr, document_part_) different_first_page_header_footer = section.different_first_page_header_footer assert different_first_page_header_footer is expected_value + @pytest.mark.parametrize( + ("sectPr_cxml", "value", "expected_cxml"), + [ + ("w:sectPr", True, "w:sectPr/w:titlePg"), + ("w:sectPr/w:titlePg", False, "w:sectPr"), + ("w:sectPr/w:titlePg{w:val=1}", True, "w:sectPr/w:titlePg"), + ("w:sectPr/w:titlePg{w:val=off}", False, "w:sectPr"), + ], + ) def it_can_change_whether_the_document_has_distinct_odd_and_even_headers( - self, diff_first_header_set_fixture + self, sectPr_cxml: str, value: bool, expected_cxml: str, document_part_: Mock ): - sectPr, value, expected_xml = diff_first_header_set_fixture - section = Section(sectPr, None) + sectPr = cast(CT_SectPr, element(sectPr_cxml)) + expected_xml = xml(expected_cxml) + section = Section(sectPr, document_part_) section.different_first_page_header_footer = value assert sectPr.xml == expected_xml def it_provides_access_to_its_even_page_footer( - self, document_part_, _Footer_, footer_ + self, document_part_: Mock, _Footer_: Mock, footer_: Mock ): - sectPr = element("w:sectPr") + sectPr = cast(CT_SectPr, element("w:sectPr")) _Footer_.return_value = footer_ section = Section(sectPr, document_part_) footer = section.even_page_footer - _Footer_.assert_called_once_with( - sectPr, document_part_, WD_HEADER_FOOTER.EVEN_PAGE - ) + _Footer_.assert_called_once_with(sectPr, document_part_, WD_HEADER_FOOTER.EVEN_PAGE) assert footer is footer_ def it_provides_access_to_its_even_page_header( - self, document_part_, _Header_, header_ + self, document_part_: Mock, _Header_: Mock, header_: Mock ): - sectPr = element("w:sectPr") + sectPr = cast(CT_SectPr, element("w:sectPr")) _Header_.return_value = header_ section = Section(sectPr, document_part_) header = section.even_page_header - _Header_.assert_called_once_with( - sectPr, document_part_, WD_HEADER_FOOTER.EVEN_PAGE - ) + _Header_.assert_called_once_with(sectPr, document_part_, WD_HEADER_FOOTER.EVEN_PAGE) assert header is header_ def it_provides_access_to_its_first_page_footer( - self, document_part_, _Footer_, footer_ + self, document_part_: Mock, _Footer_: Mock, footer_: Mock ): - sectPr = element("w:sectPr") + sectPr = cast(CT_SectPr, element("w:sectPr")) _Footer_.return_value = footer_ section = Section(sectPr, document_part_) footer = section.first_page_footer - _Footer_.assert_called_once_with( - sectPr, document_part_, WD_HEADER_FOOTER.FIRST_PAGE - ) + _Footer_.assert_called_once_with(sectPr, document_part_, WD_HEADER_FOOTER.FIRST_PAGE) assert footer is footer_ def it_provides_access_to_its_first_page_header( - self, document_part_, _Header_, header_ + self, document_part_: Mock, _Header_: Mock, header_: Mock ): - sectPr = element("w:sectPr") + sectPr = cast(CT_SectPr, element("w:sectPr")) _Header_.return_value = header_ section = Section(sectPr, document_part_) header = section.first_page_header - _Header_.assert_called_once_with( - sectPr, document_part_, WD_HEADER_FOOTER.FIRST_PAGE - ) + _Header_.assert_called_once_with(sectPr, document_part_, WD_HEADER_FOOTER.FIRST_PAGE) assert header is header_ def it_provides_access_to_its_default_footer( - self, document_part_, _Footer_, footer_ + self, document_part_: Mock, _Footer_: Mock, footer_: Mock ): - sectPr = element("w:sectPr") + sectPr = cast(CT_SectPr, element("w:sectPr")) _Footer_.return_value = footer_ section = Section(sectPr, document_part_) footer = section.footer - _Footer_.assert_called_once_with( - sectPr, document_part_, WD_HEADER_FOOTER.PRIMARY - ) + _Footer_.assert_called_once_with(sectPr, document_part_, WD_HEADER_FOOTER.PRIMARY) assert footer is footer_ def it_provides_access_to_its_default_header( - self, document_part_, _Header_, header_ + self, document_part_: Mock, _Header_: Mock, header_: Mock ): - sectPr = element("w:sectPr") + sectPr = cast(CT_SectPr, element("w:sectPr")) _Header_.return_value = header_ section = Section(sectPr, document_part_) header = section.header - _Header_.assert_called_once_with( - sectPr, document_part_, WD_HEADER_FOOTER.PRIMARY - ) + _Header_.assert_called_once_with(sectPr, document_part_, WD_HEADER_FOOTER.PRIMARY) assert header is header_ - def it_knows_its_start_type(self, start_type_get_fixture): - sectPr, expected_start_type = start_type_get_fixture - section = Section(sectPr, None) + def it_can_iterate_its_inner_content(self): + document = Document(test_file("sct-inner-content.docx")) + + assert len(document.sections) == 3 + + inner_content = list(document.sections[0].iter_inner_content()) + + assert len(inner_content) == 3 + p = inner_content[0] + assert isinstance(p, Paragraph) + assert p.text == "P1" + t = inner_content[1] + assert isinstance(t, Table) + assert t.rows[0].cells[0].text == "T2" + p = inner_content[2] + assert isinstance(p, Paragraph) + assert p.text == "P3" + + inner_content = list(document.sections[1].iter_inner_content()) + + assert len(inner_content) == 3 + t = inner_content[0] + assert isinstance(t, Table) + assert t.rows[0].cells[0].text == "T4" + p = inner_content[1] + assert isinstance(p, Paragraph) + assert p.text == "P5" + p = inner_content[2] + assert isinstance(p, Paragraph) + assert p.text == "P6" + + inner_content = list(document.sections[2].iter_inner_content()) + + assert len(inner_content) == 3 + p = inner_content[0] + assert isinstance(p, Paragraph) + assert p.text == "P7" + p = inner_content[1] + assert isinstance(p, Paragraph) + assert p.text == "P8" + p = inner_content[2] + assert isinstance(p, Paragraph) + assert p.text == "P9" + + @pytest.mark.parametrize( + ("sectPr_cxml", "expected_value"), + [ + ("w:sectPr", WD_SECTION.NEW_PAGE), + ("w:sectPr/w:type", WD_SECTION.NEW_PAGE), + ("w:sectPr/w:type{w:val=continuous}", WD_SECTION.CONTINUOUS), + ("w:sectPr/w:type{w:val=nextPage}", WD_SECTION.NEW_PAGE), + ("w:sectPr/w:type{w:val=oddPage}", WD_SECTION.ODD_PAGE), + ("w:sectPr/w:type{w:val=evenPage}", WD_SECTION.EVEN_PAGE), + ("w:sectPr/w:type{w:val=nextColumn}", WD_SECTION.NEW_COLUMN), + ], + ) + def it_knows_its_start_type( + self, sectPr_cxml: str, expected_value: WD_SECTION, document_part_: Mock + ): + sectPr = cast(CT_SectPr, element(sectPr_cxml)) + section = Section(sectPr, document_part_) start_type = section.start_type - assert start_type is expected_start_type + assert start_type is expected_value - def it_can_change_its_start_type(self, start_type_set_fixture): - sectPr, new_start_type, expected_xml = start_type_set_fixture - section = Section(sectPr, None) + @pytest.mark.parametrize( + ("sectPr_cxml", "value", "expected_cxml"), + [ + ( + "w:sectPr/w:type{w:val=oddPage}", + WD_SECTION.EVEN_PAGE, + "w:sectPr/w:type{w:val=evenPage}", + ), + ("w:sectPr/w:type{w:val=nextPage}", None, "w:sectPr"), + ("w:sectPr", None, "w:sectPr"), + ("w:sectPr/w:type{w:val=continuous}", WD_SECTION.NEW_PAGE, "w:sectPr"), + ("w:sectPr/w:type", WD_SECTION.NEW_PAGE, "w:sectPr"), + ( + "w:sectPr/w:type", + WD_SECTION.NEW_COLUMN, + "w:sectPr/w:type{w:val=nextColumn}", + ), + ], + ) + def it_can_change_its_start_type( + self, + sectPr_cxml: str, + value: WD_SECTION | None, + expected_cxml: str, + document_part_: Mock, + ): + sectPr = cast(CT_SectPr, element(sectPr_cxml)) + expected_xml = xml(expected_cxml) + section = Section(sectPr, document_part_) - section.start_type = new_start_type + section.start_type = value assert section._sectPr.xml == expected_xml - def it_knows_its_page_width(self, page_width_get_fixture): - sectPr, expected_page_width = page_width_get_fixture - section = Section(sectPr, None) + @pytest.mark.parametrize( + ("sectPr_cxml", "expected_value"), + [ + ("w:sectPr/w:pgSz{w:w=1440}", Inches(1)), + ("w:sectPr/w:pgSz", None), + ("w:sectPr", None), + ], + ) + def it_knows_its_page_width( + self, sectPr_cxml: str, expected_value: Length | None, document_part_: Mock + ): + sectPr = cast(CT_SectPr, element(sectPr_cxml)) + section = Section(sectPr, document_part_) page_width = section.page_width - assert page_width == expected_page_width + assert page_width == expected_value - def it_can_change_its_page_width(self, page_width_set_fixture): - sectPr, new_page_width, expected_xml = page_width_set_fixture - section = Section(sectPr, None) + @pytest.mark.parametrize( + ("value", "expected_cxml"), + [ + (None, "w:sectPr/w:pgSz"), + (Inches(4), "w:sectPr/w:pgSz{w:w=5760}"), + ], + ) + def it_can_change_its_page_width( + self, + value: Length | None, + expected_cxml: str, + document_part_: Mock, + ): + sectPr = cast(CT_SectPr, element("w:sectPr")) + expected_xml = xml(expected_cxml) + section = Section(sectPr, document_part_) - section.page_width = new_page_width + section.page_width = value assert section._sectPr.xml == expected_xml - def it_knows_its_page_height(self, page_height_get_fixture): - sectPr, expected_page_height = page_height_get_fixture - section = Section(sectPr, None) + @pytest.mark.parametrize( + ("sectPr_cxml", "expected_value"), + [ + ("w:sectPr/w:pgSz{w:h=2880}", Inches(2)), + ("w:sectPr/w:pgSz", None), + ("w:sectPr", None), + ], + ) + def it_knows_its_page_height( + self, sectPr_cxml: str, expected_value: Length | None, document_part_: Mock + ): + sectPr = cast(CT_SectPr, element(sectPr_cxml)) + section = Section(sectPr, document_part_) page_height = section.page_height - assert page_height == expected_page_height + assert page_height == expected_value - def it_can_change_its_page_height(self, page_height_set_fixture): - sectPr, new_page_height, expected_xml = page_height_set_fixture - section = Section(sectPr, None) + @pytest.mark.parametrize( + ("value", "expected_cxml"), + [ + (None, "w:sectPr/w:pgSz"), + (Inches(2), "w:sectPr/w:pgSz{w:h=2880}"), + ], + ) + def it_can_change_its_page_height( + self, value: Length | None, expected_cxml: str, document_part_: Mock + ): + sectPr = cast(CT_SectPr, element("w:sectPr")) + expected_xml = xml(expected_cxml) + section = Section(sectPr, document_part_) - section.page_height = new_page_height + section.page_height = value assert section._sectPr.xml == expected_xml - def it_knows_its_page_orientation(self, orientation_get_fixture): - sectPr, expected_orientation = orientation_get_fixture - section = Section(sectPr, None) + @pytest.mark.parametrize( + ("sectPr_cxml", "expected_value"), + [ + ("w:sectPr/w:pgSz{w:orient=landscape}", WD_ORIENTATION.LANDSCAPE), + ("w:sectPr/w:pgSz{w:orient=portrait}", WD_ORIENTATION.PORTRAIT), + ("w:sectPr/w:pgSz", WD_ORIENTATION.PORTRAIT), + ("w:sectPr", WD_ORIENTATION.PORTRAIT), + ], + ) + def it_knows_its_page_orientation( + self, sectPr_cxml: str, expected_value: WD_ORIENTATION, document_part_: Mock + ): + sectPr = cast(CT_SectPr, element(sectPr_cxml)) + section = Section(sectPr, document_part_) orientation = section.orientation - assert orientation is expected_orientation - - def it_can_change_its_orientation(self, orientation_set_fixture): - sectPr, new_orientation, expected_xml = orientation_set_fixture - section = Section(sectPr, None) - - section.orientation = new_orientation - - assert section._sectPr.xml == expected_xml - - def it_knows_its_page_margins(self, margins_get_fixture): - sectPr, margin_prop_name, expected_value = margins_get_fixture - section = Section(sectPr, None) - - value = getattr(section, margin_prop_name) - - assert value == expected_value + assert orientation is expected_value - def it_can_change_its_page_margins(self, margins_set_fixture): - sectPr, margin_prop_name, new_value, expected_xml = margins_set_fixture - section = Section(sectPr, None) + @pytest.mark.parametrize( + ("value", "expected_cxml"), + [ + (WD_ORIENTATION.LANDSCAPE, "w:sectPr/w:pgSz{w:orient=landscape}"), + (WD_ORIENTATION.PORTRAIT, "w:sectPr/w:pgSz"), + (None, "w:sectPr/w:pgSz"), + ], + ) + def it_can_change_its_orientation( + self, value: WD_ORIENTATION | None, expected_cxml: str, document_part_: Mock + ): + sectPr = cast(CT_SectPr, element("w:sectPr")) + expected_xml = xml(expected_cxml) + section = Section(sectPr, document_part_) - setattr(section, margin_prop_name, new_value) + section.orientation = value assert section._sectPr.xml == expected_xml - # fixtures ------------------------------------------------------- - - @pytest.fixture( - params=[ - ("w:sectPr", False), - ("w:sectPr/w:titlePg", True), - ("w:sectPr/w:titlePg{w:val=0}", False), - ("w:sectPr/w:titlePg{w:val=1}", True), - ("w:sectPr/w:titlePg{w:val=true}", True), - ] - ) - def diff_first_header_get_fixture(self, request): - sectPr_cxml, expected_value = request.param - sectPr = element(sectPr_cxml) - return sectPr, expected_value - - @pytest.fixture( - params=[ - ("w:sectPr", True, "w:sectPr/w:titlePg"), - ("w:sectPr/w:titlePg", False, "w:sectPr"), - ("w:sectPr/w:titlePg{w:val=1}", True, "w:sectPr/w:titlePg"), - ("w:sectPr/w:titlePg{w:val=off}", False, "w:sectPr"), - ] - ) - def diff_first_header_set_fixture(self, request): - sectPr_cxml, value, expected_cxml = request.param - sectPr = element(sectPr_cxml) - expected_xml = xml(expected_cxml) - return sectPr, value, expected_xml - - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("sectPr_cxml", "margin_prop_name", "expected_value"), + [ ("w:sectPr/w:pgMar{w:left=120}", "left_margin", 76200), ("w:sectPr/w:pgMar{w:right=240}", "right_margin", 152400), ("w:sectPr/w:pgMar{w:top=-360}", "top_margin", -228600), @@ -317,15 +454,25 @@ def diff_first_header_set_fixture(self, request): ("w:sectPr/w:pgMar{w:footer=840}", "footer_distance", 533400), ("w:sectPr/w:pgMar", "left_margin", None), ("w:sectPr", "top_margin", None), - ] + ], ) - def margins_get_fixture(self, request): - sectPr_cxml, margin_prop_name, expected_value = request.param - sectPr = element(sectPr_cxml) - return sectPr, margin_prop_name, expected_value + def it_knows_its_page_margins( + self, + sectPr_cxml: str, + margin_prop_name: str, + expected_value: int | None, + document_part_: Mock, + ): + sectPr = cast(CT_SectPr, element(sectPr_cxml)) + section = Section(sectPr, document_part_) + + value = getattr(section, margin_prop_name) - @pytest.fixture( - params=[ + assert value == expected_value + + @pytest.mark.parametrize( + ("sectPr_cxml", "margin_prop_name", "value", "expected_cxml"), + [ ("w:sectPr", "left_margin", Inches(1), "w:sectPr/w:pgMar{w:left=1440}"), ("w:sectPr", "right_margin", Inches(0.5), "w:sectPr/w:pgMar{w:right=720}"), ("w:sectPr", "top_margin", Inches(-0.25), "w:sectPr/w:pgMar{w:top=-360}"), @@ -355,185 +502,93 @@ def margins_get_fixture(self, request): Inches(0.6), "w:sectPr/w:pgMar{w:top=864}", ), - ] - ) - def margins_set_fixture(self, request): - sectPr_cxml, property_name, new_value, expected_cxml = request.param - sectPr = element(sectPr_cxml) - expected_xml = xml(expected_cxml) - return sectPr, property_name, new_value, expected_xml - - @pytest.fixture( - params=[ - ("w:sectPr/w:pgSz{w:orient=landscape}", WD_ORIENT.LANDSCAPE), - ("w:sectPr/w:pgSz{w:orient=portrait}", WD_ORIENT.PORTRAIT), - ("w:sectPr/w:pgSz", WD_ORIENT.PORTRAIT), - ("w:sectPr", WD_ORIENT.PORTRAIT), - ] - ) - def orientation_get_fixture(self, request): - sectPr_cxml, expected_orientation = request.param - sectPr = element(sectPr_cxml) - return sectPr, expected_orientation - - @pytest.fixture( - params=[ - (WD_ORIENT.LANDSCAPE, "w:sectPr/w:pgSz{w:orient=landscape}"), - (WD_ORIENT.PORTRAIT, "w:sectPr/w:pgSz"), - (None, "w:sectPr/w:pgSz"), - ] - ) - def orientation_set_fixture(self, request): - new_orientation, expected_cxml = request.param - sectPr = element("w:sectPr") - expected_xml = xml(expected_cxml) - return sectPr, new_orientation, expected_xml - - @pytest.fixture( - params=[ - ("w:sectPr/w:pgSz{w:h=2880}", Inches(2)), - ("w:sectPr/w:pgSz", None), - ("w:sectPr", None), - ] - ) - def page_height_get_fixture(self, request): - sectPr_cxml, expected_page_height = request.param - sectPr = element(sectPr_cxml) - return sectPr, expected_page_height - - @pytest.fixture( - params=[ - (None, "w:sectPr/w:pgSz"), - (Inches(2), "w:sectPr/w:pgSz{w:h=2880}"), - ] - ) - def page_height_set_fixture(self, request): - new_page_height, expected_cxml = request.param - sectPr = element("w:sectPr") - expected_xml = xml(expected_cxml) - return sectPr, new_page_height, expected_xml - - @pytest.fixture( - params=[ - ("w:sectPr/w:pgSz{w:w=1440}", Inches(1)), - ("w:sectPr/w:pgSz", None), - ("w:sectPr", None), - ] - ) - def page_width_get_fixture(self, request): - sectPr_cxml, expected_page_width = request.param - sectPr = element(sectPr_cxml) - return sectPr, expected_page_width - - @pytest.fixture( - params=[ - (None, "w:sectPr/w:pgSz"), - (Inches(4), "w:sectPr/w:pgSz{w:w=5760}"), - ] + ], ) - def page_width_set_fixture(self, request): - new_page_width, expected_cxml = request.param - sectPr = element("w:sectPr") + def it_can_change_its_page_margins( + self, + sectPr_cxml: str, + margin_prop_name: str, + value: Length | None, + expected_cxml: str, + document_part_: Mock, + ): + sectPr = cast(CT_SectPr, element(sectPr_cxml)) expected_xml = xml(expected_cxml) - return sectPr, new_page_width, expected_xml + section = Section(sectPr, document_part_) - @pytest.fixture( - params=[ - ("w:sectPr", WD_SECTION.NEW_PAGE), - ("w:sectPr/w:type", WD_SECTION.NEW_PAGE), - ("w:sectPr/w:type{w:val=continuous}", WD_SECTION.CONTINUOUS), - ("w:sectPr/w:type{w:val=nextPage}", WD_SECTION.NEW_PAGE), - ("w:sectPr/w:type{w:val=oddPage}", WD_SECTION.ODD_PAGE), - ("w:sectPr/w:type{w:val=evenPage}", WD_SECTION.EVEN_PAGE), - ("w:sectPr/w:type{w:val=nextColumn}", WD_SECTION.NEW_COLUMN), - ] - ) - def start_type_get_fixture(self, request): - sectPr_cxml, expected_start_type = request.param - sectPr = element(sectPr_cxml) - return sectPr, expected_start_type + setattr(section, margin_prop_name, value) - @pytest.fixture( - params=[ - ( - "w:sectPr/w:type{w:val=oddPage}", - WD_SECTION.EVEN_PAGE, - "w:sectPr/w:type{w:val=evenPage}", - ), - ("w:sectPr/w:type{w:val=nextPage}", None, "w:sectPr"), - ("w:sectPr", None, "w:sectPr"), - ("w:sectPr/w:type{w:val=continuous}", WD_SECTION.NEW_PAGE, "w:sectPr"), - ("w:sectPr/w:type", WD_SECTION.NEW_PAGE, "w:sectPr"), - ( - "w:sectPr/w:type", - WD_SECTION.NEW_COLUMN, - "w:sectPr/w:type{w:val=nextColumn}", - ), - ] - ) - def start_type_set_fixture(self, request): - initial_cxml, new_start_type, expected_cxml = request.param - sectPr = element(initial_cxml) - expected_xml = xml(expected_cxml) - return sectPr, new_start_type, expected_xml + assert section._sectPr.xml == expected_xml - # fixture components --------------------------------------------- + # -- fixtures----------------------------------------------------- @pytest.fixture - def document_part_(self, request): + def document_part_(self, request: FixtureRequest): return instance_mock(request, DocumentPart) @pytest.fixture - def _Footer_(self, request): + def _Footer_(self, request: FixtureRequest): return class_mock(request, "docx.section._Footer") @pytest.fixture - def footer_(self, request): + def footer_(self, request: FixtureRequest): return instance_mock(request, _Footer) @pytest.fixture - def _Header_(self, request): + def _Header_(self, request: FixtureRequest): return class_mock(request, "docx.section._Header") @pytest.fixture - def header_(self, request): + def header_(self, request: FixtureRequest): return instance_mock(request, _Header) -class Describe_BaseHeaderFooter(object): +class Describe_BaseHeaderFooter: + """Unit-test suite for `docx.section._BaseHeaderFooter`.""" + + @pytest.mark.parametrize(("has_definition", "expected_value"), [(False, True), (True, False)]) def it_knows_when_its_linked_to_the_previous_header_or_footer( - self, is_linked_get_fixture, _has_definition_prop_ + self, + has_definition: bool, + expected_value: bool, + header: _BaseHeaderFooter, + _has_definition_prop_: Mock, ): - has_definition, expected_value = is_linked_get_fixture _has_definition_prop_.return_value = has_definition - header = _BaseHeaderFooter(None, None, None) - - is_linked = header.is_linked_to_previous - - assert is_linked is expected_value + assert header.is_linked_to_previous is expected_value + @pytest.mark.parametrize( + ("has_definition", "value", "drop_calls", "add_calls"), + [ + (False, True, 0, 0), + (True, False, 0, 0), + (True, True, 1, 0), + (False, False, 0, 1), + ], + ) def it_can_change_whether_it_is_linked_to_previous_header_or_footer( self, - is_linked_set_fixture, - _has_definition_prop_, - _drop_definition_, - _add_definition_, + has_definition: bool, + value: bool, + drop_calls: int, + add_calls: int, + header: _BaseHeaderFooter, + _has_definition_prop_: Mock, + _drop_definition_: Mock, + _add_definition_: Mock, ): - has_definition, new_value, drop_calls, add_calls = is_linked_set_fixture _has_definition_prop_.return_value = has_definition - header = _BaseHeaderFooter(None, None, None) - header.is_linked_to_previous = new_value + header.is_linked_to_previous = value assert _drop_definition_.call_args_list == [call(header)] * drop_calls assert _add_definition_.call_args_list == [call(header)] * add_calls def it_provides_access_to_the_header_or_footer_part_for_BlockItemContainer( - self, _get_or_add_definition_, header_part_ + self, header: _BaseHeaderFooter, _get_or_add_definition_: Mock, header_part_: Mock ): # ---this override fulfills part of the BlockItemContainer subclass interface--- _get_or_add_definition_.return_value = header_part_ - header = _BaseHeaderFooter(None, None, None) header_part = header.part @@ -541,12 +596,11 @@ def it_provides_access_to_the_header_or_footer_part_for_BlockItemContainer( assert header_part is header_part_ def it_provides_access_to_the_hdr_or_ftr_element_to_help( - self, _get_or_add_definition_, header_part_ + self, header: _BaseHeaderFooter, _get_or_add_definition_: Mock, header_part_: Mock ): hdr = element("w:hdr") _get_or_add_definition_.return_value = header_part_ header_part_.element = hdr - header = _BaseHeaderFooter(None, None, None) hdr_elm = header._element @@ -554,11 +608,14 @@ def it_provides_access_to_the_hdr_or_ftr_element_to_help( assert hdr_elm is hdr def it_gets_the_definition_when_it_has_one( - self, _has_definition_prop_, _definition_prop_, header_part_ + self, + header: _BaseHeaderFooter, + _has_definition_prop_: Mock, + _definition_prop_: Mock, + header_part_: Mock, ): _has_definition_prop_.return_value = True _definition_prop_.return_value = header_part_ - header = _BaseHeaderFooter(None, None, None) header_part = header._get_or_add_definition() @@ -566,15 +623,15 @@ def it_gets_the_definition_when_it_has_one( def but_it_gets_the_prior_definition_when_it_is_linked( self, - _has_definition_prop_, - _prior_headerfooter_prop_, - prior_headerfooter_, - header_part_, + header: _BaseHeaderFooter, + _has_definition_prop_: Mock, + _prior_headerfooter_prop_: Mock, + prior_headerfooter_: Mock, + header_part_: Mock, ): _has_definition_prop_.return_value = False _prior_headerfooter_prop_.return_value = prior_headerfooter_ prior_headerfooter_._get_or_add_definition.return_value = header_part_ - header = _BaseHeaderFooter(None, None, None) header_part = header._get_or_add_definition() @@ -583,93 +640,83 @@ def but_it_gets_the_prior_definition_when_it_is_linked( def and_it_adds_a_definition_when_it_is_linked_and_the_first_section( self, - _has_definition_prop_, - _prior_headerfooter_prop_, - _add_definition_, - header_part_, + header: _BaseHeaderFooter, + _has_definition_prop_: Mock, + _prior_headerfooter_prop_: Mock, + _add_definition_: Mock, + header_part_: Mock, ): _has_definition_prop_.return_value = False _prior_headerfooter_prop_.return_value = None _add_definition_.return_value = header_part_ - header = _BaseHeaderFooter(None, None, None) header_part = header._get_or_add_definition() _add_definition_.assert_called_once_with(header) assert header_part is header_part_ - # fixtures ------------------------------------------------------- - - @pytest.fixture(params=[(False, True), (True, False)]) - def is_linked_get_fixture(self, request): - has_definition, expected_value = request.param - return has_definition, expected_value - - @pytest.fixture( - params=[ - (False, True, 0, 0), - (True, False, 0, 0), - (True, True, 1, 0), - (False, False, 0, 1), - ] - ) - def is_linked_set_fixture(self, request): - has_definition, new_value, drop_calls, add_calls = request.param - return has_definition, new_value, drop_calls, add_calls - - # fixture components --------------------------------------------- + # -- fixture ----------------------------------------------------- @pytest.fixture - def _add_definition_(self, request): + def _add_definition_(self, request: FixtureRequest): return method_mock(request, _BaseHeaderFooter, "_add_definition") @pytest.fixture - def _definition_prop_(self, request): + def _definition_prop_(self, request: FixtureRequest): return property_mock(request, _BaseHeaderFooter, "_definition") @pytest.fixture - def _drop_definition_(self, request): + def document_part_(self, request: FixtureRequest): + return instance_mock(request, DocumentPart) + + @pytest.fixture + def _drop_definition_(self, request: FixtureRequest): return method_mock(request, _BaseHeaderFooter, "_drop_definition") @pytest.fixture - def _get_or_add_definition_(self, request): + def _get_or_add_definition_(self, request: FixtureRequest): return method_mock(request, _BaseHeaderFooter, "_get_or_add_definition") @pytest.fixture - def _has_definition_prop_(self, request): + def _has_definition_prop_(self, request: FixtureRequest): return property_mock(request, _BaseHeaderFooter, "_has_definition") @pytest.fixture - def header_part_(self, request): + def header(self, document_part_: Mock) -> _BaseHeaderFooter: + sectPr = cast(CT_SectPr, element("w:sectPr")) + return _BaseHeaderFooter(sectPr, document_part_, WD_HEADER_FOOTER.PRIMARY) + + @pytest.fixture + def header_part_(self, request: FixtureRequest): return instance_mock(request, HeaderPart) @pytest.fixture - def prior_headerfooter_(self, request): + def prior_headerfooter_(self, request: FixtureRequest): return instance_mock(request, _BaseHeaderFooter) @pytest.fixture - def _prior_headerfooter_prop_(self, request): + def _prior_headerfooter_prop_(self, request: FixtureRequest): return property_mock(request, _BaseHeaderFooter, "_prior_headerfooter") -class Describe_Footer(object): - def it_can_add_a_footer_part_to_help(self, document_part_, footer_part_): - sectPr = element("w:sectPr{r:a=b}") +class Describe_Footer: + """Unit-test suite for `docx.section._Footer`.""" + + def it_can_add_a_footer_part_to_help(self, document_part_: Mock, footer_part_: Mock): + sectPr = cast(CT_SectPr, element("w:sectPr{r:a=b}")) document_part_.add_footer_part.return_value = footer_part_, "rId3" footer = _Footer(sectPr, document_part_, WD_HEADER_FOOTER.PRIMARY) footer_part = footer._add_definition() document_part_.add_footer_part.assert_called_once_with() - assert sectPr.xml == xml( - "w:sectPr{r:a=b}/w:footerReference{w:type=default,r:id=rId3}" - ) + assert sectPr.xml == xml("w:sectPr{r:a=b}/w:footerReference{w:type=default,r:id=rId3}") assert footer_part is footer_part_ def it_provides_access_to_its_footer_part_to_help( - self, document_part_, footer_part_ + self, document_part_: Mock, footer_part_: Mock ): - sectPr = element("w:sectPr/w:footerReference{w:type=even,r:id=rId3}") + sectPr = cast(CT_SectPr, element("w:sectPr/w:footerReference{w:type=even,r:id=rId3}")) document_part_.footer_part.return_value = footer_part_ footer = _Footer(sectPr, document_part_, WD_HEADER_FOOTER.EVEN_PAGE) @@ -678,8 +725,10 @@ def it_provides_access_to_its_footer_part_to_help( document_part_.footer_part.assert_called_once_with("rId3") assert footer_part is footer_part_ - def it_can_drop_the_related_footer_part_to_help(self, document_part_): - sectPr = element("w:sectPr{r:a=b}/w:footerReference{w:type=first,r:id=rId42}") + def it_can_drop_the_related_footer_part_to_help(self, document_part_: Mock): + sectPr = cast( + CT_SectPr, element("w:sectPr{r:a=b}/w:footerReference{w:type=first,r:id=rId42}") + ) footer = _Footer(sectPr, document_part_, WD_HEADER_FOOTER.FIRST_PAGE) footer._drop_definition() @@ -687,85 +736,76 @@ def it_can_drop_the_related_footer_part_to_help(self, document_part_): assert sectPr.xml == xml("w:sectPr{r:a=b}") document_part_.drop_rel.assert_called_once_with("rId42") - def it_knows_when_it_has_a_definition_to_help(self, has_definition_fixture): - sectPr, expected_value = has_definition_fixture - footer = _Footer(sectPr, None, WD_HEADER_FOOTER.PRIMARY) + @pytest.mark.parametrize( + ("sectPr_cxml", "expected_value"), + [("w:sectPr", False), ("w:sectPr/w:footerReference{w:type=default}", True)], + ) + def it_knows_when_it_has_a_definition_to_help( + self, sectPr_cxml: str, expected_value: bool, document_part_: Mock + ): + sectPr = cast(CT_SectPr, element(sectPr_cxml)) + footer = _Footer(sectPr, document_part_, WD_HEADER_FOOTER.PRIMARY) has_definition = footer._has_definition assert has_definition is expected_value def it_provides_access_to_the_prior_Footer_to_help( - self, request, document_part_, footer_ + self, request: FixtureRequest, document_part_: Mock, footer_: Mock ): doc_elm = element("w:document/(w:sectPr,w:sectPr)") - prior_sectPr, sectPr = doc_elm[0], doc_elm[1] + prior_sectPr, sectPr = cast(CT_SectPr, doc_elm[0]), cast(CT_SectPr, doc_elm[1]) footer = _Footer(sectPr, document_part_, WD_HEADER_FOOTER.EVEN_PAGE) # ---mock must occur after construction of "real" footer--- _Footer_ = class_mock(request, "docx.section._Footer", return_value=footer_) prior_footer = footer._prior_headerfooter - _Footer_.assert_called_once_with( - prior_sectPr, document_part_, WD_HEADER_FOOTER.EVEN_PAGE - ) + _Footer_.assert_called_once_with(prior_sectPr, document_part_, WD_HEADER_FOOTER.EVEN_PAGE) assert prior_footer is footer_ - def but_it_returns_None_when_its_the_first_footer(self): - doc_elm = element("w:document/w:sectPr") - sectPr = doc_elm[0] - footer = _Footer(sectPr, None, None) + def but_it_returns_None_when_its_the_first_footer(self, document_part_: Mock): + doc_elm = cast(CT_Document, element("w:document/w:sectPr")) + sectPr = cast(CT_SectPr, doc_elm[0]) + footer = _Footer(sectPr, document_part_, WD_HEADER_FOOTER.PRIMARY) prior_footer = footer._prior_headerfooter assert prior_footer is None - # fixtures ------------------------------------------------------- - - @pytest.fixture( - params=[ - ("w:sectPr", False), - ("w:sectPr/w:footerReference{w:type=default}", True), - ] - ) - def has_definition_fixture(self, request): - sectPr_cxml, expected_value = request.param - sectPr = element(sectPr_cxml) - return sectPr, expected_value - - # fixture components --------------------------------------------- + # -- fixtures--------------------------------------------------------------------------------- @pytest.fixture - def document_part_(self, request): + def document_part_(self, request: FixtureRequest): return instance_mock(request, DocumentPart) @pytest.fixture - def footer_(self, request): + def footer_(self, request: FixtureRequest): return instance_mock(request, _Footer) @pytest.fixture - def footer_part_(self, request): + def footer_part_(self, request: FixtureRequest): return instance_mock(request, FooterPart) -class Describe_Header(object): - def it_can_add_a_header_part_to_help(self, document_part_, header_part_): - sectPr = element("w:sectPr{r:a=b}") +class Describe_Header: + """Unit-test suite for `docx.section._Header`.""" + + def it_can_add_a_header_part_to_help(self, document_part_: Mock, header_part_: Mock): + sectPr = cast(CT_SectPr, element("w:sectPr{r:a=b}")) document_part_.add_header_part.return_value = header_part_, "rId3" header = _Header(sectPr, document_part_, WD_HEADER_FOOTER.FIRST_PAGE) header_part = header._add_definition() document_part_.add_header_part.assert_called_once_with() - assert sectPr.xml == xml( - "w:sectPr{r:a=b}/w:headerReference{w:type=first,r:id=rId3}" - ) + assert sectPr.xml == xml("w:sectPr{r:a=b}/w:headerReference{w:type=first,r:id=rId3}") assert header_part is header_part_ def it_provides_access_to_its_header_part_to_help( - self, document_part_, header_part_ + self, document_part_: Mock, header_part_: Mock ): - sectPr = element("w:sectPr/w:headerReference{w:type=default,r:id=rId8}") + sectPr = cast(CT_SectPr, element("w:sectPr/w:headerReference{w:type=default,r:id=rId8}")) document_part_.header_part.return_value = header_part_ header = _Header(sectPr, document_part_, WD_HEADER_FOOTER.PRIMARY) @@ -774,8 +814,10 @@ def it_provides_access_to_its_header_part_to_help( document_part_.header_part.assert_called_once_with("rId8") assert header_part is header_part_ - def it_can_drop_the_related_header_part_to_help(self, document_part_): - sectPr = element("w:sectPr{r:a=b}/w:headerReference{w:type=even,r:id=rId42}") + def it_can_drop_the_related_header_part_to_help(self, document_part_: Mock): + sectPr = cast( + CT_SectPr, element("w:sectPr{r:a=b}/w:headerReference{w:type=even,r:id=rId42}") + ) header = _Header(sectPr, document_part_, WD_HEADER_FOOTER.EVEN_PAGE) header._drop_definition() @@ -783,59 +825,53 @@ def it_can_drop_the_related_header_part_to_help(self, document_part_): assert sectPr.xml == xml("w:sectPr{r:a=b}") document_part_.drop_header_part.assert_called_once_with("rId42") - def it_knows_when_it_has_a_header_part_to_help(self, has_definition_fixture): - sectPr, expected_value = has_definition_fixture - header = _Header(sectPr, None, WD_HEADER_FOOTER.FIRST_PAGE) + @pytest.mark.parametrize( + ("sectPr_cxml", "expected_value"), + [("w:sectPr", False), ("w:sectPr/w:headerReference{w:type=first}", True)], + ) + def it_knows_when_it_has_a_header_part_to_help( + self, sectPr_cxml: str, expected_value: bool, document_part_: Mock + ): + sectPr = cast(CT_SectPr, element(sectPr_cxml)) + header = _Header(sectPr, document_part_, WD_HEADER_FOOTER.FIRST_PAGE) has_definition = header._has_definition assert has_definition is expected_value def it_provides_access_to_the_prior_Header_to_help( - self, request, document_part_, header_ + self, request: FixtureRequest, document_part_: Mock, header_: Mock ): doc_elm = element("w:document/(w:sectPr,w:sectPr)") - prior_sectPr, sectPr = doc_elm[0], doc_elm[1] + prior_sectPr, sectPr = cast(CT_SectPr, doc_elm[0]), cast(CT_SectPr, doc_elm[1]) header = _Header(sectPr, document_part_, WD_HEADER_FOOTER.PRIMARY) # ---mock must occur after construction of "real" header--- _Header_ = class_mock(request, "docx.section._Header", return_value=header_) prior_header = header._prior_headerfooter - _Header_.assert_called_once_with( - prior_sectPr, document_part_, WD_HEADER_FOOTER.PRIMARY - ) + _Header_.assert_called_once_with(prior_sectPr, document_part_, WD_HEADER_FOOTER.PRIMARY) assert prior_header is header_ - def but_it_returns_None_when_its_the_first_header(self): + def but_it_returns_None_when_its_the_first_header(self, document_part_: Mock): doc_elm = element("w:document/w:sectPr") - sectPr = doc_elm[0] - header = _Header(sectPr, None, None) + sectPr = cast(CT_SectPr, doc_elm[0]) + header = _Header(sectPr, document_part_, WD_HEADER_FOOTER.PRIMARY) prior_header = header._prior_headerfooter assert prior_header is None - # fixtures ------------------------------------------------------- - - @pytest.fixture( - params=[("w:sectPr", False), ("w:sectPr/w:headerReference{w:type=first}", True)] - ) - def has_definition_fixture(self, request): - sectPr_cxml, expected_value = request.param - sectPr = element(sectPr_cxml) - return sectPr, expected_value - - # fixture components --------------------------------------------- + # -- fixtures--------------------------------------------------------------------------------- @pytest.fixture - def document_part_(self, request): + def document_part_(self, request: FixtureRequest): return instance_mock(request, DocumentPart) @pytest.fixture - def header_(self, request): + def header_(self, request: FixtureRequest): return instance_mock(request, _Header) @pytest.fixture - def header_part_(self, request): + def header_part_(self, request: FixtureRequest): return instance_mock(request, HeaderPart) diff --git a/tests/test_settings.py b/tests/test_settings.py index 5c07a665..ff07eda2 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -1,8 +1,8 @@ -# encoding: utf-8 +# pyright: reportPrivateUsage=false -"""Unit test suite for the docx.settings module""" +"""Unit test suite for the docx.settings module.""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import annotations import pytest @@ -11,57 +11,38 @@ from .unitutil.cxml import element, xml -class DescribeSettings(object): - def it_knows_when_the_document_has_distinct_odd_and_even_headers( - self, odd_and_even_get_fixture - ): - settings_elm, expected_value = odd_and_even_get_fixture - settings = Settings(settings_elm) - - odd_and_even_pages_header_footer = settings.odd_and_even_pages_header_footer - - assert odd_and_even_pages_header_footer is expected_value - - def it_can_change_whether_the_document_has_distinct_odd_and_even_headers( - self, odd_and_even_set_fixture - ): - settings_elm, value, expected_xml = odd_and_even_set_fixture - settings = Settings(settings_elm) - - settings.odd_and_even_pages_header_footer = value +class DescribeSettings: + """Unit-test suite for the `docx.settings.Settings` objects.""" - assert settings_elm.xml == expected_xml - - # fixtures ------------------------------------------------------- - - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("cxml", "expected_value"), + [ ("w:settings", False), ("w:settings/w:evenAndOddHeaders", True), ("w:settings/w:evenAndOddHeaders{w:val=0}", False), ("w:settings/w:evenAndOddHeaders{w:val=1}", True), ("w:settings/w:evenAndOddHeaders{w:val=true}", True), - ] + ], ) - def odd_and_even_get_fixture(self, request): - settings_cxml, expected_value = request.param - settings_elm = element(settings_cxml) - return settings_elm, expected_value + def it_knows_when_the_document_has_distinct_odd_and_even_headers( + self, cxml: str, expected_value: bool + ): + assert Settings(element(cxml)).odd_and_even_pages_header_footer is expected_value - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("cxml", "new_value", "expected_cxml"), + [ ("w:settings", True, "w:settings/w:evenAndOddHeaders"), ("w:settings/w:evenAndOddHeaders", False, "w:settings"), - ( - "w:settings/w:evenAndOddHeaders{w:val=1}", - True, - "w:settings/w:evenAndOddHeaders", - ), + ("w:settings/w:evenAndOddHeaders{w:val=1}", True, "w:settings/w:evenAndOddHeaders"), ("w:settings/w:evenAndOddHeaders{w:val=off}", False, "w:settings"), - ] + ], ) - def odd_and_even_set_fixture(self, request): - settings_cxml, value, expected_cxml = request.param - settings_elm = element(settings_cxml) - expected_xml = xml(expected_cxml) - return settings_elm, value, expected_xml + def it_can_change_whether_the_document_has_distinct_odd_and_even_headers( + self, cxml: str, new_value: bool, expected_cxml: str + ): + settings = Settings(element(cxml)) + + settings.odd_and_even_pages_header_footer = new_value + + assert settings._settings.xml == xml(expected_cxml) diff --git a/tests/test_shape.py b/tests/test_shape.py index 5e08e974..68998b90 100644 --- a/tests/test_shape.py +++ b/tests/test_shape.py @@ -1,200 +1,129 @@ -# encoding: utf-8 +# pyright: reportPrivateUsage=false -""" -Test suite for the docx.shape module -""" +"""Test suite for the docx.shape module.""" -from __future__ import absolute_import, print_function, unicode_literals +from __future__ import annotations + +from typing import cast import pytest +from docx.document import Document from docx.enum.shape import WD_INLINE_SHAPE +from docx.oxml.document import CT_Body from docx.oxml.ns import nsmap +from docx.oxml.shape import CT_Inline from docx.shape import InlineShape, InlineShapes -from docx.shared import Length - -from .oxml.unitdata.dml import ( - a_blip, - a_blipFill, - a_graphic, - a_graphicData, - a_pic, - an_inline, -) +from docx.shared import Emu, Length + from .unitutil.cxml import element, xml -from .unitutil.mock import loose_mock - - -class DescribeInlineShapes(object): - def it_knows_how_many_inline_shapes_it_contains(self, inline_shapes_fixture): - inline_shapes, expected_count = inline_shapes_fixture - assert len(inline_shapes) == expected_count - - def it_can_iterate_over_its_InlineShape_instances(self, inline_shapes_fixture): - inline_shapes, inline_shape_count = inline_shapes_fixture - actual_count = 0 - for inline_shape in inline_shapes: - assert isinstance(inline_shape, InlineShape) - actual_count += 1 - assert actual_count == inline_shape_count - - def it_provides_indexed_access_to_inline_shapes(self, inline_shapes_fixture): - inline_shapes, inline_shape_count = inline_shapes_fixture - for idx in range(-inline_shape_count, inline_shape_count): - inline_shape = inline_shapes[idx] - assert isinstance(inline_shape, InlineShape) - - def it_raises_on_indexed_access_out_of_range(self, inline_shapes_fixture): - inline_shapes, inline_shape_count = inline_shapes_fixture - with pytest.raises(IndexError): - too_low = -1 - inline_shape_count - inline_shapes[too_low] - with pytest.raises(IndexError): - too_high = inline_shape_count - inline_shapes[too_high] - - def it_knows_the_part_it_belongs_to(self, inline_shapes_with_parent_): - inline_shapes, parent_ = inline_shapes_with_parent_ - part = inline_shapes.part - assert part is parent_.part - - # fixtures ------------------------------------------------------- +from .unitutil.mock import FixtureRequest, Mock, instance_mock - @pytest.fixture - def inline_shapes_fixture(self): - body = element("w:body/w:p/(w:r/w:drawing/wp:inline, w:r/w:drawing/wp:inline)") - inline_shapes = InlineShapes(body, None) - expected_count = 2 - return inline_shapes, expected_count - # fixture components --------------------------------------------- +class DescribeInlineShapes: + """Unit-test suite for `docx.shape.InlineShapes` objects.""" - @pytest.fixture - def inline_shapes_with_parent_(self, request): - parent_ = loose_mock(request, name="parent_") - inline_shapes = InlineShapes(None, parent_) - return inline_shapes, parent_ + def it_knows_how_many_inline_shapes_it_contains(self, body: CT_Body, document_: Mock): + inline_shapes = InlineShapes(body, document_) + assert len(inline_shapes) == 2 + def it_can_iterate_over_its_InlineShape_instances(self, body: CT_Body, document_: Mock): + inline_shapes = InlineShapes(body, document_) + assert all(isinstance(s, InlineShape) for s in inline_shapes) + assert len(list(inline_shapes)) == 2 -class DescribeInlineShape(object): - def it_knows_what_type_of_shape_it_is(self, shape_type_fixture): - inline_shape, inline_shape_type = shape_type_fixture - assert inline_shape.type == inline_shape_type + def it_provides_indexed_access_to_inline_shapes(self, body: CT_Body, document_: Mock): + inline_shapes = InlineShapes(body, document_) + for idx in range(-2, 2): + assert isinstance(inline_shapes[idx], InlineShape) - def it_knows_its_display_dimensions(self, dimensions_get_fixture): - inline_shape, cx, cy = dimensions_get_fixture - width = inline_shape.width - height = inline_shape.height - assert isinstance(width, Length) - assert width == cx - assert isinstance(height, Length) - assert height == cy + def it_raises_on_indexed_access_out_of_range(self, body: CT_Body, document_: Mock): + inline_shapes = InlineShapes(body, document_) + + with pytest.raises(IndexError, match=r"inline shape index \[-3\] out of range"): + inline_shapes[-3] + with pytest.raises(IndexError, match=r"inline shape index \[2\] out of range"): + inline_shapes[2] - def it_can_change_its_display_dimensions(self, dimensions_set_fixture): - inline_shape, cx, cy, expected_xml = dimensions_set_fixture - inline_shape.width = cx - inline_shape.height = cy - assert inline_shape._inline.xml == expected_xml + def it_knows_the_part_it_belongs_to(self, body: CT_Body, document_: Mock): + inline_shapes = InlineShapes(body, document_) + assert inline_shapes.part is document_.part - # fixtures ------------------------------------------------------- + # -- fixtures -------------------------------------------------------------------------------- @pytest.fixture - def dimensions_get_fixture(self): - inline_cxml, expected_cx, expected_cy = ( - "wp:inline/wp:extent{cx=333, cy=666}", - 333, - 666, + def body(self) -> CT_Body: + return cast( + CT_Body, element("w:body/w:p/(w:r/w:drawing/wp:inline, w:r/w:drawing/wp:inline)") ) - inline_shape = InlineShape(element(inline_cxml)) - return inline_shape, expected_cx, expected_cy @pytest.fixture - def dimensions_set_fixture(self): - inline_cxml, new_cx, new_cy, expected_cxml = ( - "wp:inline/(wp:extent{cx=333,cy=666},a:graphic/a:graphicData/" - "pic:pic/pic:spPr/a:xfrm/a:ext{cx=333,cy=666})", - 444, - 888, - "wp:inline/(wp:extent{cx=444,cy=888},a:graphic/a:graphicData/" - "pic:pic/pic:spPr/a:xfrm/a:ext{cx=444,cy=888})", - ) - inline_shape = InlineShape(element(inline_cxml)) - expected_xml = xml(expected_cxml) - return inline_shape, new_cx, new_cy, expected_xml - - @pytest.fixture( - params=[ - "embed pic", - "link pic", - "link+embed pic", - "chart", - "smart art", - "not implemented", - ] + def document_(self, request: FixtureRequest): + return instance_mock(request, Document) + + +class DescribeInlineShape: + """Unit-test suite for `docx.shape.InlineShape` objects.""" + + @pytest.mark.parametrize( + ("uri", "content_cxml", "expected_value"), + [ + # -- embedded picture -- + (nsmap["pic"], "/pic:pic/pic:blipFill/a:blip{r:embed=rId1}", WD_INLINE_SHAPE.PICTURE), + # -- linked picture -- + ( + nsmap["pic"], + "/pic:pic/pic:blipFill/a:blip{r:link=rId2}", + WD_INLINE_SHAPE.LINKED_PICTURE, + ), + # -- linked and embedded picture (not expected) -- + ( + nsmap["pic"], + "/pic:pic/pic:blipFill/a:blip{r:embed=rId1,r:link=rId2}", + WD_INLINE_SHAPE.LINKED_PICTURE, + ), + # -- chart -- + (nsmap["c"], "", WD_INLINE_SHAPE.CHART), + # -- SmartArt -- + (nsmap["dgm"], "", WD_INLINE_SHAPE.SMART_ART), + # -- something else we don't know about -- + ("foobar", "", WD_INLINE_SHAPE.NOT_IMPLEMENTED), + ], ) - def shape_type_fixture(self, request): - if request.param == "embed pic": - inline = self._inline_with_picture(embed=True) - shape_type = WD_INLINE_SHAPE.PICTURE - - elif request.param == "link pic": - inline = self._inline_with_picture(link=True) - shape_type = WD_INLINE_SHAPE.LINKED_PICTURE - - elif request.param == "link+embed pic": - inline = self._inline_with_picture(embed=True, link=True) - shape_type = WD_INLINE_SHAPE.LINKED_PICTURE - - elif request.param == "chart": - inline = self._inline_with_uri(nsmap["c"]) - shape_type = WD_INLINE_SHAPE.CHART - - elif request.param == "smart art": - inline = self._inline_with_uri(nsmap["dgm"]) - shape_type = WD_INLINE_SHAPE.SMART_ART - - elif request.param == "not implemented": - inline = self._inline_with_uri("foobar") - shape_type = WD_INLINE_SHAPE.NOT_IMPLEMENTED - - return InlineShape(inline), shape_type - - # fixture components --------------------------------------------- - - def _inline_with_picture(self, embed=False, link=False): - picture_ns = nsmap["pic"] - - blip_bldr = a_blip() - if embed: - blip_bldr.with_embed("rId1") - if link: - blip_bldr.with_link("rId2") - - inline = ( - an_inline() - .with_nsdecls("wp", "r") - .with_child( - a_graphic() - .with_nsdecls() - .with_child( - a_graphicData() - .with_uri(picture_ns) - .with_child( - a_pic() - .with_nsdecls() - .with_child(a_blipFill().with_child(blip_bldr)) - ) - ) - ) - ).element - return inline - - def _inline_with_uri(self, uri): - inline = ( - an_inline() - .with_nsdecls("wp") - .with_child( - a_graphic().with_nsdecls().with_child(a_graphicData().with_uri(uri)) + def it_knows_what_type_of_shape_it_is( + self, uri: str, content_cxml: str, expected_value: WD_INLINE_SHAPE + ): + cxml = "wp:inline/a:graphic/a:graphicData{uri=%s}%s" % (uri, content_cxml) + inline = cast(CT_Inline, element(cxml)) + inline_shape = InlineShape(inline) + assert inline_shape.type == expected_value + + def it_knows_its_display_dimensions(self): + inline = cast(CT_Inline, element("wp:inline/wp:extent{cx=333, cy=666}")) + inline_shape = InlineShape(inline) + + width, height = inline_shape.width, inline_shape.height + + assert isinstance(width, Length) + assert width == 333 + assert isinstance(height, Length) + assert height == 666 + + def it_can_change_its_display_dimensions(self): + inline_shape = InlineShape( + cast( + CT_Inline, + element( + "wp:inline/(wp:extent{cx=333,cy=666},a:graphic/a:graphicData/pic:pic/" + "pic:spPr/a:xfrm/a:ext{cx=333,cy=666})" + ), ) - ).element - return inline + ) + + inline_shape.width = Emu(444) + inline_shape.height = Emu(888) + + assert inline_shape._inline.xml == xml( + "wp:inline/(wp:extent{cx=444,cy=888},a:graphic/a:graphicData/pic:pic/pic:spPr/" + "a:xfrm/a:ext{cx=444,cy=888})" + ) diff --git a/tests/test_shared.py b/tests/test_shared.py index 7641c158..fb6c273c 100644 --- a/tests/test_shared.py +++ b/tests/test_shared.py @@ -1,23 +1,25 @@ -# encoding: utf-8 +"""Test suite for the docx.shared module.""" -""" -Test suite for the docx.shared module -""" - -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import annotations import pytest from docx.opc.part import XmlPart -from docx.shared import ElementProxy, Length, Cm, Emu, Inches, Mm, Pt, RGBColor, Twips +from docx.shared import Cm, ElementProxy, Emu, Inches, Length, Mm, Pt, RGBColor, Twips from .unitutil.cxml import element -from .unitutil.mock import instance_mock +from .unitutil.mock import FixtureRequest, Mock, instance_mock -class DescribeElementProxy(object): - def it_knows_when_its_equal_to_another_proxy_object(self, eq_fixture): - proxy, proxy_2, proxy_3, not_a_proxy = eq_fixture +class DescribeElementProxy: + """Unit-test suite for `docx.shared.ElementProxy` objects.""" + + def it_knows_when_its_equal_to_another_proxy_object(self): + p, q = element("w:p"), element("w:p") + proxy = ElementProxy(p) + proxy_2 = ElementProxy(p) + proxy_3 = ElementProxy(q) + not_a_proxy = "Foobar" assert (proxy == proxy_2) is True assert (proxy == proxy_3) is False @@ -27,66 +29,33 @@ def it_knows_when_its_equal_to_another_proxy_object(self, eq_fixture): assert (proxy != proxy_3) is True assert (proxy != not_a_proxy) is True - def it_knows_its_element(self, element_fixture): - proxy, element = element_fixture - assert proxy.element is element - - def it_knows_its_part(self, part_fixture): - proxy, part_ = part_fixture - assert proxy.part is part_ - - # fixture -------------------------------------------------------- - - @pytest.fixture - def element_fixture(self): + def it_knows_its_element(self): p = element("w:p") proxy = ElementProxy(p) - return proxy, p + assert proxy.element is p - @pytest.fixture - def eq_fixture(self): - p, q = element("w:p"), element("w:p") - proxy = ElementProxy(p) - proxy_2 = ElementProxy(p) - proxy_3 = ElementProxy(q) - not_a_proxy = "Foobar" - return proxy, proxy_2, proxy_3, not_a_proxy - - @pytest.fixture - def part_fixture(self, other_proxy_, part_): + def it_knows_its_part(self, other_proxy_: Mock, part_: Mock): other_proxy_.part = part_ - proxy = ElementProxy(None, other_proxy_) - return proxy, part_ + proxy = ElementProxy(element("w:p"), other_proxy_) + assert proxy.part is part_ - # fixture components --------------------------------------------- + # -- fixture --------------------------------------------------------------------------------- @pytest.fixture - def other_proxy_(self, request): + def other_proxy_(self, request: FixtureRequest): return instance_mock(request, ElementProxy) @pytest.fixture - def part_(self, request): + def part_(self, request: FixtureRequest): return instance_mock(request, XmlPart) -class DescribeLength(object): - def it_can_construct_from_convenient_units(self, construct_fixture): - UnitCls, units_val, emu = construct_fixture - length = UnitCls(units_val) - assert isinstance(length, Length) - assert length == emu - - def it_can_self_convert_to_convenient_units(self, units_fixture): - emu, units_prop_name, expected_length_in_units, type_ = units_fixture - length = Length(emu) - length_in_units = getattr(length, units_prop_name) - assert length_in_units == expected_length_in_units - assert isinstance(length_in_units, type_) - - # fixtures ------------------------------------------------------- +class DescribeLength: + """Unit-test suite for `docx.shared.Length` objects.""" - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("UnitCls", "units_val", "emu"), + [ (Length, 914400, 914400), (Inches, 1.1, 1005840), (Cm, 2.53, 910799), @@ -94,35 +63,50 @@ def it_can_self_convert_to_convenient_units(self, units_fixture): (Mm, 13.8, 496800), (Pt, 24.5, 311150), (Twips, 360, 228600), - ] + ], ) - def construct_fixture(self, request): - UnitCls, units_val, emu = request.param - return UnitCls, units_val, emu - - @pytest.fixture( - params=[ - (914400, "inches", 1.0, float), - (914400, "cm", 2.54, float), - (914400, "emu", 914400, int), - (914400, "mm", 25.4, float), - (914400, "pt", 72.0, float), - (914400, "twips", 1440, int), - ] + def it_can_construct_from_convenient_units(self, UnitCls: type, units_val: float, emu: int): + length = UnitCls(units_val) + assert isinstance(length, Length) + assert length == emu + + @pytest.mark.parametrize( + ("prop_name", "expected_value", "expected_type"), + [ + ("inches", 1.0, float), + ("cm", 2.54, float), + ("emu", 914400, int), + ("mm", 25.4, float), + ("pt", 72.0, float), + ("twips", 1440, int), + ], ) - def units_fixture(self, request): - emu, units_prop_name, expected_length_in_units, type_ = request.param - return emu, units_prop_name, expected_length_in_units, type_ + def it_can_self_convert_to_convenient_units( + self, prop_name: str, expected_value: float, expected_type: type + ): + # -- use an inch for the initial value -- + length = Length(914400) + length_in_units = getattr(length, prop_name) + assert length_in_units == expected_value + assert isinstance(length_in_units, expected_type) + +class DescribeRGBColor: + """Unit-test suite for `docx.shared.RGBColor` objects.""" -class DescribeRGBColor(object): def it_is_natively_constructed_using_three_ints_0_to_255(self): - RGBColor(0x12, 0x34, 0x56) - with pytest.raises(ValueError): - RGBColor("12", "34", "56") - with pytest.raises(ValueError): + rgb_color = RGBColor(0x12, 0x34, 0x56) + + assert isinstance(rgb_color, RGBColor) + # -- it is comparable to a tuple[int, int, int] -- + assert rgb_color == (18, 52, 86) + + def it_raises_with_helpful_error_message_on_wrong_types(self): + with pytest.raises(TypeError, match=r"RGBColor\(\) takes three integer valu"): + RGBColor("12", "34", "56") # pyright: ignore + with pytest.raises(ValueError, match=r"\(\) takes three integer values 0-255"): RGBColor(-1, 34, 56) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match=r"RGBColor\(\) takes three integer valu"): RGBColor(12, 256, 56) def it_can_construct_from_a_hex_string_rgb_value(self): @@ -130,7 +114,7 @@ def it_can_construct_from_a_hex_string_rgb_value(self): assert rgb == RGBColor(0x12, 0x34, 0x56) def it_can_provide_a_hex_string_rgb_value(self): - assert str(RGBColor(0x12, 0x34, 0x56)) == "123456" + assert str(RGBColor(0xF3, 0x8A, 0x56)) == "F38A56" def it_has_a_custom_repr(self): rgb_color = RGBColor(0x42, 0xF0, 0xBA) diff --git a/tests/test_table.py b/tests/test_table.py index b314b801..479d670c 100644 --- a/tests/test_table.py +++ b/tests/test_table.py @@ -1,11 +1,14 @@ -# encoding: utf-8 +# pyright: reportPrivateUsage=false -"""Test suite for the docx.table module""" +"""Test suite for the docx.table module.""" -from __future__ import absolute_import, print_function, unicode_literals +from __future__ import annotations + +from typing import cast import pytest +from docx.document import Document from docx.enum.style import WD_STYLE_TYPE from docx.enum.table import ( WD_ALIGN_VERTICAL, @@ -13,38 +16,46 @@ WD_TABLE_ALIGNMENT, WD_TABLE_DIRECTION, ) -from docx.oxml import parse_xml -from docx.oxml.table import CT_Tc +from docx.oxml.parser import parse_xml +from docx.oxml.table import CT_Row, CT_Tbl, CT_TblGridCol, CT_Tc from docx.parts.document import DocumentPart -from docx.shared import Inches -from docx.table import _Cell, _Column, _Columns, _Row, _Rows, Table +from docx.shared import Emu, Inches, Length +from docx.table import Table, _Cell, _Column, _Columns, _Row, _Rows from docx.text.paragraph import Paragraph -from .oxml.unitdata.table import a_gridCol, a_tbl, a_tblGrid, a_tc, a_tr -from .oxml.unitdata.text import a_p from .unitutil.cxml import element, xml from .unitutil.file import snippet_seq -from .unitutil.mock import instance_mock, property_mock +from .unitutil.mock import FixtureRequest, Mock, instance_mock, property_mock + +class DescribeTable: + """Unit-test suite for `docx.table._Rows` objects.""" + + def it_can_add_a_row(self, document_: Mock): + snippets = snippet_seq("add-row-col") + tbl = cast(CT_Tbl, parse_xml(snippets[0])) + table = Table(tbl, document_) -class DescribeTable(object): - def it_can_add_a_row(self, add_row_fixture): - table, expected_xml = add_row_fixture row = table.add_row() - assert table._tbl.xml == expected_xml + + assert table._tbl.xml == snippets[1] assert isinstance(row, _Row) assert row._tr is table._tbl.tr_lst[-1] assert row._parent is table - def it_can_add_a_column(self, add_column_fixture): - table, width, expected_xml = add_column_fixture - column = table.add_column(width) - assert table._tbl.xml == expected_xml + def it_can_add_a_column(self, document_: Mock): + snippets = snippet_seq("add-row-col") + tbl = cast(CT_Tbl, parse_xml(snippets[0])) + table = Table(tbl, document_) + + column = table.add_column(Inches(1.5)) + + assert table._tbl.xml == snippets[2] assert isinstance(column, _Column) assert column._gridCol is table._tbl.tblGrid.gridCol_lst[-1] assert column._parent is table - def it_provides_access_to_a_cell_by_row_and_col_indices(self, table): + def it_provides_access_to_a_cell_by_row_and_col_indices(self, table: Table): for row_idx in range(2): for col_idx in range(2): cell = table.cell(row_idx, col_idx) @@ -53,153 +64,95 @@ def it_provides_access_to_a_cell_by_row_and_col_indices(self, table): tc = tr.tc_lst[col_idx] assert tc is cell._tc - def it_provides_access_to_the_table_rows(self, table): + def it_provides_access_to_the_table_rows(self, table: Table): rows = table.rows assert isinstance(rows, _Rows) - def it_provides_access_to_the_table_columns(self, table): + def it_provides_access_to_the_table_columns(self, table: Table): columns = table.columns assert isinstance(columns, _Columns) - def it_provides_access_to_the_cells_in_a_column(self, col_cells_fixture): - table, column_idx, expected_cells = col_cells_fixture - column_cells = table.column_cells(column_idx) - assert column_cells == expected_cells - - def it_provides_access_to_the_cells_in_a_row(self, row_cells_fixture): - table, row_idx, expected_cells = row_cells_fixture - row_cells = table.row_cells(row_idx) - assert row_cells == expected_cells - - def it_knows_its_alignment_setting(self, alignment_get_fixture): - table, expected_value = alignment_get_fixture - assert table.alignment == expected_value - - def it_can_change_its_alignment_setting(self, alignment_set_fixture): - table, new_value, expected_xml = alignment_set_fixture - table.alignment = new_value - assert table._tbl.xml == expected_xml - - def it_knows_whether_it_should_autofit(self, autofit_get_fixture): - table, expected_value = autofit_get_fixture - assert table.autofit is expected_value - - def it_can_change_its_autofit_setting(self, autofit_set_fixture): - table, new_value, expected_xml = autofit_set_fixture - table.autofit = new_value - assert table._tbl.xml == expected_xml - - def it_knows_it_is_the_table_its_children_belong_to(self, table_fixture): - table = table_fixture - assert table.table is table - - def it_knows_its_direction(self, direction_get_fixture): - table, expected_value = direction_get_fixture - assert table.table_direction == expected_value - - def it_can_change_its_direction(self, direction_set_fixture): - table, new_value, expected_xml = direction_set_fixture - table.table_direction = new_value - assert table._element.xml == expected_xml - - def it_knows_its_table_style(self, style_get_fixture): - table, style_id_, style_ = style_get_fixture - style = table.style - table.part.get_style.assert_called_once_with(style_id_, WD_STYLE_TYPE.TABLE) - assert style is style_ - - def it_can_change_its_table_style(self, style_set_fixture): - table, value, expected_xml = style_set_fixture - table.style = value - table.part.get_style_id.assert_called_once_with(value, WD_STYLE_TYPE.TABLE) - assert table._tbl.xml == expected_xml + def it_provides_access_to_the_cells_in_a_column( + self, _cells_: Mock, _column_count_: Mock, document_: Mock + ): + table = Table(cast(CT_Tbl, element("w:tbl")), document_) + _cells_.return_value = [0, 1, 2, 3, 4, 5, 6, 7, 8] + _column_count_.return_value = 3 + column_idx = 1 - def it_provides_access_to_its_cells_to_help(self, cells_fixture): - table, cell_count, unique_count, matches = cells_fixture - cells = table._cells - assert len(cells) == cell_count - assert len(set(cells)) == unique_count - for matching_idxs in matches: - comparator_idx = matching_idxs[0] - for idx in matching_idxs[1:]: - assert cells[idx] is cells[comparator_idx] + column_cells = table.column_cells(column_idx) - def it_knows_its_column_count_to_help(self, column_count_fixture): - table, expected_value = column_count_fixture - column_count = table._column_count - assert column_count == expected_value + assert column_cells == [1, 4, 7] - # fixtures ------------------------------------------------------- + def it_provides_access_to_the_cells_in_a_row( + self, _cells_: Mock, _column_count_: Mock, document_: Mock + ): + table = Table(cast(CT_Tbl, element("w:tbl")), document_) + _cells_.return_value = [0, 1, 2, 3, 4, 5, 6, 7, 8] + _column_count_.return_value = 3 - @pytest.fixture - def add_column_fixture(self): - snippets = snippet_seq("add-row-col") - tbl = parse_xml(snippets[0]) - table = Table(tbl, None) - width = Inches(1.5) - expected_xml = snippets[2] - return table, width, expected_xml + row_cells = table.row_cells(1) - @pytest.fixture - def add_row_fixture(self): - snippets = snippet_seq("add-row-col") - tbl = parse_xml(snippets[0]) - table = Table(tbl, None) - expected_xml = snippets[1] - return table, expected_xml + assert row_cells == [3, 4, 5] - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("tbl_cxml", "expected_value"), + [ ("w:tbl/w:tblPr", None), ("w:tbl/w:tblPr/w:jc{w:val=center}", WD_TABLE_ALIGNMENT.CENTER), ("w:tbl/w:tblPr/w:jc{w:val=right}", WD_TABLE_ALIGNMENT.RIGHT), ("w:tbl/w:tblPr/w:jc{w:val=left}", WD_TABLE_ALIGNMENT.LEFT), - ] + ], ) - def alignment_get_fixture(self, request): - tbl_cxml, expected_value = request.param - table = Table(element(tbl_cxml), None) - return table, expected_value + def it_knows_its_alignment_setting( + self, tbl_cxml: str, expected_value: WD_TABLE_ALIGNMENT | None, document_: Mock + ): + table = Table(cast(CT_Tbl, element(tbl_cxml)), document_) + assert table.alignment == expected_value - @pytest.fixture( - params=[ - ( - "w:tbl/w:tblPr", - WD_TABLE_ALIGNMENT.LEFT, - "w:tbl/w:tblPr/w:jc{w:val=left}", - ), + @pytest.mark.parametrize( + ("tbl_cxml", "new_value", "expected_cxml"), + [ + ("w:tbl/w:tblPr", WD_TABLE_ALIGNMENT.LEFT, "w:tbl/w:tblPr/w:jc{w:val=left}"), ( "w:tbl/w:tblPr/w:jc{w:val=left}", WD_TABLE_ALIGNMENT.RIGHT, "w:tbl/w:tblPr/w:jc{w:val=right}", ), ("w:tbl/w:tblPr/w:jc{w:val=right}", None, "w:tbl/w:tblPr"), - ] + ], ) - def alignment_set_fixture(self, request): - tbl_cxml, new_value, expected_tbl_cxml = request.param - table = Table(element(tbl_cxml), None) - expected_xml = xml(expected_tbl_cxml) - return table, new_value, expected_xml - - @pytest.fixture( - params=[ + def it_can_change_its_alignment_setting( + self, + tbl_cxml: str, + new_value: WD_TABLE_ALIGNMENT | None, + expected_cxml: str, + document_: Mock, + ): + table = Table(cast(CT_Tbl, element(tbl_cxml)), document_) + table.alignment = new_value + assert table._tbl.xml == xml(expected_cxml) + + @pytest.mark.parametrize( + ("tbl_cxml", "expected_value"), + [ ("w:tbl/w:tblPr", True), ("w:tbl/w:tblPr/w:tblLayout", True), ("w:tbl/w:tblPr/w:tblLayout{w:type=autofit}", True), ("w:tbl/w:tblPr/w:tblLayout{w:type=fixed}", False), - ] + ], ) - def autofit_get_fixture(self, request): - tbl_cxml, expected_autofit = request.param - table = Table(element(tbl_cxml), None) - return table, expected_autofit + def it_knows_whether_it_should_autofit( + self, tbl_cxml: str, expected_value: bool, document_: Mock + ): + table = Table(cast(CT_Tbl, element(tbl_cxml)), document_) + assert table.autofit is expected_value - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("tbl_cxml", "new_value", "expected_cxml"), + [ ("w:tbl/w:tblPr", True, "w:tbl/w:tblPr/w:tblLayout{w:type=autofit}"), ("w:tbl/w:tblPr", False, "w:tbl/w:tblPr/w:tblLayout{w:type=fixed}"), - ("w:tbl/w:tblPr", None, "w:tbl/w:tblPr/w:tblLayout{w:type=fixed}"), ( "w:tbl/w:tblPr/w:tblLayout{w:type=fixed}", True, @@ -210,60 +163,36 @@ def autofit_get_fixture(self, request): False, "w:tbl/w:tblPr/w:tblLayout{w:type=fixed}", ), - ] + ], ) - def autofit_set_fixture(self, request): - tbl_cxml, new_value, expected_tbl_cxml = request.param - table = Table(element(tbl_cxml), None) - expected_xml = xml(expected_tbl_cxml) - return table, new_value, expected_xml - - @pytest.fixture( - params=[ - (0, 9, 9, ()), - (1, 9, 8, ((0, 1),)), - (2, 9, 8, ((1, 4),)), - (3, 9, 6, ((0, 1, 3, 4),)), - (4, 9, 4, ((0, 1), (3, 6), (4, 5, 7, 8))), - ] - ) - def cells_fixture(self, request): - snippet_idx, cell_count, unique_count, matches = request.param - tbl_xml = snippet_seq("tbl-cells")[snippet_idx] - table = Table(parse_xml(tbl_xml), None) - return table, cell_count, unique_count, matches - - @pytest.fixture - def col_cells_fixture(self, _cells_, _column_count_): - table = Table(None, None) - _cells_.return_value = [0, 1, 2, 3, 4, 5, 6, 7, 8] - _column_count_.return_value = 3 - column_idx = 1 - expected_cells = [1, 4, 7] - return table, column_idx, expected_cells + def it_can_change_its_autofit_setting( + self, tbl_cxml: str, new_value: bool, expected_cxml: str, document_: Mock + ): + table = Table(cast(CT_Tbl, element(tbl_cxml)), document_) + table.autofit = new_value + assert table._tbl.xml == xml(expected_cxml) - @pytest.fixture - def column_count_fixture(self): - tbl_cxml = "w:tbl/w:tblGrid/(w:gridCol,w:gridCol,w:gridCol)" - expected_value = 3 - table = Table(element(tbl_cxml), None) - return table, expected_value + def it_knows_it_is_the_table_its_children_belong_to(self, table: Table): + assert table.table is table - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("tbl_cxml", "expected_value"), + [ ("w:tbl/w:tblPr", None), ("w:tbl/w:tblPr/w:bidiVisual", WD_TABLE_DIRECTION.RTL), ("w:tbl/w:tblPr/w:bidiVisual{w:val=0}", WD_TABLE_DIRECTION.LTR), ("w:tbl/w:tblPr/w:bidiVisual{w:val=on}", WD_TABLE_DIRECTION.RTL), - ] + ], ) - def direction_get_fixture(self, request): - tbl_cxml, expected_value = request.param - table = Table(element(tbl_cxml), None) - return table, expected_value - - @pytest.fixture( - params=[ + def it_knows_its_direction( + self, tbl_cxml: str, expected_value: WD_TABLE_DIRECTION | None, document_: Mock + ): + tbl = cast(CT_Tbl, element(tbl_cxml)) + assert Table(tbl, document_).table_direction == expected_value + + @pytest.mark.parametrize( + ("tbl_cxml", "new_value", "expected_cxml"), + [ ("w:tbl/w:tblPr", WD_TABLE_DIRECTION.RTL, "w:tbl/w:tblPr/w:bidiVisual"), ( "w:tbl/w:tblPr/w:bidiVisual", @@ -276,33 +205,28 @@ def direction_get_fixture(self, request): "w:tbl/w:tblPr/w:bidiVisual", ), ("w:tbl/w:tblPr/w:bidiVisual{w:val=1}", None, "w:tbl/w:tblPr"), - ] + ], ) - def direction_set_fixture(self, request): - tbl_cxml, new_value, expected_cxml = request.param - table = Table(element(tbl_cxml), None) - expected_xml = xml(expected_cxml) - return table, new_value, expected_xml + def it_can_change_its_direction( + self, tbl_cxml: str, new_value: WD_TABLE_DIRECTION, expected_cxml: str, document_: Mock + ): + table = Table(cast(CT_Tbl, element(tbl_cxml)), document_) + table.table_direction = new_value + assert table._element.xml == xml(expected_cxml) - @pytest.fixture - def row_cells_fixture(self, _cells_, _column_count_): - table = Table(None, None) - _cells_.return_value = [0, 1, 2, 3, 4, 5, 6, 7, 8] - _column_count_.return_value = 3 - row_idx = 1 - expected_cells = [3, 4, 5] - return table, row_idx, expected_cells + def it_knows_its_table_style(self, part_prop_: Mock, document_part_: Mock, document_: Mock): + part_prop_.return_value = document_part_ + style_ = document_part_.get_style.return_value + table = Table(cast(CT_Tbl, element("w:tbl/w:tblPr/w:tblStyle{w:val=BarBaz}")), document_) - @pytest.fixture - def style_get_fixture(self, part_prop_): - style_id = "Barbaz" - tbl_cxml = "w:tbl/w:tblPr/w:tblStyle{w:val=%s}" % style_id - table = Table(element(tbl_cxml), None) - style_ = part_prop_.return_value.get_style.return_value - return table, style_id, style_ - - @pytest.fixture( - params=[ + style = table.style + + document_part_.get_style.assert_called_once_with("BarBaz", WD_STYLE_TYPE.TABLE) + assert style is style_ + + @pytest.mark.parametrize( + ("tbl_cxml", "new_value", "style_id", "expected_cxml"), + [ ("w:tbl/w:tblPr", "Tbl A", "TblA", "w:tbl/w:tblPr/w:tblStyle{w:val=TblA}"), ( "w:tbl/w:tblPr/w:tblStyle{w:val=TblA}", @@ -311,155 +235,166 @@ def style_get_fixture(self, part_prop_): "w:tbl/w:tblPr/w:tblStyle{w:val=TblB}", ), ("w:tbl/w:tblPr/w:tblStyle{w:val=TblB}", None, None, "w:tbl/w:tblPr"), - ] + ], + ) + def it_can_change_its_table_style( + self, + tbl_cxml: str, + new_value: str | None, + style_id: str | None, + expected_cxml: str, + document_: Mock, + part_prop_: Mock, + document_part_: Mock, + ): + table = Table(cast(CT_Tbl, element(tbl_cxml)), document_) + part_prop_.return_value = document_part_ + document_part_.get_style_id.return_value = style_id + + table.style = new_value + + document_part_.get_style_id.assert_called_once_with(new_value, WD_STYLE_TYPE.TABLE) + assert table._tbl.xml == xml(expected_cxml) + + @pytest.mark.parametrize( + ("snippet_idx", "cell_count", "unique_count", "matches"), + [ + (0, 9, 9, ()), + (1, 9, 8, ((0, 1),)), + (2, 9, 8, ((1, 4),)), + (3, 9, 6, ((0, 1, 3, 4),)), + (4, 9, 4, ((0, 1), (3, 6), (4, 5, 7, 8))), + ], ) - def style_set_fixture(self, request, part_prop_): - tbl_cxml, value, style_id, expected_cxml = request.param - table = Table(element(tbl_cxml), None) - part_prop_.return_value.get_style_id.return_value = style_id - expected_xml = xml(expected_cxml) - return table, value, expected_xml + def it_provides_access_to_its_cells_to_help( + self, + snippet_idx: int, + cell_count: int, + unique_count: int, + matches: tuple[tuple[int, ...]], + document_: Mock, + ): + tbl_xml = snippet_seq("tbl-cells")[snippet_idx] + table = Table(cast(CT_Tbl, parse_xml(tbl_xml)), document_) - @pytest.fixture - def table_fixture(self): - table = Table(None, None) - return table + cells = table._cells - # fixture components --------------------------------------------- + assert len(cells) == cell_count + assert len(set(cells)) == unique_count + for matching_idxs in matches: + comparator_idx = matching_idxs[0] + for idx in matching_idxs[1:]: + assert cells[idx] is cells[comparator_idx] + + def it_knows_its_column_count_to_help(self, document_: Mock): + tbl_cxml = "w:tbl/w:tblGrid/(w:gridCol,w:gridCol,w:gridCol)" + expected_value = 3 + table = Table(cast(CT_Tbl, element(tbl_cxml)), document_) + + column_count = table._column_count + + assert column_count == expected_value + + # fixtures ------------------------------------------------------- @pytest.fixture - def _cells_(self, request): + def _cells_(self, request: FixtureRequest): return property_mock(request, Table, "_cells") @pytest.fixture - def _column_count_(self, request): + def _column_count_(self, request: FixtureRequest): return property_mock(request, Table, "_column_count") @pytest.fixture - def document_part_(self, request): - return instance_mock(request, DocumentPart) + def document_(self, request: FixtureRequest): + return instance_mock(request, Document) @pytest.fixture - def part_prop_(self, request, document_part_): - return property_mock(request, Table, "part", return_value=document_part_) + def document_part_(self, request: FixtureRequest): + return instance_mock(request, DocumentPart) @pytest.fixture - def table(self): - tbl = _tbl_bldr(rows=2, cols=2).element - table = Table(tbl, None) - return table - - -class Describe_Cell(object): - def it_knows_what_text_it_contains(self, text_get_fixture): - cell, expected_text = text_get_fixture - text = cell.text - assert text == expected_text - - def it_can_replace_its_content_with_a_string_of_text(self, text_set_fixture): - cell, text, expected_xml = text_set_fixture - cell.text = text - assert cell._tc.xml == expected_xml - - def it_knows_its_vertical_alignment(self, alignment_get_fixture): - cell, expected_value = alignment_get_fixture - vertical_alignment = cell.vertical_alignment - assert vertical_alignment == expected_value - - def it_can_change_its_vertical_alignment(self, alignment_set_fixture): - cell, new_value, expected_xml = alignment_set_fixture - cell.vertical_alignment = new_value - assert cell._element.xml == expected_xml - - def it_knows_its_width_in_EMU(self, width_get_fixture): - cell, expected_width = width_get_fixture - assert cell.width == expected_width - - def it_can_change_its_width(self, width_set_fixture): - cell, value, expected_xml = width_set_fixture - cell.width = value - assert cell.width == value - assert cell._tc.xml == expected_xml + def part_prop_(self, request: FixtureRequest): + return property_mock(request, Table, "part") - def it_provides_access_to_the_paragraphs_it_contains(self, paragraphs_fixture): - cell = paragraphs_fixture - paragraphs = cell.paragraphs - assert len(paragraphs) == 2 - count = 0 - for idx, paragraph in enumerate(paragraphs): - assert isinstance(paragraph, Paragraph) - assert paragraph is paragraphs[idx] - count += 1 - assert count == 2 - - def it_provides_access_to_the_tables_it_contains(self, tables_fixture): - # test len(), iterable, and indexed access - cell, expected_count = tables_fixture - tables = cell.tables - assert len(tables) == expected_count - count = 0 - for idx, table in enumerate(tables): - assert isinstance(table, Table) - assert tables[idx] is table - count += 1 - assert count == expected_count - - def it_can_add_a_paragraph(self, add_paragraph_fixture): - cell, expected_xml = add_paragraph_fixture - p = cell.add_paragraph() - assert cell._tc.xml == expected_xml - assert isinstance(p, Paragraph) - - def it_can_add_a_table(self, add_table_fixture): - cell, expected_xml = add_table_fixture - table = cell.add_table(rows=2, cols=2) - assert cell._element.xml == expected_xml - assert isinstance(table, Table) + @pytest.fixture + def table(self, document_: Mock): + tbl_cxml = "w:tbl/(w:tblGrid/(w:gridCol,w:gridCol),w:tr/(w:tc,w:tc),w:tr/(w:tc,w:tc))" + return Table(cast(CT_Tbl, element(tbl_cxml)), document_) - def it_can_merge_itself_with_other_cells(self, merge_fixture): - cell, other_cell, merged_tc_ = merge_fixture - merged_cell = cell.merge(other_cell) - cell._tc.merge.assert_called_once_with(other_cell._tc) - assert isinstance(merged_cell, _Cell) - assert merged_cell._tc is merged_tc_ - assert merged_cell._parent is cell._parent - # fixtures ------------------------------------------------------- +class Describe_Cell: + """Unit-test suite for `docx.table._Cell` objects.""" - @pytest.fixture( - params=[ - ("w:tc", "w:tc/w:p"), - ("w:tc/w:p", "w:tc/(w:p, w:p)"), - ("w:tc/w:tbl", "w:tc/(w:tbl, w:p)"), - ] + @pytest.mark.parametrize( + ("tc_cxml", "expected_value"), + [ + ("w:tc", 1), + ("w:tc/w:tcPr", 1), + ("w:tc/w:tcPr/w:gridSpan{w:val=1}", 1), + ("w:tc/w:tcPr/w:gridSpan{w:val=4}", 4), + ], ) - def add_paragraph_fixture(self, request): - tc_cxml, after_tc_cxml = request.param - cell = _Cell(element(tc_cxml), None) - expected_xml = xml(after_tc_cxml) - return cell, expected_xml + def it_knows_its_grid_span(self, tc_cxml: str, expected_value: int, parent_: Mock): + cell = _Cell(cast(CT_Tc, element(tc_cxml)), parent_) + assert cell.grid_span == expected_value - @pytest.fixture - def add_table_fixture(self, request): - cell = _Cell(element("w:tc/w:p"), None) - expected_xml = snippet_seq("new-tbl")[1] - return cell, expected_xml + @pytest.mark.parametrize( + ("tc_cxml", "expected_text"), + [ + ("w:tc", ""), + ('w:tc/w:p/w:r/w:t"foobar"', "foobar"), + ('w:tc/(w:p/w:r/w:t"foo",w:p/w:r/w:t"bar")', "foo\nbar"), + ('w:tc/(w:tcPr,w:p/w:r/w:t"foobar")', "foobar"), + ('w:tc/w:p/w:r/(w:t"fo",w:tab,w:t"ob",w:br,w:t"ar",w:br)', "fo\tob\nar\n"), + ], + ) + def it_knows_what_text_it_contains(self, tc_cxml: str, expected_text: str, parent_: Mock): + cell = _Cell(cast(CT_Tc, element(tc_cxml)), parent_) + text = cell.text + assert text == expected_text - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("tc_cxml", "new_text", "expected_cxml"), + [ + ("w:tc/w:p", "foobar", 'w:tc/w:p/w:r/w:t"foobar"'), + ( + "w:tc/w:p", + "fo\tob\rar\n", + 'w:tc/w:p/w:r/(w:t"fo",w:tab,w:t"ob",w:br,w:t"ar",w:br)', + ), + ( + "w:tc/(w:tcPr, w:p, w:tbl, w:p)", + "foobar", + 'w:tc/(w:tcPr, w:p/w:r/w:t"foobar")', + ), + ], + ) + def it_can_replace_its_content_with_a_string_of_text( + self, tc_cxml: str, new_text: str, expected_cxml: str, parent_: Mock + ): + cell = _Cell(cast(CT_Tc, element(tc_cxml)), parent_) + cell.text = new_text + assert cell._tc.xml == xml(expected_cxml) + + @pytest.mark.parametrize( + ("tc_cxml", "expected_value"), + [ ("w:tc", None), ("w:tc/w:tcPr", None), ("w:tc/w:tcPr/w:vAlign{w:val=bottom}", WD_ALIGN_VERTICAL.BOTTOM), ("w:tc/w:tcPr/w:vAlign{w:val=top}", WD_ALIGN_VERTICAL.TOP), - ] + ], ) - def alignment_get_fixture(self, request): - tc_cxml, expected_value = request.param - cell = _Cell(element(tc_cxml), None) - return cell, expected_value - - @pytest.fixture( - params=[ + def it_knows_its_vertical_alignment( + self, tc_cxml: str, expected_value: WD_ALIGN_VERTICAL | None, parent_: Mock + ): + cell = _Cell(cast(CT_Tc, element(tc_cxml)), parent_) + assert cell.vertical_alignment == expected_value + + @pytest.mark.parametrize( + ("tc_cxml", "new_value", "expected_cxml"), + [ ("w:tc", WD_ALIGN_VERTICAL.TOP, "w:tc/w:tcPr/w:vAlign{w:val=top}"), ( "w:tc/w:tcPr", @@ -474,330 +409,300 @@ def alignment_get_fixture(self, request): ("w:tc/w:tcPr/w:vAlign{w:val=center}", None, "w:tc/w:tcPr"), ("w:tc", None, "w:tc/w:tcPr"), ("w:tc/w:tcPr", None, "w:tc/w:tcPr"), - ] + ], ) - def alignment_set_fixture(self, request): - cxml, new_value, expected_cxml = request.param - cell = _Cell(element(cxml), None) - expected_xml = xml(expected_cxml) - return cell, new_value, expected_xml - - @pytest.fixture - def merge_fixture(self, tc_, tc_2_, parent_, merged_tc_): - cell, other_cell = _Cell(tc_, parent_), _Cell(tc_2_, parent_) - tc_.merge.return_value = merged_tc_ - return cell, other_cell, merged_tc_ - - @pytest.fixture - def paragraphs_fixture(self): - return _Cell(element("w:tc/(w:p, w:p)"), None) - - @pytest.fixture( - params=[ - ("w:tc", 0), - ("w:tc/w:tbl", 1), - ("w:tc/(w:tbl,w:tbl)", 2), - ("w:tc/(w:p,w:tbl)", 1), - ("w:tc/(w:tbl,w:tbl,w:p)", 2), - ] - ) - def tables_fixture(self, request): - cell_cxml, expected_count = request.param - cell = _Cell(element(cell_cxml), None) - return cell, expected_count - - @pytest.fixture( - params=[ - ("w:tc", ""), - ('w:tc/w:p/w:r/w:t"foobar"', "foobar"), - ('w:tc/(w:p/w:r/w:t"foo",w:p/w:r/w:t"bar")', "foo\nbar"), - ('w:tc/(w:tcPr,w:p/w:r/w:t"foobar")', "foobar"), - ('w:tc/w:p/w:r/(w:t"fo",w:tab,w:t"ob",w:br,w:t"ar",w:br)', "fo\tob\nar\n"), - ] - ) - def text_get_fixture(self, request): - tc_cxml, expected_text = request.param - cell = _Cell(element(tc_cxml), None) - return cell, expected_text + def it_can_change_its_vertical_alignment( + self, tc_cxml: str, new_value: WD_ALIGN_VERTICAL | None, expected_cxml: str, parent_: Mock + ): + cell = _Cell(cast(CT_Tc, element(tc_cxml)), parent_) + cell.vertical_alignment = new_value + assert cell._element.xml == xml(expected_cxml) - @pytest.fixture( - params=[ - ("w:tc/w:p", "foobar", 'w:tc/w:p/w:r/w:t"foobar"'), - ( - "w:tc/w:p", - "fo\tob\rar\n", - 'w:tc/w:p/w:r/(w:t"fo",w:tab,w:t"ob",w:br,w:t"ar",w:br)', - ), - ( - "w:tc/(w:tcPr, w:p, w:tbl, w:p)", - "foobar", - 'w:tc/(w:tcPr, w:p/w:r/w:t"foobar")', - ), - ] - ) - def text_set_fixture(self, request): - tc_cxml, new_text, expected_cxml = request.param - cell = _Cell(element(tc_cxml), None) - expected_xml = xml(expected_cxml) - return cell, new_text, expected_xml - - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("tc_cxml", "expected_value"), + [ ("w:tc", None), ("w:tc/w:tcPr", None), ("w:tc/w:tcPr/w:tcW{w:w=25%,w:type=pct}", None), ("w:tc/w:tcPr/w:tcW{w:w=1440,w:type=dxa}", 914400), - ] + ], ) - def width_get_fixture(self, request): - tc_cxml, expected_width = request.param - cell = _Cell(element(tc_cxml), None) - return cell, expected_width + def it_knows_its_width_in_EMU(self, tc_cxml: str, expected_value: int | None, parent_: Mock): + cell = _Cell(cast(CT_Tc, element(tc_cxml)), parent_) + assert cell.width == expected_value - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("tc_cxml", "new_value", "expected_cxml"), + [ ("w:tc", Inches(1), "w:tc/w:tcPr/w:tcW{w:w=1440,w:type=dxa}"), ( "w:tc/w:tcPr/w:tcW{w:w=25%,w:type=pct}", Inches(2), "w:tc/w:tcPr/w:tcW{w:w=2880,w:type=dxa}", ), - ] + ], + ) + def it_can_change_its_width( + self, tc_cxml: str, new_value: Length, expected_cxml: str, parent_: Mock + ): + cell = _Cell(cast(CT_Tc, element(tc_cxml)), parent_) + cell.width = new_value + assert cell.width == new_value + assert cell._tc.xml == xml(expected_cxml) + + def it_provides_access_to_the_paragraphs_it_contains(self, parent_: Mock): + cell = _Cell(cast(CT_Tc, element("w:tc/(w:p, w:p)")), parent_) + + paragraphs = cell.paragraphs + + # -- every w:p produces a Paragraph instance -- + assert len(paragraphs) == 2 + assert all(isinstance(p, Paragraph) for p in paragraphs) + # -- the return value is iterable and indexable -- + assert all(p is paragraphs[idx] for idx, p in enumerate(paragraphs)) + + @pytest.mark.parametrize( + ("tc_cxml", "expected_table_count"), + [ + ("w:tc", 0), + ("w:tc/w:tbl", 1), + ("w:tc/(w:tbl,w:tbl)", 2), + ("w:tc/(w:p,w:tbl)", 1), + ("w:tc/(w:tbl,w:tbl,w:p)", 2), + ], + ) + def it_provides_access_to_the_tables_it_contains( + self, tc_cxml: str, expected_table_count: int, parent_: Mock + ): + cell = _Cell(cast(CT_Tc, element(tc_cxml)), parent_) + + tables = cell.tables + + # --- test len(), iterable, and indexed access + assert len(tables) == expected_table_count + assert all(isinstance(t, Table) for t in tables) + assert all(t is tables[idx] for idx, t in enumerate(tables)) + + @pytest.mark.parametrize( + ("tc_cxml", "expected_cxml"), + [ + ("w:tc", "w:tc/w:p"), + ("w:tc/w:p", "w:tc/(w:p, w:p)"), + ("w:tc/w:tbl", "w:tc/(w:tbl, w:p)"), + ], ) - def width_set_fixture(self, request): - tc_cxml, new_value, expected_cxml = request.param - cell = _Cell(element(tc_cxml), None) - expected_xml = xml(expected_cxml) - return cell, new_value, expected_xml + def it_can_add_a_paragraph(self, tc_cxml: str, expected_cxml: str, parent_: Mock): + cell = _Cell(cast(CT_Tc, element(tc_cxml)), parent_) + + p = cell.add_paragraph() + + assert isinstance(p, Paragraph) + assert cell._tc.xml == xml(expected_cxml) - # fixture components --------------------------------------------- + def it_can_add_a_table(self, parent_: Mock): + cell = _Cell(cast(CT_Tc, element("w:tc/w:p")), parent_) + + table = cell.add_table(rows=2, cols=2) + + assert isinstance(table, Table) + assert cell._element.xml == snippet_seq("new-tbl")[1] + + def it_can_merge_itself_with_other_cells( + self, tc_: Mock, tc_2_: Mock, parent_: Mock, merged_tc_: Mock + ): + cell, other_cell = _Cell(tc_, parent_), _Cell(tc_2_, parent_) + tc_.merge.return_value = merged_tc_ + + merged_cell = cell.merge(other_cell) + + assert isinstance(merged_cell, _Cell) + tc_.merge.assert_called_once_with(other_cell._tc) + assert merged_cell._tc is merged_tc_ + assert merged_cell._parent is cell._parent + + # fixtures ------------------------------------------------------- @pytest.fixture - def merged_tc_(self, request): + def merged_tc_(self, request: FixtureRequest): return instance_mock(request, CT_Tc) @pytest.fixture - def parent_(self, request): + def parent_(self, request: FixtureRequest): return instance_mock(request, Table) @pytest.fixture - def tc_(self, request): + def tc_(self, request: FixtureRequest): return instance_mock(request, CT_Tc) @pytest.fixture - def tc_2_(self, request): + def tc_2_(self, request: FixtureRequest): return instance_mock(request, CT_Tc) -class Describe_Column(object): - def it_provides_access_to_its_cells(self, cells_fixture): - column, column_idx, expected_cells = cells_fixture - cells = column.cells - column.table.column_cells.assert_called_once_with(column_idx) - assert cells == expected_cells - - def it_provides_access_to_the_table_it_belongs_to(self, table_fixture): - column, table_ = table_fixture - assert column.table is table_ - - def it_knows_its_width_in_EMU(self, width_get_fixture): - column, expected_width = width_get_fixture - assert column.width == expected_width - - def it_can_change_its_width(self, width_set_fixture): - column, value, expected_xml = width_set_fixture - column.width = value - assert column.width == value - assert column._gridCol.xml == expected_xml +class Describe_Column: + """Unit-test suite for `docx.table._Cell` objects.""" - def it_knows_its_index_in_table_to_help(self, index_fixture): - column, expected_idx = index_fixture - assert column._index == expected_idx + def it_provides_access_to_its_cells(self, _index_prop_: Mock, table_prop_: Mock, table_: Mock): + table_prop_.return_value = table_ + _index_prop_.return_value = 4 + column = _Column(cast(CT_TblGridCol, element("w:gridCol{w:w=500}")), table_) + table_.column_cells.return_value = [3, 2, 1] - # fixtures ------------------------------------------------------- + cells = column.cells - @pytest.fixture - def cells_fixture(self, _index_, table_prop_, table_): - column = _Column(None, None) - _index_.return_value = column_idx = 4 - expected_cells = (3, 2, 1) - table_.column_cells.return_value = list(expected_cells) - return column, column_idx, expected_cells + table_.column_cells.assert_called_once_with(4) + assert cells == (3, 2, 1) - @pytest.fixture - def index_fixture(self): - tbl = element("w:tbl/w:tblGrid/(w:gridCol,w:gridCol,w:gridCol)") - gridCol, expected_idx = tbl.tblGrid[1], 1 - column = _Column(gridCol, None) - return column, expected_idx + def it_provides_access_to_the_table_it_belongs_to(self, table_: Mock): + table_.table = table_ + column = _Column(cast(CT_TblGridCol, element("w:gridCol{w:w=500}")), table_) - @pytest.fixture - def table_fixture(self, parent_, table_): - column = _Column(None, parent_) - parent_.table = table_ - return column, table_ + assert column.table is table_ - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("gridCol_cxml", "expected_width"), + [ ("w:gridCol{w:w=4242}", 2693670), ("w:gridCol{w:w=1440}", 914400), ("w:gridCol{w:w=2.54cm}", 914400), ("w:gridCol{w:w=54mm}", 1944000), ("w:gridCol{w:w=12.5pt}", 158750), ("w:gridCol", None), - ] + ], ) - def width_get_fixture(self, request): - gridCol_cxml, expected_width = request.param - column = _Column(element(gridCol_cxml), None) - return column, expected_width - - @pytest.fixture( - params=[ - ("w:gridCol", 914400, "w:gridCol{w:w=1440}"), - ("w:gridCol{w:w=4242}", 457200, "w:gridCol{w:w=720}"), + def it_knows_its_width_in_EMU( + self, gridCol_cxml: str, expected_width: int | None, table_: Mock + ): + column = _Column(cast(CT_TblGridCol, element(gridCol_cxml)), table_) + assert column.width == expected_width + + @pytest.mark.parametrize( + ("gridCol_cxml", "new_value", "expected_cxml"), + [ + ("w:gridCol", Emu(914400), "w:gridCol{w:w=1440}"), + ("w:gridCol{w:w=4242}", Inches(0.5), "w:gridCol{w:w=720}"), ("w:gridCol{w:w=4242}", None, "w:gridCol"), ("w:gridCol", None, "w:gridCol"), - ] + ], ) - def width_set_fixture(self, request): - gridCol_cxml, new_value, expected_cxml = request.param - column = _Column(element(gridCol_cxml), None) - expected_xml = xml(expected_cxml) - return column, new_value, expected_xml + def it_can_change_its_width( + self, gridCol_cxml: str, new_value: Length | None, expected_cxml: str, table_: Mock + ): + column = _Column(cast(CT_TblGridCol, element(gridCol_cxml)), table_) - # fixture components --------------------------------------------- + column.width = new_value + + assert column.width == new_value + assert column._gridCol.xml == xml(expected_cxml) + + def it_knows_its_index_in_table_to_help(self, table_: Mock): + tbl = cast(CT_Tbl, element("w:tbl/w:tblGrid/(w:gridCol,w:gridCol,w:gridCol)")) + gridCol = tbl.tblGrid.gridCol_lst[1] + column = _Column(gridCol, table_) + assert column._index == 1 + + # fixtures ------------------------------------------------------- @pytest.fixture - def _index_(self, request): + def _index_prop_(self, request: FixtureRequest): return property_mock(request, _Column, "_index") @pytest.fixture - def parent_(self, request): + def parent_(self, request: FixtureRequest): return instance_mock(request, Table) @pytest.fixture - def table_(self, request): + def table_(self, request: FixtureRequest): return instance_mock(request, Table) @pytest.fixture - def table_prop_(self, request, table_): - return property_mock(request, _Column, "table", return_value=table_) - - -class Describe_Columns(object): - def it_knows_how_many_columns_it_contains(self, columns_fixture): - columns, column_count = columns_fixture - assert len(columns) == column_count - - def it_can_interate_over_its__Column_instances(self, columns_fixture): - columns, column_count = columns_fixture - actual_count = 0 - for column in columns: - assert isinstance(column, _Column) - actual_count += 1 - assert actual_count == column_count - - def it_provides_indexed_access_to_columns(self, columns_fixture): - columns, column_count = columns_fixture - for idx in range(-column_count, column_count): - column = columns[idx] - assert isinstance(column, _Column) - - def it_raises_on_indexed_access_out_of_range(self, columns_fixture): - columns, column_count = columns_fixture - too_low = -1 - column_count - too_high = column_count - with pytest.raises(IndexError): - columns[too_low] - with pytest.raises(IndexError): - columns[too_high] + def table_prop_(self, request: FixtureRequest): + return property_mock(request, _Column, "table") - def it_provides_access_to_the_table_it_belongs_to(self, table_fixture): - columns, table_ = table_fixture - assert columns.table is table_ - # fixtures ------------------------------------------------------- +class Describe_Columns: + """Unit-test suite for `docx.table._Columns` objects.""" - @pytest.fixture - def columns_fixture(self): - column_count = 2 - tbl = _tbl_bldr(rows=2, cols=column_count).element - columns = _Columns(tbl, None) - return columns, column_count + def it_has_sequence_behaviors(self, table_: Mock): + columns = _Columns(cast(CT_Tbl, element("w:tbl/w:tblGrid/(w:gridCol,w:gridCol)")), table_) - @pytest.fixture - def table_fixture(self, table_): - columns = _Columns(None, table_) - table_.table = table_ - return columns, table_ - - # fixture components --------------------------------------------- - - @pytest.fixture - def table_(self, request): - return instance_mock(request, Table) + # -- it supports len() -- + assert len(columns) == 2 + # -- it is iterable -- + assert len(tuple(c for c in columns)) == 2 + assert all(type(c) is _Column for c in columns) + # -- it is indexable -- + assert all(type(columns[i]) is _Column for i in range(2)) + def it_raises_on_indexed_access_out_of_range(self, table_: Mock): + columns = _Columns(cast(CT_Tbl, element("w:tbl/w:tblGrid/(w:gridCol,w:gridCol)")), table_) -class Describe_Row(object): - def it_knows_its_height(self, height_get_fixture): - row, expected_height = height_get_fixture - assert row.height == expected_height - - def it_can_change_its_height(self, height_set_fixture): - row, value, expected_xml = height_set_fixture - row.height = value - assert row._tr.xml == expected_xml + with pytest.raises(IndexError): + columns[2] + with pytest.raises(IndexError): + columns[-3] - def it_knows_its_height_rule(self, height_rule_get_fixture): - row, expected_rule = height_rule_get_fixture - assert row.height_rule == expected_rule + def it_provides_access_to_the_table_it_belongs_to(self, table_: Mock): + columns = _Columns(cast(CT_Tbl, element("w:tbl")), table_) + table_.table = table_ - def it_can_change_its_height_rule(self, height_rule_set_fixture): - row, rule, expected_xml = height_rule_set_fixture - row.height_rule = rule - assert row._tr.xml == expected_xml + assert columns.table is table_ - def it_provides_access_to_its_cells(self, cells_fixture): - row, row_idx, expected_cells = cells_fixture - cells = row.cells - row.table.row_cells.assert_called_once_with(row_idx) - assert cells == expected_cells + # fixtures ------------------------------------------------------- - def it_provides_access_to_the_table_it_belongs_to(self, table_fixture): - row, table_ = table_fixture - assert row.table is table_ + @pytest.fixture + def table_(self, request: FixtureRequest): + return instance_mock(request, Table) - def it_knows_its_index_in_table_to_help(self, idx_fixture): - row, expected_idx = idx_fixture - assert row._index == expected_idx - # fixtures ------------------------------------------------------- +class Describe_Row: + """Unit-test suite for `docx.table._Row` objects.""" - @pytest.fixture - def cells_fixture(self, _index_, table_prop_, table_): - row = _Row(None, None) - _index_.return_value = row_idx = 6 - expected_cells = (1, 2, 3) - table_.row_cells.return_value = list(expected_cells) - return row, row_idx, expected_cells - - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("tr_cxml", "expected_value"), + [ + ("w:tr", 0), + ("w:tr/w:trPr", 0), + ("w:tr/w:trPr/w:gridAfter{w:val=0}", 0), + ("w:tr/w:trPr/w:gridAfter{w:val=4}", 4), + ], + ) + def it_knows_its_grid_cols_after(self, tr_cxml: str, expected_value: int | None, parent_: Mock): + row = _Row(cast(CT_Row, element(tr_cxml)), parent_) + assert row.grid_cols_after == expected_value + + @pytest.mark.parametrize( + ("tr_cxml", "expected_value"), + [ + ("w:tr", 0), + ("w:tr/w:trPr", 0), + ("w:tr/w:trPr/w:gridBefore{w:val=0}", 0), + ("w:tr/w:trPr/w:gridBefore{w:val=3}", 3), + ], + ) + def it_knows_its_grid_cols_before( + self, tr_cxml: str, expected_value: int | None, parent_: Mock + ): + row = _Row(cast(CT_Row, element(tr_cxml)), parent_) + assert row.grid_cols_before == expected_value + + @pytest.mark.parametrize( + ("tr_cxml", "expected_value"), + [ ("w:tr", None), ("w:tr/w:trPr", None), ("w:tr/w:trPr/w:trHeight", None), ("w:tr/w:trPr/w:trHeight{w:val=0}", 0), ("w:tr/w:trPr/w:trHeight{w:val=1440}", 914400), - ] + ], ) - def height_get_fixture(self, request): - tr_cxml, expected_height = request.param - row = _Row(element(tr_cxml), None) - return row, expected_height + def it_knows_its_height(self, tr_cxml: str, expected_value: int | None, parent_: Mock): + row = _Row(cast(CT_Row, element(tr_cxml)), parent_) + assert row.height == expected_value - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("tr_cxml", "new_value", "expected_cxml"), + [ ("w:tr", Inches(1), "w:tr/w:trPr/w:trHeight{w:val=1440}"), ("w:tr/w:trPr", Inches(1), "w:tr/w:trPr/w:trHeight{w:val=1440}"), ("w:tr/w:trPr/w:trHeight", Inches(1), "w:tr/w:trPr/w:trHeight{w:val=1440}"), @@ -810,16 +715,18 @@ def height_get_fixture(self, request): ("w:tr", None, "w:tr/w:trPr"), ("w:tr/w:trPr", None, "w:tr/w:trPr"), ("w:tr/w:trPr/w:trHeight", None, "w:tr/w:trPr/w:trHeight"), - ] + ], ) - def height_set_fixture(self, request): - tr_cxml, new_value, expected_cxml = request.param - row = _Row(element(tr_cxml), None) - expected_xml = xml(expected_cxml) - return row, new_value, expected_xml - - @pytest.fixture( - params=[ + def it_can_change_its_height( + self, tr_cxml: str, new_value: Length | None, expected_cxml: str, parent_: Mock + ): + row = _Row(cast(CT_Row, element(tr_cxml)), parent_) + row.height = new_value + assert row._tr.xml == xml(expected_cxml) + + @pytest.mark.parametrize( + ("tr_cxml", "expected_value"), + [ ("w:tr", None), ("w:tr/w:trPr", None), ("w:tr/w:trPr/w:trHeight{w:val=0, w:hRule=auto}", WD_ROW_HEIGHT.AUTO), @@ -831,15 +738,17 @@ def height_set_fixture(self, request): "w:tr/w:trPr/w:trHeight{w:val=2880, w:hRule=exact}", WD_ROW_HEIGHT.EXACTLY, ), - ] + ], ) - def height_rule_get_fixture(self, request): - tr_cxml, expected_rule = request.param - row = _Row(element(tr_cxml), None) - return row, expected_rule - - @pytest.fixture( - params=[ + def it_knows_its_height_rule( + self, tr_cxml: str, expected_value: WD_ROW_HEIGHT | None, parent_: Mock + ): + row = _Row(cast(CT_Row, element(tr_cxml)), parent_) + assert row.height_rule == expected_value + + @pytest.mark.parametrize( + ("tr_cxml", "new_value", "expected_cxml"), + [ ("w:tr", WD_ROW_HEIGHT.AUTO, "w:tr/w:trPr/w:trHeight{w:hRule=auto}"), ( "w:tr/w:trPr", @@ -864,142 +773,148 @@ def height_rule_get_fixture(self, request): ("w:tr", None, "w:tr/w:trPr"), ("w:tr/w:trPr", None, "w:tr/w:trPr"), ("w:tr/w:trPr/w:trHeight", None, "w:tr/w:trPr/w:trHeight"), - ] + ], + ) + def it_can_change_its_height_rule( + self, tr_cxml: str, new_value: WD_ROW_HEIGHT | None, expected_cxml: str, parent_: Mock + ): + row = _Row(cast(CT_Row, element(tr_cxml)), parent_) + row.height_rule = new_value + assert row._tr.xml == xml(expected_cxml) + + @pytest.mark.parametrize( + ("tbl_cxml", "row_idx", "expected_len"), + [ + # -- cell corresponds to single layout-grid cell -- + ("w:tbl/w:tr/w:tc/w:p", 0, 1), + # -- cell has a horizontal span -- + ("w:tbl/w:tr/w:tc/(w:tcPr/w:gridSpan{w:val=2},w:p)", 0, 2), + # -- cell is in latter row of vertical span -- + ( + "w:tbl/(w:tr/w:tc/(w:tcPr/w:vMerge{w:val=restart},w:p)," + "w:tr/w:tc/(w:tcPr/w:vMerge,w:p))", + 1, + 1, + ), + # -- cell both has horizontal span and is latter row of vertical span -- + ( + "w:tbl/(w:tr/w:tc/(w:tcPr/(w:gridSpan{w:val=2},w:vMerge{w:val=restart}),w:p)," + "w:tr/w:tc/(w:tcPr/(w:gridSpan{w:val=2},w:vMerge),w:p))", + 1, + 2, + ), + ], ) - def height_rule_set_fixture(self, request): - tr_cxml, new_rule, expected_cxml = request.param - row = _Row(element(tr_cxml), None) - expected_xml = xml(expected_cxml) - return row, new_rule, expected_xml + def it_provides_access_to_its_cells( + self, tbl_cxml: str, row_idx: int, expected_len: int, parent_: Mock + ): + tbl = cast(CT_Tbl, element(tbl_cxml)) + tr = tbl.tr_lst[row_idx] + table = Table(tbl, parent_) + row = _Row(tr, table) - @pytest.fixture - def idx_fixture(self): - tbl = element("w:tbl/(w:tr,w:tr,w:tr)") - tr, expected_idx = tbl[1], 1 - row = _Row(tr, None) - return row, expected_idx + cells = row.cells - @pytest.fixture - def table_fixture(self, parent_, table_): - row = _Row(None, parent_) + assert len(cells) == expected_len + assert all(type(c) is _Cell for c in cells) + + def it_provides_access_to_the_table_it_belongs_to(self, parent_: Mock, table_: Mock): parent_.table = table_ - return row, table_ + row = _Row(cast(CT_Row, element("w:tr")), parent_) + assert row.table is table_ - # fixture components --------------------------------------------- + def it_knows_its_index_in_table_to_help(self, parent_: Mock): + tbl = element("w:tbl/(w:tr,w:tr,w:tr)") + row = _Row(cast(CT_Row, tbl[1]), parent_) + assert row._index == 1 + + # fixtures ------------------------------------------------------- @pytest.fixture - def _index_(self, request): + def _index_prop_(self, request: FixtureRequest): return property_mock(request, _Row, "_index") @pytest.fixture - def parent_(self, request): + def parent_(self, request: FixtureRequest): return instance_mock(request, Table) @pytest.fixture - def table_(self, request): + def table_(self, request: FixtureRequest): return instance_mock(request, Table) @pytest.fixture - def table_prop_(self, request, table_): - return property_mock(request, _Row, "table", return_value=table_) + def table_prop_(self, request: FixtureRequest, table_: Mock): + return property_mock(request, _Row, "table") -class Describe_Rows(object): - def it_knows_how_many_rows_it_contains(self, rows_fixture): - rows, row_count = rows_fixture - assert len(rows) == row_count +class Describe_Rows: + """Unit-test suite for `docx.table._Rows` objects.""" - def it_can_iterate_over_its__Row_instances(self, rows_fixture): - rows, row_count = rows_fixture - actual_count = 0 - for row in rows: - assert isinstance(row, _Row) - actual_count += 1 - assert actual_count == row_count + @pytest.mark.parametrize( + ("tbl_cxml", "expected_len"), + [ + ("w:tbl", 0), + ("w:tbl/w:tr", 1), + ("w:tbl/(w:tr,w:tr)", 2), + ("w:tbl/(w:tr,w:tr,w:tr)", 3), + ], + ) + def it_has_sequence_behaviors(self, tbl_cxml: str, expected_len: int, parent_: Mock): + tbl = cast(CT_Tbl, element(tbl_cxml)) + table = Table(tbl, parent_) + rows = _Rows(tbl, table) + + # -- it supports len() -- + assert len(rows) == expected_len + # -- it is iterable -- + assert len(tuple(r for r in rows)) == expected_len + assert all(type(r) is _Row for r in rows) + # -- it is indexable -- + assert all(type(rows[i]) is _Row for i in range(expected_len)) + + @pytest.mark.parametrize( + ("tbl_cxml", "out_of_range_idx"), + [ + ("w:tbl", 0), + ("w:tbl", 1), + ("w:tbl", -1), + ("w:tbl/w:tr", 1), + ("w:tbl/w:tr", -2), + ("w:tbl/(w:tr,w:tr,w:tr)", 3), + ("w:tbl/(w:tr,w:tr,w:tr)", -4), + ], + ) + def it_raises_on_indexed_access_out_of_range( + self, tbl_cxml: str, out_of_range_idx: int, parent_: Mock + ): + rows = _Rows(cast(CT_Tbl, element(tbl_cxml)), parent_) - def it_provides_indexed_access_to_rows(self, rows_fixture): - rows, row_count = rows_fixture - for idx in range(-row_count, row_count): - row = rows[idx] - assert isinstance(row, _Row) + with pytest.raises(IndexError, match="list index out of range"): + rows[out_of_range_idx] + + @pytest.mark.parametrize(("start", "end", "expected_len"), [(1, 3, 2), (0, -1, 2)]) + def it_provides_sliced_access_to_rows( + self, start: int, end: int, expected_len: int, parent_: Mock + ): + tbl = cast(CT_Tbl, element("w:tbl/(w:tr,w:tr,w:tr)")) + rows = _Rows(tbl, parent_) - def it_provides_sliced_access_to_rows(self, slice_fixture): - rows, start, end, expected_count = slice_fixture slice_of_rows = rows[start:end] - assert len(slice_of_rows) == expected_count - tr_lst = rows._tbl.tr_lst + + assert len(slice_of_rows) == expected_len for idx, row in enumerate(slice_of_rows): - assert tr_lst.index(row._tr) == start + idx + assert tbl.tr_lst.index(row._tr) == start + idx assert isinstance(row, _Row) - def it_raises_on_indexed_access_out_of_range(self, rows_fixture): - rows, row_count = rows_fixture - with pytest.raises(IndexError): - too_low = -1 - row_count - rows[too_low] - with pytest.raises(IndexError): - too_high = row_count - rows[too_high] + def it_provides_access_to_the_table_it_belongs_to(self, parent_: Mock): + tbl = cast(CT_Tbl, element("w:tbl")) + table = Table(tbl, parent_) + rows = _Rows(tbl, table) - def it_provides_access_to_the_table_it_belongs_to(self, table_fixture): - rows, table_ = table_fixture - assert rows.table is table_ + assert rows.table is table # fixtures ------------------------------------------------------- @pytest.fixture - def rows_fixture(self): - row_count = 2 - tbl = _tbl_bldr(rows=row_count, cols=2).element - rows = _Rows(tbl, None) - return rows, row_count - - @pytest.fixture( - params=[ - (3, 1, 3, 2), - (3, 0, -1, 2), - ] - ) - def slice_fixture(self, request): - row_count, start, end, expected_count = request.param - tbl = _tbl_bldr(rows=row_count, cols=2).element - rows = _Rows(tbl, None) - return rows, start, end, expected_count - - @pytest.fixture - def table_fixture(self, table_): - rows = _Rows(None, table_) - table_.table = table_ - return rows, table_ - - # fixture components --------------------------------------------- - - @pytest.fixture - def table_(self, request): - return instance_mock(request, Table) - - -# fixtures ----------------------------------------------------------- - - -def _tbl_bldr(rows, cols): - tblGrid_bldr = a_tblGrid() - for i in range(cols): - tblGrid_bldr.with_child(a_gridCol()) - tbl_bldr = a_tbl().with_nsdecls().with_child(tblGrid_bldr) - for i in range(rows): - tr_bldr = _tr_bldr(cols) - tbl_bldr.with_child(tr_bldr) - return tbl_bldr - - -def _tc_bldr(): - return a_tc().with_child(a_p()) - - -def _tr_bldr(cols): - tr_bldr = a_tr() - for i in range(cols): - tc_bldr = _tc_bldr() - tr_bldr.with_child(tc_bldr) - return tr_bldr + def parent_(self, request: FixtureRequest): + return instance_mock(request, Document) diff --git a/tests/text/test_font.py b/tests/text/test_font.py index 46149bc0..4edd632b 100644 --- a/tests/text/test_font.py +++ b/tests/text/test_font.py @@ -1,96 +1,137 @@ -# encoding: utf-8 +# pyright: reportPrivateUsage=false -""" -Test suite for the docx.text.run module -""" +"""Test suite for the docx.text.run module.""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import annotations + +from typing import cast + +import pytest +from _pytest.fixtures import FixtureRequest from docx.dml.color import ColorFormat from docx.enum.text import WD_COLOR, WD_UNDERLINE -from docx.shared import Pt +from docx.oxml.text.run import CT_R +from docx.shared import Length, Pt from docx.text.font import Font -import pytest - from ..unitutil.cxml import element, xml -from ..unitutil.mock import class_mock, instance_mock +from ..unitutil.mock import Mock, class_mock, instance_mock + +class DescribeFont: + """Unit-test suite for `docx.text.font.Font`.""" + + def it_provides_access_to_its_color_object(self, ColorFormat_: Mock, color_: Mock): + r = cast(CT_R, element("w:r")) + font = Font(r) -class DescribeFont(object): - def it_provides_access_to_its_color_object(self, color_fixture): - font, color_, ColorFormat_ = color_fixture color = font.color + ColorFormat_.assert_called_once_with(font.element) assert color is color_ - def it_knows_its_typeface_name(self, name_get_fixture): - font, expected_value = name_get_fixture - assert font.name == expected_value + @pytest.mark.parametrize( + ("r_cxml", "expected_ascii", "expected_hAnsi", "expected_eastAsia"), + [ + ("w:r", None, None, None), + ("w:r/w:rPr", None, None, None), + ("w:r/w:rPr/w:rFonts", None, None, None), + ("w:r/w:rPr/w:rFonts{w:ascii=Arial}", "Arial", None, None), + ("w:r/w:rPr/w:rFonts{w:hAnsi=Arial}", None, "Arial", None), + ("w:r/w:rPr/w:rFonts{w:eastAsia=Arial}", None, None, "Arial"), + ], + ) + def it_knows_its_typeface_name( + self, r_cxml: str, expected_ascii: str | None, expected_hAnsi: str | None, expected_eastAsia: str | None + ): + r = cast(CT_R, element(r_cxml)) + font = Font(r) + assert font.name == expected_ascii + assert font.hAnsi == expected_hAnsi + assert font.eastAsia == expected_eastAsia + + @pytest.mark.parametrize( + ("r_cxml", "value", "expected_r_cxml"), + [ + ("w:r", "Foo", "w:r/w:rPr/w:rFonts{w:ascii=Foo,w:hAnsi=Foo,w:eastAsia=Foo}"), + ("w:r/w:rPr", "Foo", "w:r/w:rPr/w:rFonts{w:ascii=Foo,w:hAnsi=Foo,w:eastAsia=Foo}"), + ( + "w:r/w:rPr/w:rFonts{w:hAnsi=Foo}", + "Bar", + "w:r/w:rPr/w:rFonts{w:ascii=Bar,w:hAnsi=Bar,w:eastAsia=Bar}", + ), + ( + "w:r/w:rPr/w:rFonts{w:ascii=Foo,w:hAnsi=Foo}", + "Bar", + "w:r/w:rPr/w:rFonts{w:ascii=Bar,w:hAnsi=Bar,w:eastAsia=Bar}", + ), + ( + "w:r/w:rPr/w:rFonts{w:ascii=Foo,w:eastAsia=Foo}", + "Bar", + "w:r/w:rPr/w:rFonts{w:ascii=Bar,w:hAnsi=Bar,w:eastAsia=Bar}", + ), + ( + "w:r/w:rPr/w:rFonts{w:hAnsi=Foo,w:eastAsia=Foo}", + "Bar", + "w:r/w:rPr/w:rFonts{w:ascii=Bar,w:hAnsi=Bar,w:eastAsia=Bar}", + ), + # Dictionary format tests + ( + "w:r", + {"ascii": "Arial", "hAnsi": "Times New Roman", "eastAsia": "Microsoft YaHei"}, + "w:r/w:rPr/w:rFonts{w:ascii=Arial,w:hAnsi='Times New Roman',w:eastAsia='Microsoft YaHei'}", + ), + ( + "w:r/w:rPr/w:rFonts{w:ascii=Foo}", + {"hAnsi": "Bar", "eastAsia": "Baz"}, + "w:r/w:rPr/w:rFonts{w:ascii=Foo,w:hAnsi=Bar,w:eastAsia=Baz}", + ), + ], + ) + def it_can_change_its_typeface_name(self, r_cxml: str, value: str | dict[str, str | None], expected_r_cxml: str): + r = cast(CT_R, element(r_cxml)) + font = Font(r) + expected_xml = xml(expected_r_cxml) - def it_can_change_its_typeface_name(self, name_set_fixture): - font, value, expected_xml = name_set_fixture font.name = value - assert font._element.xml == expected_xml - def it_knows_its_size(self, size_get_fixture): - font, expected_value = size_get_fixture - assert font.size == expected_value - - def it_can_change_its_size(self, size_set_fixture): - font, value, expected_xml = size_set_fixture - font.size = value assert font._element.xml == expected_xml - def it_knows_its_bool_prop_states(self, bool_prop_get_fixture): - font, prop_name, expected_state = bool_prop_get_fixture - assert getattr(font, prop_name) == expected_state - - def it_can_change_its_bool_prop_settings(self, bool_prop_set_fixture): - font, prop_name, value, expected_xml = bool_prop_set_fixture - setattr(font, prop_name, value) - assert font._element.xml == expected_xml - - def it_knows_whether_it_is_subscript(self, subscript_get_fixture): - font, expected_value = subscript_get_fixture - assert font.subscript == expected_value - - def it_can_change_whether_it_is_subscript(self, subscript_set_fixture): - font, value, expected_xml = subscript_set_fixture - font.subscript = value - assert font._element.xml == expected_xml - - def it_knows_whether_it_is_superscript(self, superscript_get_fixture): - font, expected_value = superscript_get_fixture - assert font.superscript == expected_value - - def it_can_change_whether_it_is_superscript(self, superscript_set_fixture): - font, value, expected_xml = superscript_set_fixture - font.superscript = value - assert font._element.xml == expected_xml - - def it_knows_its_underline_type(self, underline_get_fixture): - font, expected_value = underline_get_fixture - assert font.underline is expected_value + @pytest.mark.parametrize( + ("r_cxml", "expected_value"), + [ + ("w:r", None), + ("w:r/w:rPr", None), + ("w:r/w:rPr/w:sz{w:val=28}", Pt(14)), + ], + ) + def it_knows_its_size(self, r_cxml: str, expected_value: Length | None): + r = cast(CT_R, element(r_cxml)) + font = Font(r) + assert font.size == expected_value - def it_can_change_its_underline_type(self, underline_set_fixture): - font, underline, expected_xml = underline_set_fixture - font.underline = underline - assert font._element.xml == expected_xml + @pytest.mark.parametrize( + ("r_cxml", "value", "expected_r_cxml"), + [ + ("w:r", Pt(12), "w:r/w:rPr/w:sz{w:val=24}"), + ("w:r/w:rPr", Pt(12), "w:r/w:rPr/w:sz{w:val=24}"), + ("w:r/w:rPr/w:sz{w:val=24}", Pt(18), "w:r/w:rPr/w:sz{w:val=36}"), + ("w:r/w:rPr/w:sz{w:val=36}", None, "w:r/w:rPr"), + ], + ) + def it_can_change_its_size(self, r_cxml: str, value: Length | None, expected_r_cxml: str): + r = cast(CT_R, element(r_cxml)) + font = Font(r) + expected_xml = xml(expected_r_cxml) - def it_knows_its_highlight_color(self, highlight_get_fixture): - font, expected_value = highlight_get_fixture - assert font.highlight_color is expected_value + font.size = value - def it_can_change_its_highlight_color(self, highlight_set_fixture): - font, highlight_color, expected_xml = highlight_set_fixture - font.highlight_color = highlight_color assert font._element.xml == expected_xml - # fixtures ------------------------------------------------------- - - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("r_cxml", "bool_prop_name", "expected_value"), + [ ("w:r/w:rPr", "all_caps", None), ("w:r/w:rPr/w:caps", "all_caps", True), ("w:r/w:rPr/w:caps{w:val=on}", "all_caps", True), @@ -115,15 +156,18 @@ def it_can_change_its_highlight_color(self, highlight_set_fixture): ("w:r/w:rPr/w:specVanish{w:val=off}", "spec_vanish", False), ("w:r/w:rPr/w:strike{w:val=1}", "strike", True), ("w:r/w:rPr/w:webHidden{w:val=0}", "web_hidden", False), - ] + ], ) - def bool_prop_get_fixture(self, request): - r_cxml, bool_prop_name, expected_value = request.param - font = Font(element(r_cxml)) - return font, bool_prop_name, expected_value - - @pytest.fixture( - params=[ + def it_knows_its_bool_prop_states( + self, r_cxml: str, bool_prop_name: str, expected_value: bool | None + ): + r = cast(CT_R, element(r_cxml)) + font = Font(r) + assert getattr(font, bool_prop_name) == expected_value + + @pytest.mark.parametrize( + ("r_cxml", "prop_name", "value", "expected_cxml"), + [ # nothing to True, False, and None --------------------------- ("w:r", "all_caps", True, "w:r/w:rPr/w:caps"), ("w:r", "bold", False, "w:r/w:rPr/w:b{w:val=0}"), @@ -180,141 +224,37 @@ def bool_prop_get_fixture(self, request): False, "w:r/w:rPr/w:webHidden{w:val=0}", ), - ] - ) - def bool_prop_set_fixture(self, request): - r_cxml, prop_name, value, expected_cxml = request.param - font = Font(element(r_cxml)) - expected_xml = xml(expected_cxml) - return font, prop_name, value, expected_xml - - @pytest.fixture - def color_fixture(self, ColorFormat_, color_): - font = Font(element("w:r")) - return font, color_, ColorFormat_ - - @pytest.fixture( - params=[ - ("w:r", None), - ("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), - ] - ) - def highlight_get_fixture(self, request): - r_cxml, expected_value = request.param - font = Font(element(r_cxml), None) - return font, expected_value - - @pytest.fixture( - params=[ - ("w:r", WD_COLOR.AUTO, "w:r/w:rPr/w:highlight{w:val=default}"), - ("w:r/w:rPr", WD_COLOR.BRIGHT_GREEN, "w:r/w:rPr/w:highlight{w:val=green}"), - ( - "w:r/w:rPr/w:highlight{w:val=green}", - WD_COLOR.YELLOW, - "w:r/w:rPr/w:highlight{w:val=yellow}", - ), - ("w:r/w:rPr/w:highlight{w:val=yellow}", None, "w:r/w:rPr"), - ("w:r/w:rPr", None, "w:r/w:rPr"), - ("w:r", None, "w:r/w:rPr"), - ] + ], ) - def highlight_set_fixture(self, request): - r_cxml, value, expected_cxml = request.param - font = Font(element(r_cxml), None) + def it_can_change_its_bool_prop_settings( + self, r_cxml: str, prop_name: str, value: bool | None, expected_cxml: str + ): + r = cast(CT_R, element(r_cxml)) + font = Font(r) expected_xml = xml(expected_cxml) - return font, value, expected_xml - - @pytest.fixture( - params=[ - ("w:r", {'ascii': None, 'hAnsi': None, 'eastAsia': None}), - ("w:r/w:rPr", {'ascii': None, 'hAnsi': None, 'eastAsia': None}), - ("w:r/w:rPr/w:rFonts", {'ascii': None, 'hAnsi': None, 'eastAsia': None}), - ("w:r/w:rPr/w:rFonts{w:ascii=Arial}", {'ascii': "Arial", 'hAnsi': None, 'eastAsia': None}), - ("w:r/w:rPr/w:rFonts{w:hAnsi=Arial}", {'ascii': None, 'hAnsi': "Arial", 'eastAsia': None}), - ("w:r/w:rPr/w:rFonts{w:eastAsia=Arial}", {'ascii': None, 'hAnsi': None, 'eastAsia': "Arial"}), - ] - ) - def name_get_fixture(self, request): - r_cxml, expected_value = request.param - font = Font(element(r_cxml)) - return font, expected_value - @pytest.fixture( - params=[ - ("w:r", "Foo", "w:r/w:rPr/w:rFonts{w:ascii=Foo,w:hAnsi=Foo,w:eastAsia=Foo}"), - ("w:r/w:rPr", "Foo", "w:r/w:rPr/w:rFonts{w:ascii=Foo,w:hAnsi=Foo,w:eastAsia=Foo}"), - ( - "w:r/w:rPr/w:rFonts{w:hAnsi=Foo}", - "Bar", - "w:r/w:rPr/w:rFonts{w:ascii=Bar,w:hAnsi=Bar,w:eastAsia=Bar}", - ), - ( - "w:r/w:rPr/w:rFonts{w:ascii=Foo,w:hAnsi=Foo}", - "Bar", - "w:r/w:rPr/w:rFonts{w:ascii=Bar,w:hAnsi=Bar,w:eastAsia=Bar}", - ), - ( - "w:r/w:rPr/w:rFonts{w:ascii=Foo,w:eastAsia=Foo}", - "Bar", - "w:r/w:rPr/w:rFonts{w:ascii=Bar,w:hAnsi=Bar,w:eastAsia=Bar}", - ), - ( - "w:r/w:rPr/w:rFonts{w:hAnsi=Foo,w:eastAsia=Foo}", - "Bar", - "w:r/w:rPr/w:rFonts{w:ascii=Bar,w:hAnsi=Bar,w:eastAsia=Bar}", - ), - ] - ) - def name_set_fixture(self, request): - r_cxml, value, expected_r_cxml = request.param - font = Font(element(r_cxml)) - expected_xml = xml(expected_r_cxml) - return font, value, expected_xml - - @pytest.fixture( - params=[ - ("w:r", None), - ("w:r/w:rPr", None), - ("w:r/w:rPr/w:sz{w:val=28}", Pt(14)), - ] - ) - def size_get_fixture(self, request): - r_cxml, expected_value = request.param - font = Font(element(r_cxml)) - return font, expected_value + setattr(font, prop_name, value) - @pytest.fixture( - params=[ - ("w:r", Pt(12), "w:r/w:rPr/w:sz{w:val=24}"), - ("w:r/w:rPr", Pt(12), "w:r/w:rPr/w:sz{w:val=24}"), - ("w:r/w:rPr/w:sz{w:val=24}", Pt(18), "w:r/w:rPr/w:sz{w:val=36}"), - ("w:r/w:rPr/w:sz{w:val=36}", None, "w:r/w:rPr"), - ] - ) - def size_set_fixture(self, request): - r_cxml, value, expected_r_cxml = request.param - font = Font(element(r_cxml)) - expected_xml = xml(expected_r_cxml) - return font, value, expected_xml + assert font._element.xml == expected_xml - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("r_cxml", "expected_value"), + [ ("w:r", None), ("w:r/w:rPr", None), ("w:r/w:rPr/w:vertAlign{w:val=baseline}", False), ("w:r/w:rPr/w:vertAlign{w:val=subscript}", True), ("w:r/w:rPr/w:vertAlign{w:val=superscript}", False), - ] + ], ) - def subscript_get_fixture(self, request): - r_cxml, expected_value = request.param - font = Font(element(r_cxml)) - return font, expected_value + def it_knows_whether_it_is_subscript(self, r_cxml: str, expected_value: bool | None): + r = cast(CT_R, element(r_cxml)) + font = Font(r) + assert font.subscript == expected_value - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("r_cxml", "value", "expected_r_cxml"), + [ ("w:r", True, "w:r/w:rPr/w:vertAlign{w:val=subscript}"), ("w:r", False, "w:r/w:rPr"), ("w:r", None, "w:r/w:rPr"), @@ -341,30 +281,37 @@ def subscript_get_fixture(self, request): True, "w:r/w:rPr/w:vertAlign{w:val=subscript}", ), - ] + ], ) - def subscript_set_fixture(self, request): - r_cxml, value, expected_r_cxml = request.param - font = Font(element(r_cxml)) + def it_can_change_whether_it_is_subscript( + self, r_cxml: str, value: bool | None, expected_r_cxml: str + ): + r = cast(CT_R, element(r_cxml)) + font = Font(r) expected_xml = xml(expected_r_cxml) - return font, value, expected_xml - @pytest.fixture( - params=[ + font.subscript = value + + assert font._element.xml == expected_xml + + @pytest.mark.parametrize( + ("r_cxml", "expected_value"), + [ ("w:r", None), ("w:r/w:rPr", None), ("w:r/w:rPr/w:vertAlign{w:val=baseline}", False), ("w:r/w:rPr/w:vertAlign{w:val=subscript}", False), ("w:r/w:rPr/w:vertAlign{w:val=superscript}", True), - ] + ], ) - def superscript_get_fixture(self, request): - r_cxml, expected_value = request.param - font = Font(element(r_cxml)) - return font, expected_value + def it_knows_whether_it_is_superscript(self, r_cxml: str, expected_value: bool | None): + r = cast(CT_R, element(r_cxml)) + font = Font(r) + assert font.superscript == expected_value - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("r_cxml", "value", "expected_r_cxml"), + [ ("w:r", True, "w:r/w:rPr/w:vertAlign{w:val=superscript}"), ("w:r", False, "w:r/w:rPr"), ("w:r", None, "w:r/w:rPr"), @@ -391,31 +338,38 @@ def superscript_get_fixture(self, request): True, "w:r/w:rPr/w:vertAlign{w:val=superscript}", ), - ] + ], ) - def superscript_set_fixture(self, request): - r_cxml, value, expected_r_cxml = request.param - font = Font(element(r_cxml)) + def it_can_change_whether_it_is_superscript( + self, r_cxml: str, value: bool | None, expected_r_cxml: str + ): + r = cast(CT_R, element(r_cxml)) + font = Font(r) expected_xml = xml(expected_r_cxml) - return font, value, expected_xml - @pytest.fixture( - params=[ + font.superscript = value + + assert font._element.xml == expected_xml + + @pytest.mark.parametrize( + ("r_cxml", "expected_value"), + [ ("w:r", None), ("w:r/w:rPr/w:u", None), ("w:r/w:rPr/w:u{w:val=single}", True), ("w:r/w:rPr/w:u{w:val=none}", False), ("w:r/w:rPr/w:u{w:val=double}", WD_UNDERLINE.DOUBLE), ("w:r/w:rPr/w:u{w:val=wave}", WD_UNDERLINE.WAVY), - ] + ], ) - def underline_get_fixture(self, request): - r_cxml, expected_value = request.param - run = Font(element(r_cxml), None) - return run, expected_value + def it_knows_its_underline_type(self, r_cxml: str, expected_value: WD_UNDERLINE | bool | None): + r = cast(CT_R, element(r_cxml)) + font = Font(r) + assert font.underline is expected_value - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("r_cxml", "value", "expected_r_cxml"), + [ ("w:r", True, "w:r/w:rPr/w:u{w:val=single}"), ("w:r", False, "w:r/w:rPr/w:u{w:val=none}"), ("w:r", None, "w:r/w:rPr"), @@ -434,20 +388,65 @@ def underline_get_fixture(self, request): WD_UNDERLINE.DOTTED, "w:r/w:rPr/w:u{w:val=dotted}", ), - ] + ], ) - def underline_set_fixture(self, request): - initial_r_cxml, value, expected_cxml = request.param - run = Font(element(initial_r_cxml), None) - expected_xml = xml(expected_cxml) - return run, value, expected_xml + def it_can_change_its_underline_type( + self, r_cxml: str, value: bool | None, expected_r_cxml: str + ): + r = cast(CT_R, element(r_cxml)) + font = Font(r) + expected_xml = xml(expected_r_cxml) + + font.underline = value + + assert font._element.xml == expected_xml + + @pytest.mark.parametrize( + ("r_cxml", "expected_value"), + [ + ("w:r", None), + ("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), + ], + ) + def it_knows_its_highlight_color(self, r_cxml: str, expected_value: WD_COLOR | None): + r = cast(CT_R, element(r_cxml)) + font = Font(r) + assert font.highlight_color is expected_value + + @pytest.mark.parametrize( + ("r_cxml", "value", "expected_r_cxml"), + [ + ("w:r", WD_COLOR.AUTO, "w:r/w:rPr/w:highlight{w:val=default}"), + ("w:r/w:rPr", WD_COLOR.BRIGHT_GREEN, "w:r/w:rPr/w:highlight{w:val=green}"), + ( + "w:r/w:rPr/w:highlight{w:val=green}", + WD_COLOR.YELLOW, + "w:r/w:rPr/w:highlight{w:val=yellow}", + ), + ("w:r/w:rPr/w:highlight{w:val=yellow}", None, "w:r/w:rPr"), + ("w:r/w:rPr", None, "w:r/w:rPr"), + ("w:r", None, "w:r/w:rPr"), + ], + ) + def it_can_change_its_highlight_color( + self, r_cxml: str, value: WD_COLOR | None, expected_r_cxml: str + ): + r = cast(CT_R, element(r_cxml)) + font = Font(r) + expected_xml = xml(expected_r_cxml) + + font.highlight_color = value + + assert font._element.xml == expected_xml - # fixture components --------------------------------------------- + # -- fixtures ---------------------------------------------------- @pytest.fixture - def color_(self, request): + def color_(self, request: FixtureRequest): return instance_mock(request, ColorFormat) @pytest.fixture - def ColorFormat_(self, request, color_): + def ColorFormat_(self, request: FixtureRequest, color_: Mock): return class_mock(request, "docx.text.font.ColorFormat", return_value=color_) diff --git a/tests/text/test_hyperlink.py b/tests/text/test_hyperlink.py new file mode 100644 index 00000000..0cb97715 --- /dev/null +++ b/tests/text/test_hyperlink.py @@ -0,0 +1,149 @@ +"""Test suite for the docx.text.hyperlink module.""" + +from typing import cast + +import pytest + +from docx import types as t +from docx.opc.rel import _Relationship # pyright: ignore[reportPrivateUsage] +from docx.oxml.text.hyperlink import CT_Hyperlink +from docx.parts.story import StoryPart +from docx.text.hyperlink import Hyperlink + +from ..unitutil.cxml import element +from ..unitutil.mock import FixtureRequest, Mock, instance_mock + + +class DescribeHyperlink: + """Unit-test suite for the docx.text.hyperlink.Hyperlink object.""" + + @pytest.mark.parametrize( + ("hlink_cxml", "expected_value"), + [ + ('w:hyperlink{r:id=rId6}/w:r/w:t"post"', "https://google.com/"), + ("w:hyperlink{w:anchor=_Toc147925734}", ""), + ("w:hyperlink", ""), + ], + ) + def it_knows_the_hyperlink_address( + self, hlink_cxml: str, expected_value: str, fake_parent: t.ProvidesStoryPart + ): + hlink = cast(CT_Hyperlink, element(hlink_cxml)) + hyperlink = Hyperlink(hlink, fake_parent) + + assert hyperlink.address == expected_value + + @pytest.mark.parametrize( + ("hlink_cxml", "expected_value"), + [ + ("w:hyperlink", False), + ("w:hyperlink/w:r", False), + ('w:hyperlink/w:r/(w:t"abc",w:lastRenderedPageBreak,w:t"def")', True), + ('w:hyperlink/w:r/(w:lastRenderedPageBreak,w:t"abc",w:t"def")', True), + ('w:hyperlink/w:r/(w:t"abc",w:t"def",w:lastRenderedPageBreak)', True), + ], + ) + def it_knows_whether_it_contains_a_page_break( + self, hlink_cxml: str, expected_value: bool, fake_parent: t.ProvidesStoryPart + ): + hlink = cast(CT_Hyperlink, element(hlink_cxml)) + hyperlink = Hyperlink(hlink, fake_parent) + + assert hyperlink.contains_page_break is expected_value + + @pytest.mark.parametrize( + ("hlink_cxml", "expected_value"), + [ + ("w:hyperlink{r:id=rId6}", ""), + ("w:hyperlink{w:anchor=intro}", "intro"), + ], + ) + def it_knows_the_link_fragment_when_there_is_one( + self, hlink_cxml: str, expected_value: str, fake_parent: t.ProvidesStoryPart + ): + hlink = cast(CT_Hyperlink, element(hlink_cxml)) + hyperlink = Hyperlink(hlink, fake_parent) + + assert hyperlink.fragment == expected_value + + @pytest.mark.parametrize( + ("hlink_cxml", "count"), + [ + ("w:hyperlink", 0), + ("w:hyperlink/w:r", 1), + ("w:hyperlink/(w:r,w:r)", 2), + ("w:hyperlink/(w:r,w:lastRenderedPageBreak)", 1), + ("w:hyperlink/(w:lastRenderedPageBreak,w:r)", 1), + ("w:hyperlink/(w:r,w:lastRenderedPageBreak,w:r)", 2), + ], + ) + def it_provides_access_to_the_runs_it_contains( + self, hlink_cxml: str, count: int, fake_parent: t.ProvidesStoryPart + ): + hlink = cast(CT_Hyperlink, element(hlink_cxml)) + hyperlink = Hyperlink(hlink, fake_parent) + + runs = hyperlink.runs + + actual = [type(item).__name__ for item in runs] + expected = ["Run" for _ in range(count)] + assert actual == expected + + @pytest.mark.parametrize( + ("hlink_cxml", "expected_text"), + [ + ("w:hyperlink", ""), + ("w:hyperlink/w:r", ""), + ('w:hyperlink/w:r/w:t"foobar"', "foobar"), + ('w:hyperlink/w:r/(w:t"foo",w:lastRenderedPageBreak,w:t"bar")', "foobar"), + ('w:hyperlink/w:r/(w:t"abc",w:tab,w:t"def",w:noBreakHyphen)', "abc\tdef-"), + ], + ) + def it_knows_the_visible_text_of_the_link( + self, hlink_cxml: str, expected_text: str, fake_parent: t.ProvidesStoryPart + ): + hlink = cast(CT_Hyperlink, element(hlink_cxml)) + hyperlink = Hyperlink(hlink, fake_parent) + + text = hyperlink.text + + assert text == expected_text + + @pytest.mark.parametrize( + ("hlink_cxml", "expected_value"), + [ + ("w:hyperlink", ""), + ("w:hyperlink{w:anchor=_Toc147925734}", ""), + ('w:hyperlink{r:id=rId6}/w:r/w:t"post"', "https://google.com/"), + ( + 'w:hyperlink{r:id=rId6,w:anchor=foo}/w:r/w:t"post"', + "https://google.com/#foo", + ), + ], + ) + def it_knows_the_full_url_for_web_addresses( + self, hlink_cxml: str, expected_value: str, fake_parent: t.ProvidesStoryPart + ): + hlink = cast(CT_Hyperlink, element(hlink_cxml)) + hyperlink = Hyperlink(hlink, fake_parent) + + assert hyperlink.url == expected_value + + # -- fixtures -------------------------------------------------------------------- + + @pytest.fixture + def fake_parent(self, story_part: Mock, rel: Mock) -> t.ProvidesStoryPart: + class StoryChild: + @property + def part(self) -> StoryPart: + return story_part + + return StoryChild() + + @pytest.fixture + def rel(self, request: FixtureRequest): + return instance_mock(request, _Relationship, target_ref="https://google.com/") + + @pytest.fixture + def story_part(self, request: FixtureRequest, rel: Mock): + return instance_mock(request, StoryPart, rels={"rId6": rel}) diff --git a/tests/text/test_pagebreak.py b/tests/text/test_pagebreak.py new file mode 100644 index 00000000..bc784879 --- /dev/null +++ b/tests/text/test_pagebreak.py @@ -0,0 +1,141 @@ +# pyright: reportPrivateUsage=false + +"""Unit-test suite for the docx.text.pagebreak module.""" + +from typing import cast + +import pytest + +from docx import types as t +from docx.oxml.text.paragraph import CT_P +from docx.text.pagebreak import RenderedPageBreak + +from ..unitutil.cxml import element, xml + + +class DescribeRenderedPageBreak: + """Unit-test suite for the docx.text.pagebreak.RenderedPageBreak object.""" + + def it_raises_on_preceding_fragment_when_page_break_is_not_first_in_paragrah( + self, fake_parent: t.ProvidesStoryPart + ): + p_cxml = 'w:p/(w:r/(w:t"abc",w:lastRenderedPageBreak,w:lastRenderedPageBreak))' + p = cast(CT_P, element(p_cxml)) + lrpb = p.lastRenderedPageBreaks[-1] + page_break = RenderedPageBreak(lrpb, fake_parent) + + with pytest.raises(ValueError, match="only defined on first rendered page-br"): + page_break.preceding_paragraph_fragment + + def it_produces_None_for_preceding_fragment_when_page_break_is_leading( + self, fake_parent: t.ProvidesStoryPart + ): + """A page-break with no preceding content is "leading".""" + p_cxml = 'w:p/(w:pPr/w:ind,w:r/(w:lastRenderedPageBreak,w:t"foo",w:t"bar"))' + p = cast(CT_P, element(p_cxml)) + lrpb = p.lastRenderedPageBreaks[0] + page_break = RenderedPageBreak(lrpb, fake_parent) + + preceding_fragment = page_break.preceding_paragraph_fragment + + assert preceding_fragment is None + + def it_can_split_off_the_preceding_paragraph_content_when_in_a_run( + self, fake_parent: t.ProvidesStoryPart + ): + p_cxml = ( + "w:p/(" + " w:pPr/w:ind" + ' ,w:r/(w:t"foo",w:lastRenderedPageBreak,w:t"bar")' + ' ,w:r/w:t"barfoo"' + ")" + ) + p = cast(CT_P, element(p_cxml)) + lrpb = p.lastRenderedPageBreaks[0] + page_break = RenderedPageBreak(lrpb, fake_parent) + + preceding_fragment = page_break.preceding_paragraph_fragment + + expected_cxml = 'w:p/(w:pPr/w:ind,w:r/w:t"foo")' + assert preceding_fragment is not None + assert preceding_fragment._p.xml == xml(expected_cxml) + + def and_it_can_split_off_the_preceding_paragraph_content_when_in_a_hyperlink( + self, fake_parent: t.ProvidesStoryPart + ): + p_cxml = ( + "w:p/(" + " w:pPr/w:ind" + ' ,w:hyperlink/w:r/(w:t"foo",w:lastRenderedPageBreak,w:t"bar")' + ' ,w:r/w:t"barfoo"' + ")" + ) + p = cast(CT_P, element(p_cxml)) + lrpb = p.lastRenderedPageBreaks[0] + page_break = RenderedPageBreak(lrpb, fake_parent) + + preceding_fragment = page_break.preceding_paragraph_fragment + + expected_cxml = 'w:p/(w:pPr/w:ind,w:hyperlink/w:r/(w:t"foo",w:t"bar"))' + assert preceding_fragment is not None + assert preceding_fragment._p.xml == xml(expected_cxml) + + def it_raises_on_following_fragment_when_page_break_is_not_first_in_paragrah( + self, fake_parent: t.ProvidesStoryPart + ): + p_cxml = 'w:p/(w:r/(w:lastRenderedPageBreak,w:lastRenderedPageBreak,w:t"abc"))' + p = cast(CT_P, element(p_cxml)) + lrpb = p.lastRenderedPageBreaks[-1] + page_break = RenderedPageBreak(lrpb, fake_parent) + + with pytest.raises(ValueError, match="only defined on first rendered page-br"): + page_break.following_paragraph_fragment + + def it_produces_None_for_following_fragment_when_page_break_is_trailing( + self, fake_parent: t.ProvidesStoryPart + ): + """A page-break with no following content is "trailing".""" + p_cxml = 'w:p/(w:pPr/w:ind,w:r/(w:t"foo",w:t"bar",w:lastRenderedPageBreak))' + p = cast(CT_P, element(p_cxml)) + lrpb = p.lastRenderedPageBreaks[0] + page_break = RenderedPageBreak(lrpb, fake_parent) + + following_fragment = page_break.following_paragraph_fragment + + assert following_fragment is None + + def it_can_split_off_the_following_paragraph_content_when_in_a_run( + self, fake_parent: t.ProvidesStoryPart + ): + p_cxml = 'w:p/(w:pPr/w:ind,w:r/(w:t"foo",w:lastRenderedPageBreak,w:t"bar"),w:r/w:t"foo")' + p = cast(CT_P, element(p_cxml)) + lrpb = p.lastRenderedPageBreaks[0] + page_break = RenderedPageBreak(lrpb, fake_parent) + + following_fragment = page_break.following_paragraph_fragment + + expected_cxml = 'w:p/(w:pPr/w:ind,w:r/w:t"bar",w:r/w:t"foo")' + assert following_fragment is not None + assert following_fragment._p.xml == xml(expected_cxml) + + def and_it_can_split_off_the_following_paragraph_content_when_in_a_hyperlink( + self, fake_parent: t.ProvidesStoryPart + ): + p_cxml = ( + "w:p/(" + " w:pPr/w:ind" + ' ,w:hyperlink/w:r/(w:t"foo",w:lastRenderedPageBreak,w:t"bar")' + ' ,w:r/w:t"baz"' + ' ,w:r/w:t"qux"' + ")" + ) + p = cast(CT_P, element(p_cxml)) + lrpb = p.lastRenderedPageBreaks[0] + page_break = RenderedPageBreak(lrpb, fake_parent) + + following_fragment = page_break.following_paragraph_fragment + + expected_cxml = 'w:p/(w:pPr/w:ind,w:r/w:t"baz",w:r/w:t"qux")' + + assert following_fragment is not None + assert following_fragment._p.xml == xml(expected_cxml) diff --git a/tests/text/test_paragraph.py b/tests/text/test_paragraph.py index e394334e..0329b1dd 100644 --- a/tests/text/test_paragraph.py +++ b/tests/text/test_paragraph.py @@ -1,9 +1,10 @@ -# encoding: utf-8 +"""Unit test suite for the docx.text.paragraph module.""" -"""Unit test suite for the docx.text.paragraph module""" +from typing import List, cast -from __future__ import absolute_import, division, print_function, unicode_literals +import pytest +from docx import types as t from docx.enum.style import WD_STYLE_TYPE from docx.enum.text import WD_ALIGN_PARAGRAPH from docx.oxml.text.paragraph import CT_P @@ -13,19 +14,78 @@ from docx.text.parfmt import ParagraphFormat from docx.text.run import Run -import pytest - from ..unitutil.cxml import element, xml from ..unitutil.mock import call, class_mock, instance_mock, method_mock, property_mock -class DescribeParagraph(object): +class DescribeParagraph: + """Unit-test suite for `docx.text.run.Paragraph`.""" + + @pytest.mark.parametrize( + ("p_cxml", "expected_value"), + [ + ("w:p/w:r", False), + ('w:p/w:r/w:t"foobar"', False), + ('w:p/w:hyperlink/w:r/(w:t"abc",w:lastRenderedPageBreak,w:t"def")', True), + ("w:p/w:r/(w:lastRenderedPageBreak, w:lastRenderedPageBreak)", True), + ], + ) + def it_knows_whether_it_contains_a_page_break( + self, p_cxml: str, expected_value: bool, fake_parent: t.ProvidesStoryPart + ): + p = cast(CT_P, element(p_cxml)) + paragraph = Paragraph(p, fake_parent) + + assert paragraph.contains_page_break == expected_value + + @pytest.mark.parametrize( + ("p_cxml", "count"), + [ + ("w:p", 0), + ("w:p/w:r", 0), + ("w:p/w:hyperlink", 1), + ("w:p/(w:r,w:hyperlink,w:r)", 1), + ("w:p/(w:r,w:hyperlink,w:r,w:hyperlink)", 2), + ("w:p/(w:hyperlink,w:r,w:hyperlink,w:r)", 2), + ], + ) + def it_provides_access_to_the_hyperlinks_it_contains( + self, p_cxml: str, count: int, fake_parent: t.ProvidesStoryPart + ): + p = cast(CT_P, element(p_cxml)) + paragraph = Paragraph(p, fake_parent) + + hyperlinks = paragraph.hyperlinks + + actual = [type(item).__name__ for item in hyperlinks] + expected = ["Hyperlink" for _ in range(count)] + assert actual == expected, f"expected: {expected}, got: {actual}" + + @pytest.mark.parametrize( + ("p_cxml", "expected"), + [ + ("w:p", []), + ("w:p/w:r", ["Run"]), + ("w:p/w:hyperlink", ["Hyperlink"]), + ("w:p/(w:r,w:hyperlink,w:r)", ["Run", "Hyperlink", "Run"]), + ("w:p/(w:hyperlink,w:r,w:hyperlink)", ["Hyperlink", "Run", "Hyperlink"]), + ], + ) + def it_can_iterate_its_inner_content_items( + self, p_cxml: str, expected: List[str], fake_parent: t.ProvidesStoryPart + ): + p = cast(CT_P, element(p_cxml)) + paragraph = Paragraph(p, fake_parent) + + inner_content = paragraph.iter_inner_content() + + actual = [type(item).__name__ for item in inner_content] + assert actual == expected, f"expected: {expected}, got: {actual}" + def it_knows_its_paragraph_style(self, style_get_fixture): paragraph, style_id_, style_ = style_get_fixture style = paragraph.style - paragraph.part.get_style.assert_called_once_with( - style_id_, WD_STYLE_TYPE.PARAGRAPH - ) + paragraph.part.get_style.assert_called_once_with(style_id_, WD_STYLE_TYPE.PARAGRAPH) assert style is style_ def it_can_change_its_paragraph_style(self, style_set_fixture): @@ -33,14 +93,61 @@ def it_can_change_its_paragraph_style(self, style_set_fixture): paragraph.style = value - paragraph.part.get_style_id.assert_called_once_with( - value, WD_STYLE_TYPE.PARAGRAPH - ) + paragraph.part.get_style_id.assert_called_once_with(value, WD_STYLE_TYPE.PARAGRAPH) assert paragraph._p.xml == expected_xml - def it_knows_the_text_it_contains(self, text_get_fixture): - paragraph, expected_text = text_get_fixture - assert paragraph.text == expected_text + @pytest.mark.parametrize( + ("p_cxml", "count"), + [ + ("w:p", 0), + ("w:p/w:r", 0), + ("w:p/w:r/w:lastRenderedPageBreak", 1), + ("w:p/w:hyperlink/w:r/w:lastRenderedPageBreak", 1), + ( + "w:p/(w:r/w:lastRenderedPageBreak,w:hyperlink/w:r/w:lastRenderedPageBreak)", + 2, + ), + ( + "w:p/(w:hyperlink/w:r/w:lastRenderedPageBreak,w:r," + "w:r/w:lastRenderedPageBreak,w:r,w:hyperlink)", + 2, + ), + ], + ) + def it_provides_access_to_the_rendered_page_breaks_it_contains( + self, p_cxml: str, count: int, fake_parent: t.ProvidesStoryPart + ): + p = cast(CT_P, element(p_cxml)) + paragraph = Paragraph(p, fake_parent) + + rendered_page_breaks = paragraph.rendered_page_breaks + + actual = [type(item).__name__ for item in rendered_page_breaks] + expected = ["RenderedPageBreak" for _ in range(count)] + assert actual == expected, f"expected: {expected}, got: {actual}" + + @pytest.mark.parametrize( + ("p_cxml", "expected_value"), + [ + ("w:p", ""), + ("w:p/w:r", ""), + ("w:p/w:r/w:t", ""), + ('w:p/w:r/w:t"foo"', "foo"), + ('w:p/w:r/(w:t"foo", w:t"bar")', "foobar"), + ('w:p/w:r/(w:t"fo ", w:t"bar")', "fo bar"), + ('w:p/w:r/(w:t"foo", w:tab, w:t"bar")', "foo\tbar"), + ('w:p/w:r/(w:t"foo", w:br, w:t"bar")', "foo\nbar"), + ('w:p/w:r/(w:t"foo", w:cr, w:t"bar")', "foo\nbar"), + ( + 'w:p/(w:r/w:t"click ",w:hyperlink{r:id=rId6}/w:r/w:t"here",w:r/w:t" for more")', + "click here for more", + ), + ], + ) + def it_knows_the_text_it_contains(self, p_cxml: str, expected_value: str): + """Including the text of embedded hyperlinks.""" + paragraph = Paragraph(element(p_cxml), None) + assert paragraph.text == expected_value def it_can_replace_the_text_it_contains(self, text_set_fixture): paragraph, text, expected_text = text_set_fixture @@ -227,24 +334,6 @@ def style_set_fixture(self, request, part_prop_): expected_xml = xml(expected_cxml) return paragraph, value, expected_xml - @pytest.fixture( - params=[ - ("w:p", ""), - ("w:p/w:r", ""), - ("w:p/w:r/w:t", ""), - ('w:p/w:r/w:t"foo"', "foo"), - ('w:p/w:r/(w:t"foo", w:t"bar")', "foobar"), - ('w:p/w:r/(w:t"fo ", w:t"bar")', "fo bar"), - ('w:p/w:r/(w:t"foo", w:tab, w:t"bar")', "foo\tbar"), - ('w:p/w:r/(w:t"foo", w:br, w:t"bar")', "foo\nbar"), - ('w:p/w:r/(w:t"foo", w:cr, w:t"bar")', "foo\nbar"), - ] - ) - def text_get_fixture(self, request): - p_cxml, expected_text_value = request.param - paragraph = Paragraph(element(p_cxml), None) - return paragraph, expected_text_value - @pytest.fixture def text_set_fixture(self): paragraph = Paragraph(element("w:p"), None) @@ -290,9 +379,7 @@ def part_prop_(self, request, document_part_): @pytest.fixture def Run_(self, request, runs_): run_, run_2_ = runs_ - return class_mock( - request, "docx.text.paragraph.Run", side_effect=[run_, run_2_] - ) + return class_mock(request, "docx.text.paragraph.Run", side_effect=[run_, run_2_]) @pytest.fixture def r_(self, request): diff --git a/tests/text/test_parfmt.py b/tests/text/test_parfmt.py index ce992779..be31329e 100644 --- a/tests/text/test_parfmt.py +++ b/tests/text/test_parfmt.py @@ -1,24 +1,17 @@ -# encoding: utf-8 +"""Test suite for docx.text.parfmt module, containing the ParagraphFormat object.""" -""" -Test suite for the docx.text.parfmt module, containing the ParagraphFormat -object. -""" - -from __future__ import absolute_import, division, print_function, unicode_literals +import pytest from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_LINE_SPACING from docx.shared import Pt from docx.text.parfmt import ParagraphFormat from docx.text.tabstops import TabStops -import pytest - from ..unitutil.cxml import element, xml from ..unitutil.mock import class_mock, instance_mock -class DescribeParagraphFormat(object): +class DescribeParagraphFormat: def it_knows_its_alignment_value(self, alignment_get_fixture): paragraph_format, expected_value = alignment_get_fixture assert paragraph_format.alignment == expected_value diff --git a/tests/text/test_run.py b/tests/text/test_run.py index 02cb8741..910f445d 100644 --- a/tests/text/test_run.py +++ b/tests/text/test_run.py @@ -1,237 +1,156 @@ -# encoding: utf-8 +# pyright: reportPrivateUsage=false -"""Test suite for the docx.text.run module""" +"""Test suite for the docx.text.run module.""" -from __future__ import absolute_import, division, print_function, unicode_literals +from __future__ import annotations +from typing import Any, List, cast + +import pytest + +from docx import types as t from docx.enum.style import WD_STYLE_TYPE from docx.enum.text import WD_BREAK, WD_UNDERLINE +from docx.oxml.text.paragraph import CT_P +from docx.oxml.text.run import CT_R from docx.parts.document import DocumentPart from docx.shape import InlineShape from docx.text.font import Font +from docx.text.paragraph import Paragraph from docx.text.run import Run -import pytest - from ..unitutil.cxml import element, xml -from ..unitutil.mock import class_mock, instance_mock, property_mock - - -class DescribeRun(object): - def it_knows_its_bool_prop_states(self, bool_prop_get_fixture): - run, prop_name, expected_state = bool_prop_get_fixture - assert getattr(run, prop_name) == expected_state - - def it_can_change_its_bool_prop_settings(self, bool_prop_set_fixture): - run, prop_name, value, expected_xml = bool_prop_set_fixture - setattr(run, prop_name, value) - assert run._r.xml == expected_xml - - def it_knows_its_character_style(self, style_get_fixture): - run, style_id_, style_ = style_get_fixture - style = run.style - run.part.get_style.assert_called_once_with(style_id_, WD_STYLE_TYPE.CHARACTER) - assert style is style_ - - def it_can_change_its_character_style(self, style_set_fixture): - run, value, expected_xml = style_set_fixture - run.style = value - run.part.get_style_id.assert_called_once_with(value, WD_STYLE_TYPE.CHARACTER) - assert run._r.xml == expected_xml - - def it_knows_its_underline_type(self, underline_get_fixture): - run, expected_value = underline_get_fixture - assert run.underline is expected_value - - def it_can_change_its_underline_type(self, underline_set_fixture): - run, underline, expected_xml = underline_set_fixture - run.underline = underline - assert run._r.xml == expected_xml - - def it_raises_on_assign_invalid_underline_type(self, underline_raise_fixture): - run, underline = underline_raise_fixture - with pytest.raises(ValueError): - run.underline = underline - - def it_provides_access_to_its_font(self, font_fixture): - run, Font_, font_ = font_fixture - font = run.font - Font_.assert_called_once_with(run._element) - assert font is font_ - - def it_can_add_text(self, add_text_fixture, Text_): - r, text_str, expected_xml = add_text_fixture - run = Run(r, None) - - _text = run.add_text(text_str) - - assert run._r.xml == expected_xml - assert _text is Text_.return_value +from ..unitutil.mock import FixtureRequest, Mock, class_mock, instance_mock, property_mock - def it_can_add_a_break(self, add_break_fixture): - run, break_type, expected_xml = add_break_fixture - run.add_break(break_type) - assert run._r.xml == expected_xml - - def it_can_add_a_tab(self, add_tab_fixture): - run, expected_xml = add_tab_fixture - run.add_tab() - assert run._r.xml == expected_xml - def it_can_add_a_picture(self, add_picture_fixture): - run, image, width, height, inline = add_picture_fixture[:5] - expected_xml, InlineShape_, picture_ = add_picture_fixture[5:] - - picture = run.add_picture(image, width, height) +class DescribeRun: + """Unit-test suite for `docx.text.run.Run`.""" - run.part.new_pic_inline.assert_called_once_with(image, width, height) - assert run._r.xml == expected_xml - InlineShape_.assert_called_once_with(inline) - assert picture is picture_ - - def it_can_remove_its_content_but_keep_formatting(self, clear_fixture): - run, expected_xml = clear_fixture - _run = run.clear() - assert run._r.xml == expected_xml - assert _run is run - - def it_knows_the_text_it_contains(self, text_get_fixture): - run, expected_text = text_get_fixture - assert run.text == expected_text - - def it_can_replace_the_text_it_contains(self, text_set_fixture): - run, text, expected_xml = text_set_fixture - run.text = text - assert run._r.xml == expected_xml - - # fixtures ------------------------------------------------------- - - @pytest.fixture( - params=[ - (WD_BREAK.LINE, "w:r/w:br"), - (WD_BREAK.PAGE, "w:r/w:br{w:type=page}"), - (WD_BREAK.COLUMN, "w:r/w:br{w:type=column}"), - (WD_BREAK.LINE_CLEAR_LEFT, "w:r/w:br{w:type=textWrapping, w:clear=left}"), - (WD_BREAK.LINE_CLEAR_RIGHT, "w:r/w:br{w:type=textWrapping, w:clear=right}"), - (WD_BREAK.LINE_CLEAR_ALL, "w:r/w:br{w:type=textWrapping, w:clear=all}"), - ] - ) - def add_break_fixture(self, request): - break_type, expected_cxml = request.param - run = Run(element("w:r"), None) - expected_xml = xml(expected_cxml) - return run, break_type, expected_xml - - @pytest.fixture - def add_picture_fixture(self, part_prop_, document_part_, InlineShape_, picture_): - run = Run(element("w:r/wp:x"), None) - image = "foobar.png" - width, height, inline = 1111, 2222, element("wp:inline{id=42}") - expected_xml = xml("w:r/(wp:x,w:drawing/wp:inline{id=42})") - document_part_.new_pic_inline.return_value = inline - InlineShape_.return_value = picture_ - return (run, image, width, height, inline, expected_xml, InlineShape_, picture_) - - @pytest.fixture( - params=[ - ('w:r/w:t"foo"', 'w:r/(w:t"foo", w:tab)'), - ] - ) - def add_tab_fixture(self, request): - r_cxml, expected_cxml = request.param - run = Run(element(r_cxml), None) - expected_xml = xml(expected_cxml) - return run, expected_xml - - @pytest.fixture( - params=[ - ("w:r", "foo", 'w:r/w:t"foo"'), - ('w:r/w:t"foo"', "bar", 'w:r/(w:t"foo", w:t"bar")'), - ("w:r", "fo ", 'w:r/w:t{xml:space=preserve}"fo "'), - ("w:r", "f o", 'w:r/w:t"f o"'), - ] - ) - def add_text_fixture(self, request): - r_cxml, text, expected_cxml = request.param - r = element(r_cxml) - expected_xml = xml(expected_cxml) - return r, text, expected_xml - - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("r_cxml", "bool_prop_name", "expected_value"), + [ ("w:r/w:rPr", "bold", None), ("w:r/w:rPr/w:b", "bold", True), ("w:r/w:rPr/w:b{w:val=on}", "bold", True), ("w:r/w:rPr/w:b{w:val=off}", "bold", False), ("w:r/w:rPr/w:b{w:val=1}", "bold", True), ("w:r/w:rPr/w:i{w:val=0}", "italic", False), - ] + ], ) - def bool_prop_get_fixture(self, request): - r_cxml, bool_prop_name, expected_value = request.param - run = Run(element(r_cxml), None) - return run, bool_prop_name, expected_value - - @pytest.fixture( - params=[ - # nothing to True, False, and None --------------------------- + def it_knows_its_bool_prop_states( + self, r_cxml: str, bool_prop_name: str, expected_value: bool | None, paragraph_: Mock + ): + run = Run(cast(CT_R, element(r_cxml)), paragraph_) + assert getattr(run, bool_prop_name) == expected_value + + @pytest.mark.parametrize( + ("initial_r_cxml", "bool_prop_name", "value", "expected_cxml"), + [ + # -- nothing to True, False, and None --------------------------- ("w:r", "bold", True, "w:r/w:rPr/w:b"), ("w:r", "bold", False, "w:r/w:rPr/w:b{w:val=0}"), ("w:r", "italic", None, "w:r/w:rPr"), - # default to True, False, and None --------------------------- + # -- default to True, False, and None --------------------------- ("w:r/w:rPr/w:b", "bold", True, "w:r/w:rPr/w:b"), ("w:r/w:rPr/w:b", "bold", False, "w:r/w:rPr/w:b{w:val=0}"), ("w:r/w:rPr/w:i", "italic", None, "w:r/w:rPr"), - # True to True, False, and None ------------------------------ + # -- True to True, False, and None ------------------------------ ("w:r/w:rPr/w:b{w:val=on}", "bold", True, "w:r/w:rPr/w:b"), ("w:r/w:rPr/w:b{w:val=1}", "bold", False, "w:r/w:rPr/w:b{w:val=0}"), ("w:r/w:rPr/w:b{w:val=1}", "bold", None, "w:r/w:rPr"), - # False to True, False, and None ----------------------------- + # -- False to True, False, and None ----------------------------- ("w:r/w:rPr/w:i{w:val=false}", "italic", True, "w:r/w:rPr/w:i"), ("w:r/w:rPr/w:i{w:val=0}", "italic", False, "w:r/w:rPr/w:i{w:val=0}"), ("w:r/w:rPr/w:i{w:val=off}", "italic", None, "w:r/w:rPr"), - ] + ], ) - def bool_prop_set_fixture(self, request): - initial_r_cxml, bool_prop_name, value, expected_cxml = request.param - run = Run(element(initial_r_cxml), None) - expected_xml = xml(expected_cxml) - return run, bool_prop_name, value, expected_xml - - @pytest.fixture( - params=[ - ("w:r", "w:r"), - ('w:r/w:t"foo"', "w:r"), - ("w:r/w:br", "w:r"), - ("w:r/w:rPr", "w:r/w:rPr"), - ('w:r/(w:rPr, w:t"foo")', "w:r/w:rPr"), + def it_can_change_its_bool_prop_settings( + self, + initial_r_cxml: str, + bool_prop_name: str, + value: bool | None, + expected_cxml: str, + paragraph_: Mock, + ): + run = Run(cast(CT_R, element(initial_r_cxml)), paragraph_) + + setattr(run, bool_prop_name, value) + + assert run._r.xml == xml(expected_cxml) + + @pytest.mark.parametrize( + ("r_cxml", "expected_value"), + [ + ("w:r", False), + ('w:r/w:t"foobar"', False), + ('w:r/(w:t"abc", w:lastRenderedPageBreak, w:t"def")', True), + ("w:r/(w:lastRenderedPageBreak, w:lastRenderedPageBreak)", True), + ], + ) + def it_knows_whether_it_contains_a_page_break( + self, r_cxml: str, expected_value: bool, paragraph_: Mock + ): + run = Run(cast(CT_R, element(r_cxml)), paragraph_) + assert run.contains_page_break == expected_value + + @pytest.mark.parametrize( + ("r_cxml", "expected"), + [ + # -- no content produces an empty iterator -- + ("w:r", []), + # -- contiguous text content is condensed into a single str -- + ('w:r/(w:t"foo",w:cr,w:t"bar")', ["str"]), + # -- page-breaks are a form of inner-content -- ( - 'w:r/(w:rPr/(w:b, w:i), w:t"foo", w:cr, w:t"bar")', - "w:r/w:rPr/(w:b, w:i)", + 'w:r/(w:t"abc",w:br,w:lastRenderedPageBreak,w:noBreakHyphen,w:t"def")', + ["str", "RenderedPageBreak", "str"], ), - ] + # -- as are drawings -- + ( + 'w:r/(w:t"abc", w:lastRenderedPageBreak, w:drawing)', + ["str", "RenderedPageBreak", "Drawing"], + ), + ], ) - def clear_fixture(self, request): - initial_r_cxml, expected_cxml = request.param - run = Run(element(initial_r_cxml), None) - expected_xml = xml(expected_cxml) - return run, expected_xml + def it_can_iterate_its_inner_content_items( + self, r_cxml: str, expected: List[str], fake_parent: t.ProvidesStoryPart + ): + r = cast(CT_R, element(r_cxml)) + run = Run(r, fake_parent) + + inner_content = run.iter_inner_content() + + actual = [type(item).__name__ for item in inner_content] + assert actual == expected, f"expected: {expected}, got: {actual}" + + def it_can_mark_a_comment_reference_range(self, paragraph_: Mock): + p = cast(CT_P, element('w:p/w:r/w:t"referenced text"')) + run = last_run = Run(p.r_lst[0], paragraph_) + + run.mark_comment_range(last_run, comment_id=42) + + assert p.xml == xml( + 'w:p/(w:commentRangeStart{w:id=42},w:r/w:t"referenced text"' + ",w:commentRangeEnd{w:id=42}" + ",w:r/(w:rPr/w:rStyle{w:val=CommentReference},w:commentReference{w:id=42}))" + ) + + def it_knows_its_character_style( + self, part_prop_: Mock, document_part_: Mock, paragraph_: Mock + ): + style_ = document_part_.get_style.return_value + part_prop_.return_value = document_part_ + style_id = "Barfoo" + run = Run(cast(CT_R, element(f"w:r/w:rPr/w:rStyle{{w:val={style_id}}}")), paragraph_) - @pytest.fixture - def font_fixture(self, Font_, font_): - run = Run(element("w:r"), None) - return run, Font_, font_ + style = run.style - @pytest.fixture - def style_get_fixture(self, part_prop_): - style_id = "Barfoo" - r_cxml = "w:r/w:rPr/w:rStyle{w:val=%s}" % style_id - run = Run(element(r_cxml), None) - style_ = part_prop_.return_value.get_style.return_value - return run, style_id, style_ + document_part_.get_style.assert_called_once_with(style_id, WD_STYLE_TYPE.CHARACTER) + assert style is style_ - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("r_cxml", "value", "style_id", "expected_cxml"), + [ ("w:r", "Foo Font", "FooFont", "w:r/w:rPr/w:rStyle{w:val=FooFont}"), ("w:r/w:rPr", "Foo Font", "FooFont", "w:r/w:rPr/w:rStyle{w:val=FooFont}"), ( @@ -242,60 +161,46 @@ def style_get_fixture(self, part_prop_): ), ("w:r/w:rPr/w:rStyle{w:val=FooFont}", None, None, "w:r/w:rPr"), ("w:r", None, None, "w:r/w:rPr"), - ] + ], ) - def style_set_fixture(self, request, part_prop_): - r_cxml, value, style_id, expected_cxml = request.param - run = Run(element(r_cxml), None) - part_prop_.return_value.get_style_id.return_value = style_id - expected_xml = xml(expected_cxml) - return run, value, expected_xml - - @pytest.fixture( - params=[ - ("w:r", ""), - ('w:r/w:t"foobar"', "foobar"), - ('w:r/(w:t"abc", w:tab, w:t"def", w:cr)', "abc\tdef\n"), - ('w:r/(w:br{w:type=page}, w:t"abc", w:t"def", w:tab)', "\nabcdef\t"), - ] - ) - def text_get_fixture(self, request): - r_cxml, expected_text = request.param - run = Run(element(r_cxml), None) - return run, expected_text + def it_can_change_its_character_style( + self, + r_cxml: str, + value: str | None, + style_id: str | None, + expected_cxml: str, + part_prop_: Mock, + paragraph_: Mock, + ): + part_ = part_prop_.return_value + part_.get_style_id.return_value = style_id + run = Run(cast(CT_R, element(r_cxml)), paragraph_) - @pytest.fixture( - params=[ - ("abc def", 'w:r/w:t"abc def"'), - ("abc\tdef", 'w:r/(w:t"abc", w:tab, w:t"def")'), - ("abc\ndef", 'w:r/(w:t"abc", w:br, w:t"def")'), - ("abc\rdef", 'w:r/(w:t"abc", w:br, w:t"def")'), - ] - ) - def text_set_fixture(self, request): - new_text, expected_cxml = request.param - initial_r_cxml = 'w:r/w:t"should get deleted"' - run = Run(element(initial_r_cxml), None) - expected_xml = xml(expected_cxml) - return run, new_text, expected_xml - - @pytest.fixture( - params=[ + run.style = value + + part_.get_style_id.assert_called_once_with(value, WD_STYLE_TYPE.CHARACTER) + assert run._r.xml == xml(expected_cxml) + + @pytest.mark.parametrize( + ("r_cxml", "expected_value"), + [ ("w:r", None), ("w:r/w:rPr/w:u", None), ("w:r/w:rPr/w:u{w:val=single}", True), ("w:r/w:rPr/w:u{w:val=none}", False), ("w:r/w:rPr/w:u{w:val=double}", WD_UNDERLINE.DOUBLE), ("w:r/w:rPr/w:u{w:val=wave}", WD_UNDERLINE.WAVY), - ] + ], ) - def underline_get_fixture(self, request): - r_cxml, expected_underline = request.param - run = Run(element(r_cxml), None) - return run, expected_underline + def it_knows_its_underline_type( + self, r_cxml: str, expected_value: bool | WD_UNDERLINE | None, paragraph_: Mock + ): + run = Run(cast(CT_R, element(r_cxml)), paragraph_) + assert run.underline is expected_value - @pytest.fixture( - params=[ + @pytest.mark.parametrize( + ("initial_r_cxml", "new_underline", "expected_cxml"), + [ ("w:r", True, "w:r/w:rPr/w:u{w:val=single}"), ("w:r", False, "w:r/w:rPr/w:u{w:val=none}"), ("w:r", None, "w:r/w:rPr"), @@ -314,46 +219,190 @@ def underline_get_fixture(self, request): WD_UNDERLINE.DOTTED, "w:r/w:rPr/w:u{w:val=dotted}", ), - ] + ], + ) + def it_can_change_its_underline_type( + self, + initial_r_cxml: str, + new_underline: bool | WD_UNDERLINE | None, + expected_cxml: str, + paragraph_: Mock, + ): + run = Run(cast(CT_R, element(initial_r_cxml)), paragraph_) + + run.underline = new_underline + + assert run._r.xml == xml(expected_cxml) + + @pytest.mark.parametrize("invalid_value", ["foobar", 42, "single"]) + def it_raises_on_assign_invalid_underline_value(self, invalid_value: Any, paragraph_: Mock): + run = Run(cast(CT_R, element("w:r/w:rPr")), paragraph_) + with pytest.raises(ValueError, match=" is not a valid WD_UNDERLINE"): + run.underline = invalid_value + + def it_provides_access_to_its_font(self, Font_: Mock, font_: Mock, paragraph_: Mock): + Font_.return_value = font_ + run = Run(cast(CT_R, element("w:r")), paragraph_) + + font = run.font + + Font_.assert_called_once_with(run._element) + assert font is font_ + + @pytest.mark.parametrize( + ("r_cxml", "new_text", "expected_cxml"), + [ + ("w:r", "foo", 'w:r/w:t"foo"'), + ('w:r/w:t"foo"', "bar", 'w:r/(w:t"foo", w:t"bar")'), + ("w:r", "fo ", 'w:r/w:t{xml:space=preserve}"fo "'), + ("w:r", "f o", 'w:r/w:t"f o"'), + ], ) - def underline_set_fixture(self, request): - initial_r_cxml, new_underline, expected_cxml = request.param - run = Run(element(initial_r_cxml), None) - expected_xml = xml(expected_cxml) - return run, new_underline, expected_xml + def it_can_add_text( + self, r_cxml: str, new_text: str, expected_cxml: str, Text_: Mock, paragraph_: Mock + ): + run = Run(cast(CT_R, element(r_cxml)), paragraph_) + + text = run.add_text(new_text) - @pytest.fixture(params=["foobar", 42, "single"]) - def underline_raise_fixture(self, request): - invalid_underline_setting = request.param - run = Run(element("w:r/w:rPr"), None) - return run, invalid_underline_setting + assert run._r.xml == xml(expected_cxml) + assert text is Text_.return_value - # fixture components --------------------------------------------- + @pytest.mark.parametrize( + ("break_type", "expected_cxml"), + [ + (WD_BREAK.LINE, "w:r/w:br"), + (WD_BREAK.PAGE, "w:r/w:br{w:type=page}"), + (WD_BREAK.COLUMN, "w:r/w:br{w:type=column}"), + (WD_BREAK.LINE_CLEAR_LEFT, "w:r/w:br{w:clear=left}"), + (WD_BREAK.LINE_CLEAR_RIGHT, "w:r/w:br{w:clear=right}"), + (WD_BREAK.LINE_CLEAR_ALL, "w:r/w:br{w:clear=all}"), + ], + ) + def it_can_add_a_break(self, break_type: WD_BREAK, expected_cxml: str, paragraph_: Mock): + run = Run(cast(CT_R, element("w:r")), paragraph_) + + run.add_break(break_type) + + assert run._r.xml == xml(expected_cxml) + + @pytest.mark.parametrize( + ("r_cxml", "expected_cxml"), [('w:r/w:t"foo"', 'w:r/(w:t"foo", w:tab)')] + ) + def it_can_add_a_tab(self, r_cxml: str, expected_cxml: str, paragraph_: Mock): + run = Run(cast(CT_R, element(r_cxml)), paragraph_) + + run.add_tab() + + assert run._r.xml == xml(expected_cxml) + + def it_can_add_a_picture( + self, + part_prop_: Mock, + document_part_: Mock, + InlineShape_: Mock, + picture_: Mock, + paragraph_: Mock, + ): + part_prop_.return_value = document_part_ + run = Run(cast(CT_R, element("w:r/wp:x")), paragraph_) + image = "foobar.png" + width, height, inline = 1111, 2222, element("wp:inline{id=42}") + document_part_.new_pic_inline.return_value = inline + InlineShape_.return_value = picture_ + + picture = run.add_picture(image, width, height) + + document_part_.new_pic_inline.assert_called_once_with(image, width, height) + assert run._r.xml == xml("w:r/(wp:x,w:drawing/wp:inline{id=42})") + InlineShape_.assert_called_once_with(inline) + assert picture is picture_ + + @pytest.mark.parametrize( + ("initial_r_cxml", "expected_cxml"), + [ + ("w:r", "w:r"), + ('w:r/w:t"foo"', "w:r"), + ("w:r/w:br", "w:r"), + ("w:r/w:rPr", "w:r/w:rPr"), + ('w:r/(w:rPr, w:t"foo")', "w:r/w:rPr"), + ( + 'w:r/(w:rPr/(w:b, w:i), w:t"foo", w:cr, w:t"bar")', + "w:r/w:rPr/(w:b, w:i)", + ), + ], + ) + def it_can_remove_its_content_but_keep_formatting( + self, initial_r_cxml: str, expected_cxml: str, paragraph_: Mock + ): + run = Run(cast(CT_R, element(initial_r_cxml)), paragraph_) + + cleared_run = run.clear() + + assert run._r.xml == xml(expected_cxml) + assert cleared_run is run + + @pytest.mark.parametrize( + ("r_cxml", "expected_text"), + [ + ("w:r", ""), + ('w:r/w:t"foobar"', "foobar"), + ('w:r/(w:t"abc", w:tab, w:t"def", w:cr)', "abc\tdef\n"), + ('w:r/(w:br{w:type=page}, w:t"abc", w:t"def", w:tab)', "abcdef\t"), + ], + ) + def it_knows_the_text_it_contains(self, r_cxml: str, expected_text: str, paragraph_: Mock): + run = Run(cast(CT_R, element(r_cxml)), paragraph_) + assert run.text == expected_text + + @pytest.mark.parametrize( + ("new_text", "expected_cxml"), + [ + ("abc def", 'w:r/w:t"abc def"'), + ("abc\tdef", 'w:r/(w:t"abc", w:tab, w:t"def")'), + ("abc\ndef", 'w:r/(w:t"abc", w:br, w:t"def")'), + ("abc\rdef", 'w:r/(w:t"abc", w:br, w:t"def")'), + ], + ) + def it_can_replace_the_text_it_contains( + self, new_text: str, expected_cxml: str, paragraph_: Mock + ): + run = Run(cast(CT_R, element('w:r/w:t"should get deleted"')), paragraph_) + + run.text = new_text + + assert run._r.xml == xml(expected_cxml) + + # -- fixtures -------------------------------------------------------------------------------- @pytest.fixture - def document_part_(self, request): + def document_part_(self, request: FixtureRequest): return instance_mock(request, DocumentPart) @pytest.fixture - def Font_(self, request, font_): - return class_mock(request, "docx.text.run.Font", return_value=font_) + def Font_(self, request: FixtureRequest): + return class_mock(request, "docx.text.run.Font") @pytest.fixture - def font_(self, request): + def font_(self, request: FixtureRequest): return instance_mock(request, Font) @pytest.fixture - def InlineShape_(self, request): + def InlineShape_(self, request: FixtureRequest): return class_mock(request, "docx.text.run.InlineShape") @pytest.fixture - def part_prop_(self, request, document_part_): - return property_mock(request, Run, "part", return_value=document_part_) + def paragraph_(self, request: FixtureRequest): + return instance_mock(request, Paragraph) + + @pytest.fixture + def part_prop_(self, request: FixtureRequest): + return property_mock(request, Run, "part") @pytest.fixture - def picture_(self, request): + def picture_(self, request: FixtureRequest): return instance_mock(request, InlineShape) @pytest.fixture - def Text_(self, request): + def Text_(self, request: FixtureRequest): return class_mock(request, "docx.text.run._Text") diff --git a/tests/text/test_tabstops.py b/tests/text/test_tabstops.py index 29627fcb..79d920c2 100644 --- a/tests/text/test_tabstops.py +++ b/tests/text/test_tabstops.py @@ -1,23 +1,16 @@ -# encoding: utf-8 +"""Test suite for the docx.text.tabstops module.""" -""" -Test suite for the docx.text.tabstops module, containing the TabStops and -TabStop objects. -""" - -from __future__ import absolute_import, division, print_function, unicode_literals +import pytest from docx.enum.text import WD_TAB_ALIGNMENT, WD_TAB_LEADER from docx.shared import Twips from docx.text.tabstops import TabStop, TabStops -import pytest - from ..unitutil.cxml import element, xml from ..unitutil.mock import call, class_mock, instance_mock -class DescribeTabStop(object): +class DescribeTabStop: def it_knows_its_position(self, position_get_fixture): tab_stop, expected_value = position_get_fixture assert tab_stop.position == expected_value @@ -151,7 +144,7 @@ def position_set_fixture(self, request): return tab_stop, value, tabs, new_idx, expected_xml -class DescribeTabStops(object): +class DescribeTabStops: def it_knows_its_length(self, len_fixture): tab_stops, expected_value = len_fixture assert len(tab_stops) == expected_value diff --git a/tests/unitdata.py b/tests/unitdata.py index 7fe0a7c1..31f0044d 100644 --- a/tests/unitdata.py +++ b/tests/unitdata.py @@ -1,16 +1,10 @@ -# encoding: utf-8 +"""Shared code for unit test data builders.""" -""" -Shared code for unit test data builders -""" - -from __future__ import absolute_import, print_function, unicode_literals - -from docx.oxml import parse_xml from docx.oxml.ns import nsdecls +from docx.oxml.parser import parse_xml -class BaseBuilder(object): +class BaseBuilder: """ Provides common behavior for all data builders. """ @@ -62,7 +56,7 @@ def element(self): def with_child(self, child_bldr): """ - Cause new child element specified by *child_bldr* to be appended to + Cause new child element specified by `child_bldr` to be appended to the children of this element. """ self._child_bldrs.append(child_bldr) @@ -70,7 +64,7 @@ def with_child(self, child_bldr): def with_text(self, text): """ - Cause *text* to be placed between the start and end tags of this + Cause `text` to be placed between the start and end tags of this element. Not robust enough for mixed elements, intended only for elements having no child elements. """ diff --git a/tests/unitutil/cxml.py b/tests/unitutil/cxml.py index 3029eda7..36d6ea86 100644 --- a/tests/unitutil/cxml.py +++ b/tests/unitutil/cxml.py @@ -1,51 +1,43 @@ -# encoding: utf-8 - """Parser for Compact XML Expression Language (CXEL) ('see-ex-ell'). CXEL is a compact XML specification language I made up that's useful for producing XML element trees suitable for unit testing. """ -from __future__ import absolute_import, division, print_function, unicode_literals - from pyparsing import ( - alphas, - alphanums, Combine, - dblQuotedString, - delimitedList, + DelimitedList, Forward, Group, Literal, Optional, - removeQuotes, - stringEnd, Suppress, Word, + alphanums, + alphas, + dblQuotedString, + quotedString, + removeQuotes, + stringEnd, ) -from docx.oxml import parse_xml from docx.oxml.ns import nsmap - +from docx.oxml.parser import parse_xml # ==================================================================== # api functions # ==================================================================== -def element(cxel_str): - """ - Return an oxml element parsed from the XML generated from *cxel_str*. - """ +def element(cxel_str: str): + """Return an oxml element parsed from the XML generated from `cxel_str`.""" _xml = xml(cxel_str) return parse_xml(_xml) -def xml(cxel_str): - """ - Return the XML generated from *cxel_str*. - """ - root_token = root_node.parseString(cxel_str) +def xml(cxel_str: str) -> str: + """Return the XML generated from `cxel_str`.""" + root_token = root_node.parse_string(cxel_str) xml = root_token.element.xml return xml @@ -56,17 +48,14 @@ def xml(cxel_str): def nsdecls(*nspfxs): - """ - Return a string containing a namespace declaration for each of *nspfxs*, - in the order they are specified. - """ + """Namespace-declaration including each of `nspfxs`, in the order specified.""" nsdecls = "" for nspfx in nspfxs: nsdecls += ' xmlns:%s="%s"' % (nspfx, nsmap[nspfx]) return nsdecls -class Element(object): +class Element: """ Represents an XML element, having a namespace, tagname, attributes, and may contain either text or children (but not both) or may be empty. @@ -88,7 +77,7 @@ def __repr__(self): def connect_children(self, child_node_list): """ - Make each of the elements appearing in *child_node_list* a child of + Make each of the elements appearing in `child_node_list` a child of this element. """ for node in child_node_list: @@ -101,7 +90,7 @@ def from_token(cls, token): Return an ``Element`` object constructed from a parser element token. """ tagname = token.tagname - attrs = [(name, value) for name, value in token.attr_list] + attrs = [tuple(a) for a in token.attr_list] text = token.text return cls(tagname, attrs, text) @@ -170,7 +159,7 @@ def xml(self): def _xml(self, indent): """ Return a string containing the XML of this element and all its - children with a starting indent of *indent* spaces. + children with a starting indent of `indent` spaces. """ self._indent_str = " " * indent xml = self._start_tag @@ -253,32 +242,30 @@ def grammar(): # np:attr_name=attr_val ---------------------- attr_name = Word(alphas + ":") - attr_val = Word(alphanums + " %-./:_") + attr_val = Word(alphanums + " %-./:_") | quotedString.set_parse_action(removeQuotes) attr_def = Group(attr_name + equal + attr_val) - attr_list = open_brace + delimitedList(attr_def) + close_brace + attr_list = open_brace + DelimitedList(attr_def) + close_brace - text = dblQuotedString.setParseAction(removeQuotes) + text = dblQuotedString.set_parse_action(removeQuotes) # w:jc{val=right} ---------------------------- element = ( tagname("tagname") + Group(Optional(attr_list))("attr_list") + Optional(text, default="")("text") - ).setParseAction(Element.from_token) + ).set_parse_action(Element.from_token) child_node_list = Forward() node = Group( element("element") + Group(Optional(slash + child_node_list))("child_node_list") - ).setParseAction(connect_node_children) + ).set_parse_action(connect_node_children) - child_node_list << (open_paren + delimitedList(node) + close_paren | node) + child_node_list << (open_paren + DelimitedList(node) + close_paren | node) root_node = ( - element("element") - + Group(Optional(slash + child_node_list))("child_node_list") - + stringEnd - ).setParseAction(connect_root_node_children) + element("element") + Group(Optional(slash + child_node_list))("child_node_list") + stringEnd + ).set_parse_action(connect_root_node_children) return root_node diff --git a/tests/unitutil/file.py b/tests/unitutil/file.py index aa99b0b3..226585bc 100644 --- a/tests/unitutil/file.py +++ b/tests/unitutil/file.py @@ -1,39 +1,36 @@ -# encoding: utf-8 +"""Utility functions for loading files for unit testing.""" -""" -Utility functions for loading files for unit testing -""" +from __future__ import annotations import os - _thisdir = os.path.split(__file__)[0] -testfile_dir = os.path.abspath(os.path.join(_thisdir, "..", "test_files")) +test_file_dir = os.path.abspath(os.path.join(_thisdir, "..", "test_files")) -def abspath(relpath): +def abspath(relpath: str) -> str: thisdir = os.path.split(__file__)[0] return os.path.abspath(os.path.join(thisdir, relpath)) -def absjoin(*paths): +def absjoin(*paths: str) -> str: return os.path.abspath(os.path.join(*paths)) -def docx_path(name): +def docx_path(name: str): """ - Return the absolute path to test .docx file with root name *name*. + Return the absolute path to test .docx file with root name `name`. """ - return absjoin(testfile_dir, "%s.docx" % name) + return absjoin(test_file_dir, "%s.docx" % name) -def snippet_seq(name, offset=0, count=1024): +def snippet_seq(name: str, offset: int = 0, count: int = 1024): """ Return a tuple containing the unicode text snippets read from the snippet - file having *name*. Snippets are delimited by a blank line. If specified, - *count* snippets starting at *offset* are returned. + file having `name`. Snippets are delimited by a blank line. If specified, + `count` snippets starting at `offset` are returned. """ - path = os.path.join(testfile_dir, "snippets", "%s.txt" % name) + path = os.path.join(test_file_dir, "snippets", "%s.txt" % name) with open(path, "rb") as f: text = f.read().decode("utf-8") snippets = text.split("\n\n") @@ -41,21 +38,19 @@ def snippet_seq(name, offset=0, count=1024): return tuple(snippets[start:end]) -def snippet_text(snippet_file_name): +def snippet_text(snippet_file_name: str): """ Return the unicode text read from the test snippet file having - *snippet_file_name*. + `snippet_file_name`. """ - snippet_file_path = os.path.join( - testfile_dir, "snippets", "%s.txt" % snippet_file_name - ) + snippet_file_path = os.path.join(test_file_dir, "snippets", "%s.txt" % snippet_file_name) with open(snippet_file_path, "rb") as f: snippet_bytes = f.read() return snippet_bytes.decode("utf-8") -def testfile(name): +def test_file(name: str): """ - Return the absolute path to test file having *name*. + Return the absolute path to test file having `name`. """ - return absjoin(testfile_dir, name) + return absjoin(test_file_dir, name) diff --git a/tests/unitutil/mock.py b/tests/unitutil/mock.py index 4bd1fdcc..de05cc20 100644 --- a/tests/unitutil/mock.py +++ b/tests/unitutil/mock.py @@ -1,26 +1,44 @@ -# encoding: utf-8 - -"""Utility functions wrapping the excellent *mock* library""" - -from __future__ import absolute_import, division, print_function, unicode_literals - -import sys - -if sys.version_info >= (3, 3): - from unittest import mock # noqa - from unittest.mock import ANY, call, MagicMock # noqa - from unittest.mock import create_autospec, Mock, mock_open, patch, PropertyMock -else: - import mock # noqa - from mock import ANY, call, MagicMock # noqa - from mock import create_autospec, Mock, patch, PropertyMock - - -def class_mock(request, q_class_name, autospec=True, **kwargs): - """Return mock patching class with qualified name *q_class_name*. +"""Utility functions wrapping the excellent `mock` library.""" + +from __future__ import annotations + +from typing import Any +from unittest.mock import ( + ANY, + MagicMock, + Mock, + PropertyMock, + call, + create_autospec, + mock_open, + patch, +) + +from pytest import FixtureRequest, LogCaptureFixture # noqa: PT013 + +__all__ = ( + "ANY", + "FixtureRequest", + "LogCaptureFixture", + "MagicMock", + "Mock", + "call", + "class_mock", + "function_mock", + "initializer_mock", + "instance_mock", + "method_mock", + "property_mock", +) + + +def class_mock( + request: FixtureRequest, q_class_name: str, autospec: bool = True, **kwargs: Any +) -> Mock: + """Return mock patching class with qualified name `q_class_name`. The mock is autospec'ed based on the patched class unless the optional - argument *autospec* is set to False. Any other keyword arguments are + argument `autospec` is set to False. Any other keyword arguments are passed through to Mock(). Patch is reversed after calling test returns. """ _patch = patch(q_class_name, autospec=autospec, **kwargs) @@ -28,10 +46,16 @@ def class_mock(request, q_class_name, autospec=True, **kwargs): return _patch.start() -def cls_attr_mock(request, cls, attr_name, name=None, **kwargs): - """ - Return a mock for attribute *attr_name* on *cls* where the patch is - reversed after pytest uses it. +def cls_attr_mock( + request: FixtureRequest, + cls: type, + attr_name: str, + name: str | None = None, + **kwargs: Any, +): + """Return a mock for attribute `attr_name` on `cls`. + + Patch is reversed after pytest uses it. """ name = request.fixturename if name is None else name _patch = patch.object(cls, attr_name, name=name, **kwargs) @@ -39,8 +63,10 @@ def cls_attr_mock(request, cls, attr_name, name=None, **kwargs): return _patch.start() -def function_mock(request, q_function_name, autospec=True, **kwargs): - """Return mock patching function with qualified name *q_function_name*. +def function_mock( + request: FixtureRequest, q_function_name: str, autospec: bool = True, **kwargs: Any +): + """Return mock patching function with qualified name `q_function_name`. Patch is reversed after calling test returns. """ @@ -49,22 +75,26 @@ def function_mock(request, q_function_name, autospec=True, **kwargs): return _patch.start() -def initializer_mock(request, cls, autospec=True, **kwargs): - """Return mock for __init__() method on *cls*. +def initializer_mock(request: FixtureRequest, cls: type, autospec: bool = True, **kwargs: Any): + """Return mock for __init__() method on `cls`. The patch is reversed after pytest uses it. """ - _patch = patch.object( - cls, "__init__", autospec=autospec, return_value=None, **kwargs - ) + _patch = patch.object(cls, "__init__", autospec=autospec, return_value=None, **kwargs) request.addfinalizer(_patch.stop) return _patch.start() -def instance_mock(request, cls, name=None, spec_set=True, **kwargs): +def instance_mock( + request: FixtureRequest, + cls: type, + name: str | None = None, + spec_set: bool = True, + **kwargs: Any, +): """ - Return a mock for an instance of *cls* that draws its spec from the class - and does not allow new attributes to be set on the instance. If *name* is + Return a mock for an instance of `cls` that draws its spec from the class + and does not allow new attributes to be set on the instance. If `name` is missing or |None|, the name of the returned |Mock| instance is set to *request.fixturename*. Additional keyword arguments are passed through to the Mock() call that creates the mock. @@ -73,7 +103,7 @@ def instance_mock(request, cls, name=None, spec_set=True, **kwargs): return create_autospec(cls, _name=name, spec_set=spec_set, instance=True, **kwargs) -def loose_mock(request, name=None, **kwargs): +def loose_mock(request: FixtureRequest, name: str | None = None, **kwargs: Any): """ Return a "loose" mock, meaning it has no spec to constrain calls on it. Additional keyword arguments are passed through to Mock(). If called @@ -84,8 +114,14 @@ def loose_mock(request, name=None, **kwargs): return Mock(name=name, **kwargs) -def method_mock(request, cls, method_name, autospec=True, **kwargs): - """Return mock for method *method_name* on *cls*. +def method_mock( + request: FixtureRequest, + cls: type, + method_name: str, + autospec: bool = True, + **kwargs: Any, +): + """Return mock for method `method_name` on `cls`. The patch is reversed after pytest uses it. """ @@ -94,9 +130,9 @@ def method_mock(request, cls, method_name, autospec=True, **kwargs): return _patch.start() -def open_mock(request, module_name, **kwargs): +def open_mock(request: FixtureRequest, module_name: str, **kwargs: Any): """ - Return a mock for the builtin `open()` method in *module_name*. + Return a mock for the builtin `open()` method in `module_name`. """ target = "%s.open" % module_name _patch = patch(target, mock_open(), create=True, **kwargs) @@ -104,9 +140,9 @@ def open_mock(request, module_name, **kwargs): return _patch.start() -def property_mock(request, cls, prop_name, **kwargs): +def property_mock(request: FixtureRequest, cls: type, prop_name: str, **kwargs: Any): """ - Return a mock for property *prop_name* on class *cls* where the patch is + Return a mock for property `prop_name` on class `cls` where the patch is reversed after pytest uses it. """ _patch = patch.object(cls, prop_name, new_callable=PropertyMock, **kwargs) @@ -114,9 +150,9 @@ def property_mock(request, cls, prop_name, **kwargs): return _patch.start() -def var_mock(request, q_var_name, **kwargs): +def var_mock(request: FixtureRequest, q_var_name: str, **kwargs: Any): """ - Return a mock patching the variable with qualified name *q_var_name*. + Return a mock patching the variable with qualified name `q_var_name`. Patch is reversed after calling test returns. """ _patch = patch(q_var_name, **kwargs) diff --git a/tox.ini b/tox.ini index f5afb0de..63f3d1ab 100644 --- a/tox.ini +++ b/tox.ini @@ -1,27 +1,9 @@ -# -# Configuration for tox and pytest - -[flake8] -exclude = dist,docs,*.egg-info,.git,ref,_scratch,.tox -max-line-length = 88 - -[pytest] -norecursedirs = doc docx *.egg-info features .git ref _scratch .tox -python_files = test_*.py -python_classes = Test Describe -python_functions = it_ they_ and_it_ but_it_ test_ - [tox] -envlist = py310, py311, py312, py313 +envlist = py312, py313 [testenv] -deps = - behave - lxml - pyparsing - pytest - pytest-mock +deps = -rrequirements-test.txt commands = - pytest -qx + py.test -qx behave --format progress --stop --tags=-wip diff --git a/typings/behave/__init__.pyi b/typings/behave/__init__.pyi new file mode 100644 index 00000000..f8ffc205 --- /dev/null +++ b/typings/behave/__init__.pyi @@ -0,0 +1,17 @@ +from __future__ import annotations + +from typing import Callable + +from typing_extensions import TypeAlias + +from .runner import Context + +_ThreeArgStep: TypeAlias = Callable[[Context, str, str, str], None] +_TwoArgStep: TypeAlias = Callable[[Context, str, str], None] +_OneArgStep: TypeAlias = Callable[[Context, str], None] +_NoArgStep: TypeAlias = Callable[[Context], None] +_Step: TypeAlias = _NoArgStep | _OneArgStep | _TwoArgStep | _ThreeArgStep + +def given(phrase: str) -> Callable[[_Step], _Step]: ... +def when(phrase: str) -> Callable[[_Step], _Step]: ... +def then(phrase: str) -> Callable[[_Step], _Step]: ... diff --git a/typings/behave/runner.pyi b/typings/behave/runner.pyi new file mode 100644 index 00000000..aaea74da --- /dev/null +++ b/typings/behave/runner.pyi @@ -0,0 +1,3 @@ +from types import SimpleNamespace + +class Context(SimpleNamespace): ... diff --git a/uv.lock b/uv.lock new file mode 100644 index 00000000..ff0927c1 --- /dev/null +++ b/uv.lock @@ -0,0 +1,1090 @@ +version = 1 +revision = 3 +requires-python = ">=3.12" + +[[package]] +name = "alabaster" +version = "1.0.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/a6/f8/d9c74d0daf3f742840fd818d69cfae176fa332022fd44e3469487d5a9420/alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b" }, +] + +[[package]] +name = "babel" +version = "2.18.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/7d/b2/51899539b6ceeeb420d40ed3cd4b7a40519404f9baf3d4ac99dc413a834b/babel-2.18.0.tar.gz", hash = "sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl", hash = "sha256:e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35" }, +] + +[[package]] +name = "beautifulsoup4" +version = "4.14.3" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "soupsieve" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/c3/b0/1c6a16426d389813b48d95e26898aff79abbde42ad353958ad95cc8c9b21/beautifulsoup4-4.14.3.tar.gz", hash = "sha256:6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl", hash = "sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb" }, +] + +[[package]] +name = "behave" +version = "1.3.3" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "colorama" }, + { name = "cucumber-expressions" }, + { name = "cucumber-tag-expressions" }, + { name = "parse" }, + { name = "parse-type" }, + { name = "six" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/62/51/f37442fe648b3e35ecf69bee803fa6db3f74c5b46d6c882d0bc5654185a2/behave-1.3.3.tar.gz", hash = "sha256:2b8f4b64ed2ea756a5a2a73e23defc1c4631e9e724c499e46661778453ebaf51" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/63/71/06f74ffed6d74525c5cd6677c97bd2df0b7649e47a249cf6a0c2038083b2/behave-1.3.3-py2.py3-none-any.whl", hash = "sha256:89bdb62af8fb9f147ce245736a5de69f025e5edfb66f1fbe16c5007493f842c0" }, +] + +[[package]] +name = "cachetools" +version = "7.0.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/98/af/df70e9b65bc77a1cbe0768c0aa4617147f30f8306ded98c1744bcdc0ae1e/cachetools-7.0.0.tar.gz", hash = "sha256:a9abf18ff3b86c7d05b27ead412e235e16ae045925e531fae38d5fada5ed5b08" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/28/df/2dd32cce20cbcf6f2ec456b58d44368161ad28320729f64e5e1d5d7bd0ae/cachetools-7.0.0-py3-none-any.whl", hash = "sha256:d52fef60e6e964a1969cfb61ccf6242a801b432790fe520d78720d757c81cbd2" }, +] + +[[package]] +name = "certifi" +version = "2026.1.4" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/e0/2d/a891ca51311197f6ad14a7ef42e2399f36cf2f9bd44752b3dc4eab60fdc5/certifi-2026.1.4.tar.gz", hash = "sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl", hash = "sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c" }, +] + +[[package]] +name = "cffi" +version = "2.0.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "pycparser", marker = "implementation_name != 'PyPy'" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062" }, + { url = "https://mirrors.aliyun.com/pypi/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba" }, + { url = "https://mirrors.aliyun.com/pypi/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26" }, + { url = "https://mirrors.aliyun.com/pypi/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592" }, + { url = "https://mirrors.aliyun.com/pypi/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4" }, +] + +[[package]] +name = "chardet" +version = "5.2.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/f3/0d/f7b6ab21ec75897ed80c17d79b15951a719226b9fababf1e40ea74d69079/chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/38/6f/f5fbc992a329ee4e0f288c1fe0e2ad9485ed064cac731ed2fe47dcc38cbf/chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970" }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.4" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/f3/85/1637cd4af66fa687396e757dec650f28025f2a2f5a5531a3208dc0ec43f2/charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9d/6a/04130023fef2a0d9c62d0bae2649b69f7b7d8d24ea5536feef50551029df/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25" }, + { url = "https://mirrors.aliyun.com/pypi/packages/78/29/62328d79aa60da22c9e0b9a66539feae06ca0f5a4171ac4f7dc285b83688/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef" }, + { url = "https://mirrors.aliyun.com/pypi/packages/86/bb/b32194a4bf15b88403537c2e120b817c61cd4ecffa9b6876e941c3ee38fe/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/19/89/a54c82b253d5b9b111dc74aca196ba5ccfcca8242d0fb64146d4d3183ff1/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c0/10/d20b513afe03acc89ec33948320a5544d31f21b05368436d580dec4e234d/charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86" }, + { url = "https://mirrors.aliyun.com/pypi/packages/61/fa/fbf177b55bdd727010f9c0a3c49eefa1d10f960e5f09d1d887bf93c2e698/charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/05/12/9fbc6a4d39c0198adeebbde20b619790e9236557ca59fc40e0e3cebe6f40/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ad/1f/6a9a593d52e3e8c5d2b167daf8c6b968808efb57ef4c210acb907c365bc4/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc" }, + { url = "https://mirrors.aliyun.com/pypi/packages/30/42/9a52c609e72471b0fc54386dc63c3781a387bb4fe61c20231a4ebcd58bdd/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c4/5b/c0682bbf9f11597073052628ddd38344a3d673fda35a36773f7d19344b23/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e4/24/a41afeab6f990cf2daf6cb8c67419b63b48cf518e4f56022230840c9bfb2/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2a/e5/6a4ce77ed243c4a50a1fecca6aaaab419628c818a49434be428fe24c9957/charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a8/ef/89297262b8092b312d29cdb2517cb1237e51db8ecef2e9af5edbe7b683b1/charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3d/2d/1e5ed9dd3b3803994c155cd9aacb60c82c331bad84daf75bcb9c91b3295e/charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d0/d9/0ed4c7098a861482a7b6a95603edce4c0d9db2311af23da1fb2b75ec26fc/charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/97/45/4b3a1239bbacd321068ea6e7ac28875b03ab8bc0aa0966452db17cd36714/charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7d/62/73a6d7450829655a35bb88a88fca7d736f9882a27eacdca2c6d505b57e2e/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed" }, + { url = "https://mirrors.aliyun.com/pypi/packages/89/c5/adb8c8b3d6625bef6d88b251bbb0d95f8205831b987631ab0c8bb5d937c2/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72" }, + { url = "https://mirrors.aliyun.com/pypi/packages/91/ed/9706e4070682d1cc219050b6048bfd293ccf67b3d4f5a4f39207453d4b99/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d5/0d/031f0d95e4972901a2f6f09ef055751805ff541511dc1252ba3ca1f80cf5/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894" }, + { url = "https://mirrors.aliyun.com/pypi/packages/75/1e/5ff781ddf5260e387d6419959ee89ef13878229732732ee73cdae01800f2/charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d7/57/71be810965493d3510a6ca79b90c19e48696fb1ff964da319334b12677f0/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e5/d5/c3d057a78c181d007014feb7e9f2e65905a6c4ef182c0ddf0de2924edd65/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e6/8c/d0406294828d4976f275ffbe66f00266c4b3136b7506941d87c00cab5272/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d7/24/e2aa1f18c8f15c4c0e932d9287b8609dd30ad56dbe41d926bd846e22fb8d/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e4/5b/1e6160c7739aad1e2df054300cc618b06bf784a7a164b0f238360721ab86/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7a/10/f882167cd207fbdd743e55534d5d9620e095089d176d55cb22d5322f2afd/charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc" }, + { url = "https://mirrors.aliyun.com/pypi/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14" }, + { url = "https://mirrors.aliyun.com/pypi/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14" }, + { url = "https://mirrors.aliyun.com/pypi/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191" }, + { url = "https://mirrors.aliyun.com/pypi/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838" }, + { url = "https://mirrors.aliyun.com/pypi/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090" }, + { url = "https://mirrors.aliyun.com/pypi/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828" }, + { url = "https://mirrors.aliyun.com/pypi/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" }, +] + +[[package]] +name = "cryptography" +version = "46.0.4" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/78/19/f748958276519adf6a0c1e79e7b8860b4830dda55ccdf29f2719b5fc499c/cryptography-46.0.4.tar.gz", hash = "sha256:bfd019f60f8abc2ed1b9be4ddc21cfef059c841d86d710bb69909a688cbb8f59" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/87/91/874b8910903159043b5c6a123b7e79c4559ddd1896e38967567942635778/cryptography-46.0.4-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5f14fba5bf6f4390d7ff8f086c566454bff0411f6d8aa7af79c88b6f9267aecc" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c0/35/690e809be77896111f5b195ede56e4b4ed0435b428c2f2b6d35046fbb5e8/cryptography-46.0.4-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:47bcd19517e6389132f76e2d5303ded6cf3f78903da2158a671be8de024f4cd0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1a/5b/a26407d4f79d61ca4bebaa9213feafdd8806dc69d3d290ce24996d3cfe43/cryptography-46.0.4-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:01df4f50f314fbe7009f54046e908d1754f19d0c6d3070df1e6268c5a4af09fa" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2b/08/f83e2e0814248b844265802d081f2fac2f1cbe6cd258e72ba14ff006823a/cryptography-46.0.4-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:0a9ad24359fee86f131836a9ac3bffc9329e956624a2d379b613f8f8abaf5255" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0a/05/19d849cf4096448779d2dcc9bb27d097457dac36f7273ffa875a93b5884c/cryptography-46.0.4-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:dc1272e25ef673efe72f2096e92ae39dea1a1a450dd44918b15351f72c5a168e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e6/89/f7bac81d66ba7cde867a743ea5b37537b32b5c633c473002b26a226f703f/cryptography-46.0.4-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:de0f5f4ec8711ebc555f54735d4c673fc34b65c44283895f1a08c2b49d2fd99c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a6/f7/6d43cbaddf6f65b24816e4af187d211f0bc536a29961f69faedc48501d8e/cryptography-46.0.4-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:3d425eacbc9aceafd2cb429e42f4e5d5633c6f873f5e567077043ef1b9bbf616" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9e/4f/ebd0473ad656a0ac912a16bd07db0f5d85184924e14fc88feecae2492834/cryptography-46.0.4-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:91627ebf691d1ea3976a031b61fb7bac1ccd745afa03602275dda443e11c8de0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d1/f7/7923886f32dc47e27adeff8246e976d77258fd2aa3efdd1754e4e323bf49/cryptography-46.0.4-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:2d08bc22efd73e8854b0b7caff402d735b354862f1145d7be3b9c0f740fef6a0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f8/f5/559c25b77f40b6bf828eabaf988efb8b0e17b573545edb503368ca0a2a03/cryptography-46.0.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:078e5f06bd2fa5aea5a324f2a09f914b1484f1d0c2a4d6a8a28c74e72f65f2da" }, + { url = "https://mirrors.aliyun.com/pypi/packages/49/a1/551fa162d33074b660dc35c9bc3616fefa21a0e8c1edd27b92559902e408/cryptography-46.0.4-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:dce1e4f068f03008da7fa51cc7abc6ddc5e5de3e3d1550334eaf8393982a5829" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b0/6a/4d8d129a755f5d6df1bbee69ea2f35ebfa954fa1847690d1db2e8bca46a5/cryptography-46.0.4-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:2067461c80271f422ee7bdbe79b9b4be54a5162e90345f86a23445a0cf3fd8a2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/43/ae/9f03d5f0c0c00e85ecb34f06d3b79599f20630e4db91b8a6e56e8f83d410/cryptography-46.0.4-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:829c2b12bbc5428ab02d6b7f7e9bbfd53e33efd6672d21341f2177470171ad8b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8b/22/e0f9f2dae8040695103369cf2283ef9ac8abe4d51f68710bec2afd232609/cryptography-46.0.4-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:62217ba44bf81b30abaeda1488686a04a702a261e26f87db51ff61d9d3510abd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/01/5b/6a43fcccc51dae4d101ac7d378a8724d1ba3de628a24e11bf2f4f43cba4d/cryptography-46.0.4-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:9c2da296c8d3415b93e6053f5a728649a87a48ce084a9aaf51d6e46c87c7f2d2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/83/17/259409b8349aa10535358807a472c6a695cf84f106022268d31cea2b6c97/cryptography-46.0.4-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:df4a817fa7138dd0c96c8c8c20f04b8aaa1fac3bbf610913dcad8ea82e1bfd3f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9c/fe/e4a1b0c989b00cee5ffa0764401767e2d1cf59f45530963b894129fd5dce/cryptography-46.0.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:b1de0ebf7587f28f9190b9cb526e901bf448c9e6a99655d2b07fff60e8212a82" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b3/81/ba8fd9657d27076eb40d6a2f941b23429a3c3d2f56f5a921d6b936a27bc9/cryptography-46.0.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9b4d17bc7bd7cdd98e3af40b441feaea4c68225e2eb2341026c84511ad246c0c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d8/cc/8f3224cbb2a928de7298d6ed4790f5ebc48114e02bdc9559196bfb12435d/cryptography-46.0.4-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8bf75b0259e87fa70bddc0b8b4078b76e7fd512fd9afae6c1193bcf440a4dbef" }, + { url = "https://mirrors.aliyun.com/pypi/packages/17/43/4a18faa7a872d00e4264855134ba82d23546c850a70ff209e04ee200e76f/cryptography-46.0.4-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3c268a3490df22270955966ba236d6bc4a8f9b6e4ffddb78aac535f1a5ea471d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ee/64/6651969409821d791ba12346a124f55e1b76f66a819254ae840a965d4b9c/cryptography-46.0.4-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:812815182f6a0c1d49a37893a303b44eaac827d7f0d582cecfc81b6427f22973" }, + { url = "https://mirrors.aliyun.com/pypi/packages/db/a7/20c5701e2cd3e1dfd7a19d2290c522a5f435dd30957d431dcb531d0f1413/cryptography-46.0.4-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a05177ff6296644ef2876fce50518dffb5bcdf903c85250974fc8bc85d54c0af" }, + { url = "https://mirrors.aliyun.com/pypi/packages/00/dc/3e16030ea9aa47b63af6524c354933b4fb0e352257c792c4deeb0edae367/cryptography-46.0.4-cp38-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:daa392191f626d50f1b136c9b4cf08af69ca8279d110ea24f5c2700054d2e263" }, + { url = "https://mirrors.aliyun.com/pypi/packages/42/c8/ad93f14118252717b465880368721c963975ac4b941b7ef88f3c56bf2897/cryptography-46.0.4-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:e07ea39c5b048e085f15923511d8121e4a9dc45cee4e3b970ca4f0d338f23095" }, + { url = "https://mirrors.aliyun.com/pypi/packages/03/c3/c90a2cb358de4ac9309b26acf49b2a100957e1ff5cc1e98e6c4996576710/cryptography-46.0.4-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:6bb5157bf6a350e5b28aee23beb2d84ae6f5be390b2f8ee7ea179cda077e1019" }, + { url = "https://mirrors.aliyun.com/pypi/packages/96/2c/8d7f4171388a10208671e181ca43cdc0e596d8259ebacbbcfbd16de593da/cryptography-46.0.4-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:dd5aba870a2c40f87a3af043e0dee7d9eb02d4aff88a797b48f2b43eff8c3ab4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e9/23/cbb2036e450980f65c6e0a173b73a56ff3bccd8998965dea5cc9ddd424a5/cryptography-46.0.4-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:93d8291da8d71024379ab2cb0b5c57915300155ad42e07f76bea6ad838d7e59b" }, +] + +[[package]] +name = "cssselect" +version = "1.4.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ec/2e/cdfd8b01c37cbf4f9482eefd455853a3cf9c995029a46acd31dfaa9c1dd6/cssselect-1.4.0.tar.gz", hash = "sha256:fdaf0a1425e17dfe8c5cf66191d211b357cf7872ae8afc4c6762ddd8ac47fc92" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/20/0c/7bb51e3acfafd16c48875bf3db03607674df16f5b6ef8d056586af7e2b8b/cssselect-1.4.0-py3-none-any.whl", hash = "sha256:c0ec5c0191c8ee39fcc8afc1540331d8b55b0183478c50e9c8a79d44dbceb1d8" }, +] + +[[package]] +name = "cucumber-expressions" +version = "19.0.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/81/5f/1afc1a0a2a6daed47b2d032a897613a556ebf49303e4af8310223f4a450b/cucumber_expressions-19.0.0.tar.gz", hash = "sha256:8eb5ae46dd03dd37fec1163ace1510529501d7d1868ff372c1ab2cd5aa4543a8" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/3b/72/eb79377be899d24c91ed196a50808563685992bb3aa6b82dbe3a1e30df67/cucumber_expressions-19.0.0-py3-none-any.whl", hash = "sha256:f452e6c73258c1677043ad67ad5f538c87284d6b502004720510fb6b7452d9c5" }, +] + +[[package]] +name = "cucumber-tag-expressions" +version = "9.0.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/37/97/61f67f61041c9356686b1098596f436d900fc6c44e63314252da8a60b394/cucumber_tag_expressions-9.0.0.tar.gz", hash = "sha256:731302c12bd602309596b35e733c1021b517d4948329803c23ca026e26ef4e99" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/03/9e/59aa2873e9274900334bafa9454363905fa6e69d14d1770dc85b14c6599e/cucumber_tag_expressions-9.0.0-py3-none-any.whl", hash = "sha256:36f3eacf49ad24feeb60218db4c51ab114853b3f022f4f3ad790c32b7597faee" }, +] + +[[package]] +name = "distlib" +version = "0.4.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/96/8e/709914eb2b5749865801041647dc7f4e6d00b549cfe88b65ca192995f07c/distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16" }, +] + +[[package]] +name = "docutils" +version = "0.22.4" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ae/b6/03bb70946330e88ffec97aefd3ea75ba575cb2e762061e0e62a213befee8/docutils-0.22.4.tar.gz", hash = "sha256:4db53b1fde9abecbb74d91230d32ab626d94f6badfc575d6db9194a49df29968" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl", hash = "sha256:d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de" }, +] + +[[package]] +name = "filelock" +version = "3.20.3" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/1d/65/ce7f1b70157833bf3cb851b556a37d4547ceafc158aa9b34b36782f23696/filelock-3.20.3.tar.gz", hash = "sha256:18c57ee915c7ec61cff0ecf7f0f869936c7c30191bb0cf406f1341778d0834e1" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/b5/36/7fb70f04bf00bc646cd5bb45aa9eddb15e19437a28b8fb2b4a5249fac770/filelock-3.20.3-py3-none-any.whl", hash = "sha256:4b0dda527ee31078689fc205ec4f1c1bf7d56cf88b6dc9426c4f230e46c2dce1" }, +] + +[[package]] +name = "id" +version = "1.5.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "requests" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/22/11/102da08f88412d875fa2f1a9a469ff7ad4c874b0ca6fed0048fe385bdb3d/id-1.5.0.tar.gz", hash = "sha256:292cb8a49eacbbdbce97244f47a97b4c62540169c976552e497fd57df0734c1d" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/9f/cb/18326d2d89ad3b0dd143da971e77afd1e6ca6674f1b1c3df4b6bec6279fc/id-1.5.0-py3-none-any.whl", hash = "sha256:f1434e1cef91f2cbb8a4ec64663d5a23b9ed43ef44c4c957d02583d61714c658" }, +] + +[[package]] +name = "idna" +version = "3.11" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea" }, +] + +[[package]] +name = "imagesize" +version = "1.4.1" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/a7/84/62473fb57d61e31fef6e36d64a179c8781605429fd927b5dd608c997be31/imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12" }, +] + +[[package]] +name = "jaraco-classes" +version = "3.4.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "more-itertools" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/06/c0/ed4a27bc5571b99e3cff68f8a9fa5b56ff7df1c2251cc715a652ddd26402/jaraco.classes-3.4.0.tar.gz", hash = "sha256:47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/7f/66/b15ce62552d84bbfcec9a4873ab79d993a1dd4edb922cbfccae192bd5b5f/jaraco.classes-3.4.0-py3-none-any.whl", hash = "sha256:f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790" }, +] + +[[package]] +name = "jaraco-context" +version = "6.1.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/cb/9c/a788f5bb29c61e456b8ee52ce76dbdd32fd72cd73dd67bc95f42c7a8d13c/jaraco_context-6.1.0.tar.gz", hash = "sha256:129a341b0a85a7db7879e22acd66902fda67882db771754574338898b2d5d86f" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/8d/48/aa685dbf1024c7bd82bede569e3a85f82c32fd3d79ba5fea578f0159571a/jaraco_context-6.1.0-py3-none-any.whl", hash = "sha256:a43b5ed85815223d0d3cfdb6d7ca0d2bc8946f28f30b6f3216bda070f68badda" }, +] + +[[package]] +name = "jaraco-functools" +version = "4.4.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "more-itertools" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/0f/27/056e0638a86749374d6f57d0b0db39f29509cce9313cf91bdc0ac4d91084/jaraco_functools-4.4.0.tar.gz", hash = "sha256:da21933b0417b89515562656547a77b4931f98176eb173644c0d35032a33d6bb" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/fd/c4/813bb09f0985cb21e959f21f2464169eca882656849adf727ac7bb7e1767/jaraco_functools-4.4.0-py3-none-any.whl", hash = "sha256:9eec1e36f45c818d9bf307c8948eb03b2b56cd44087b3cdc989abca1f20b9176" }, +] + +[[package]] +name = "jeepney" +version = "0.9.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/7b/6f/357efd7602486741aa73ffc0617fb310a29b588ed0fd69c2399acbb85b0c/jeepney-0.9.0.tar.gz", hash = "sha256:cf0e9e845622b81e4a28df94c40345400256ec608d0e55bb8a3feaa9163f5732" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/b2/a3/e137168c9c44d18eff0376253da9f1e9234d0239e0ee230d2fee6cea8e55/jeepney-0.9.0-py3-none-any.whl", hash = "sha256:97e5714520c16fc0a45695e5365a2e11b81ea79bba796e26f9f1d178cb182683" }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67" }, +] + +[[package]] +name = "keyring" +version = "25.7.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "jaraco-classes" }, + { name = "jaraco-context" }, + { name = "jaraco-functools" }, + { name = "jeepney", marker = "sys_platform == 'linux'" }, + { name = "pywin32-ctypes", marker = "sys_platform == 'win32'" }, + { name = "secretstorage", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/43/4b/674af6ef2f97d56f0ab5153bf0bfa28ccb6c3ed4d1babf4305449668807b/keyring-25.7.0.tar.gz", hash = "sha256:fe01bd85eb3f8fb3dd0405defdeac9a5b4f6f0439edbb3149577f244a2e8245b" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/81/db/e655086b7f3a705df045bf0933bdd9c2f79bb3c97bfef1384598bb79a217/keyring-25.7.0-py3-none-any.whl", hash = "sha256:be4a0b195f149690c166e850609a477c532ddbfbaed96a404d4e43f8d5e2689f" }, +] + +[[package]] +name = "lxml" +version = "6.0.2" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/aa/88/262177de60548e5a2bfc46ad28232c9e9cbde697bd94132aeb80364675cb/lxml-6.0.2.tar.gz", hash = "sha256:cd79f3367bd74b317dda655dc8fcfa304d9eb6e4fb06b7168c5cf27f96e0cd62" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/f3/c8/8ff2bc6b920c84355146cd1ab7d181bc543b89241cfb1ebee824a7c81457/lxml-6.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:a59f5448ba2ceccd06995c95ea59a7674a10de0810f2ce90c9006f3cbc044456" }, + { url = "https://mirrors.aliyun.com/pypi/packages/37/6f/9aae1008083bb501ef63284220ce81638332f9ccbfa53765b2b7502203cf/lxml-6.0.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e8113639f3296706fbac34a30813929e29247718e88173ad849f57ca59754924" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f1/ca/31fb37f99f37f1536c133476674c10b577e409c0a624384147653e38baf2/lxml-6.0.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a8bef9b9825fa8bc816a6e641bb67219489229ebc648be422af695f6e7a4fa7f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/da/87/f6cb9442e4bada8aab5ae7e1046264f62fdbeaa6e3f6211b93f4c0dd97f1/lxml-6.0.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:65ea18d710fd14e0186c2f973dc60bb52039a275f82d3c44a0e42b43440ea534" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c8/20/a7760713e65888db79bbae4f6146a6ae5c04e4a204a3c48896c408cd6ed2/lxml-6.0.2-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c371aa98126a0d4c739ca93ceffa0fd7a5d732e3ac66a46e74339acd4d334564" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a2/b0/7e64e0460fcb36471899f75831509098f3fd7cd02a3833ac517433cb4f8f/lxml-6.0.2-cp312-cp312-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:700efd30c0fa1a3581d80a748157397559396090a51d306ea59a70020223d16f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b9/e1/e5df362e9ca4e2f48ed6411bd4b3a0ae737cc842e96877f5bf9428055ab4/lxml-6.0.2-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c33e66d44fe60e72397b487ee92e01da0d09ba2d66df8eae42d77b6d06e5eba0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c6/d1/232b3309a02d60f11e71857778bfcd4acbdb86c07db8260caf7d008b08f8/lxml-6.0.2-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:90a345bbeaf9d0587a3aaffb7006aa39ccb6ff0e96a57286c0cb2fd1520ea192" }, + { url = "https://mirrors.aliyun.com/pypi/packages/35/35/d955a070994725c4f7d80583a96cab9c107c57a125b20bb5f708fe941011/lxml-6.0.2-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:064fdadaf7a21af3ed1dcaa106b854077fbeada827c18f72aec9346847cd65d0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1e/be/667d17363b38a78c4bd63cfd4b4632029fd68d2c2dc81f25ce9eb5224dd5/lxml-6.0.2-cp312-cp312-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fbc74f42c3525ac4ffa4b89cbdd00057b6196bcefe8bce794abd42d33a018092" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ea/47/62c70aa4a1c26569bc958c9ca86af2bb4e1f614e8c04fb2989833874f7ae/lxml-6.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6ddff43f702905a4e32bc24f3f2e2edfe0f8fde3277d481bffb709a4cced7a1f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/bd/55/6ceddaca353ebd0f1908ef712c597f8570cc9c58130dbb89903198e441fd/lxml-6.0.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:6da5185951d72e6f5352166e3da7b0dc27aa70bd1090b0eb3f7f7212b53f1bb8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/cf/e8/fd63e15da5e3fd4c2146f8bbb3c14e94ab850589beab88e547b2dbce22e1/lxml-6.0.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:57a86e1ebb4020a38d295c04fc79603c7899e0df71588043eb218722dabc087f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/76/47/b3ec58dc5c374697f5ba37412cd2728f427d056315d124dd4b61da381877/lxml-6.0.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:2047d8234fe735ab77802ce5f2297e410ff40f5238aec569ad7c8e163d7b19a6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/19/93/03ba725df4c3d72afd9596eef4a37a837ce8e4806010569bedfcd2cb68fd/lxml-6.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6f91fd2b2ea15a6800c8e24418c0775a1694eefc011392da73bc6cef2623b322" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c6/80/c06de80bfce881d0ad738576f243911fccf992687ae09fd80b734712b39c/lxml-6.0.2-cp312-cp312-win32.whl", hash = "sha256:3ae2ce7d6fedfb3414a2b6c5e20b249c4c607f72cb8d2bb7cc9c6ec7c6f4e849" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f7/d7/0cdfb6c3e30893463fb3d1e52bc5f5f99684a03c29a0b6b605cfae879cd5/lxml-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:72c87e5ee4e58a8354fb9c7c84cbf95a1c8236c127a5d1b7683f04bed8361e1f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ea/7b/93c73c67db235931527301ed3785f849c78991e2e34f3fd9a6663ffda4c5/lxml-6.0.2-cp312-cp312-win_arm64.whl", hash = "sha256:61cb10eeb95570153e0c0e554f58df92ecf5109f75eacad4a95baa709e26c3d6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/53/fd/4e8f0540608977aea078bf6d79f128e0e2c2bba8af1acf775c30baa70460/lxml-6.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:9b33d21594afab46f37ae58dfadd06636f154923c4e8a4d754b0127554eb2e77" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5d/f4/2a94a3d3dfd6c6b433501b8d470a1960a20ecce93245cf2db1706adf6c19/lxml-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6c8963287d7a4c5c9a432ff487c52e9c5618667179c18a204bdedb27310f022f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/25/2e/4efa677fa6b322013035d38016f6ae859d06cac67437ca7dc708a6af7028/lxml-6.0.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1941354d92699fb5ffe6ed7b32f9649e43c2feb4b97205f75866f7d21aa91452" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ce/0f/526e78a6d38d109fdbaa5049c62e1d32fdd70c75fb61c4eadf3045d3d124/lxml-6.0.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bb2f6ca0ae2d983ded09357b84af659c954722bbf04dea98030064996d156048" }, + { url = "https://mirrors.aliyun.com/pypi/packages/81/76/99de58d81fa702cc0ea7edae4f4640416c2062813a00ff24bd70ac1d9c9b/lxml-6.0.2-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eb2a12d704f180a902d7fa778c6d71f36ceb7b0d317f34cdc76a5d05aa1dd1df" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b5/35/9e57d25482bc9a9882cb0037fdb9cc18f4b79d85df94fa9d2a89562f1d25/lxml-6.0.2-cp313-cp313-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:6ec0e3f745021bfed19c456647f0298d60a24c9ff86d9d051f52b509663feeb1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a6/8e/cb99bd0b83ccc3e8f0f528e9aa1f7a9965dfec08c617070c5db8d63a87ce/lxml-6.0.2-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:846ae9a12d54e368933b9759052d6206a9e8b250291109c48e350c1f1f49d916" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d0/34/9e591954939276bb679b73773836c6684c22e56d05980e31d52a9a8deb18/lxml-6.0.2-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ef9266d2aa545d7374938fb5c484531ef5a2ec7f2d573e62f8ce722c735685fd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8d/27/b29ff065f9aaca443ee377aff699714fcbffb371b4fce5ac4ca759e436d5/lxml-6.0.2-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:4077b7c79f31755df33b795dc12119cb557a0106bfdab0d2c2d97bd3cf3dffa6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2b/9f/f756f9c2cd27caa1a6ef8c32ae47aadea697f5c2c6d07b0dae133c244fbe/lxml-6.0.2-cp313-cp313-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a7c5d5e5f1081955358533be077166ee97ed2571d6a66bdba6ec2f609a715d1a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/61/46/bb85ea42d2cb1bd8395484fd72f38e3389611aa496ac7772da9205bbda0e/lxml-6.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:8f8d0cbd0674ee89863a523e6994ac25fd5be9c8486acfc3e5ccea679bad2679" }, + { url = "https://mirrors.aliyun.com/pypi/packages/95/0c/443fc476dcc8e41577f0af70458c50fe299a97bb6b7505bb1ae09aa7f9ac/lxml-6.0.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:2cbcbf6d6e924c28f04a43f3b6f6e272312a090f269eff68a2982e13e5d57659" }, + { url = "https://mirrors.aliyun.com/pypi/packages/48/78/6ef0b359d45bb9697bc5a626e1992fa5d27aa3f8004b137b2314793b50a0/lxml-6.0.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dfb874cfa53340009af6bdd7e54ebc0d21012a60a4e65d927c2e477112e63484" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ff/ea/e1d33808f386bc1339d08c0dcada6e4712d4ed8e93fcad5f057070b7988a/lxml-6.0.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:fb8dae0b6b8b7f9e96c26fdd8121522ce5de9bb5538010870bd538683d30e9a2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4f/47/eba75dfd8183673725255247a603b4ad606f4ae657b60c6c145b381697da/lxml-6.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:358d9adae670b63e95bc59747c72f4dc97c9ec58881d4627fe0120da0f90d314" }, + { url = "https://mirrors.aliyun.com/pypi/packages/76/04/5c5e2b8577bc936e219becb2e98cdb1aca14a4921a12995b9d0c523502ae/lxml-6.0.2-cp313-cp313-win32.whl", hash = "sha256:e8cd2415f372e7e5a789d743d133ae474290a90b9023197fd78f32e2dc6873e2" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fe/0a/4643ccc6bb8b143e9f9640aa54e38255f9d3b45feb2cbe7ae2ca47e8782e/lxml-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:b30d46379644fbfc3ab81f8f82ae4de55179414651f110a1514f0b1f8f6cb2d7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/31/ef/dcf1d29c3f530577f61e5fe2f1bd72929acf779953668a8a47a479ae6f26/lxml-6.0.2-cp313-cp313-win_arm64.whl", hash = "sha256:13dcecc9946dca97b11b7c40d29fba63b55ab4170d3c0cf8c0c164343b9bfdcf" }, + { url = "https://mirrors.aliyun.com/pypi/packages/03/15/d4a377b385ab693ce97b472fe0c77c2b16ec79590e688b3ccc71fba19884/lxml-6.0.2-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:b0c732aa23de8f8aec23f4b580d1e52905ef468afb4abeafd3fec77042abb6fe" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c8/e8/c128e37589463668794d503afaeb003987373c5f94d667124ffd8078bbd9/lxml-6.0.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4468e3b83e10e0317a89a33d28f7aeba1caa4d1a6fd457d115dd4ffe90c5931d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/00/ce/74903904339decdf7da7847bb5741fc98a5451b42fc419a86c0c13d26fe2/lxml-6.0.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:abd44571493973bad4598a3be7e1d807ed45aa2adaf7ab92ab7c62609569b17d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1f/d3/131dec79ce61c5567fecf82515bd9bc36395df42501b50f7f7f3bd065df0/lxml-6.0.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:370cd78d5855cfbffd57c422851f7d3864e6ae72d0da615fca4dad8c45d375a5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3a/ea/a43ba9bb750d4ffdd885f2cd333572f5bb900cd2408b67fdda07e85978a0/lxml-6.0.2-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:901e3b4219fa04ef766885fb40fa516a71662a4c61b80c94d25336b4934b71c0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/60/23/6885b451636ae286c34628f70a7ed1fcc759f8d9ad382d132e1c8d3d9bfd/lxml-6.0.2-cp314-cp314-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:a4bf42d2e4cf52c28cc1812d62426b9503cdb0c87a6de81442626aa7d69707ba" }, + { url = "https://mirrors.aliyun.com/pypi/packages/48/5b/fc2ddfc94ddbe3eebb8e9af6e3fd65e2feba4967f6a4e9683875c394c2d8/lxml-6.0.2-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2c7fdaa4d7c3d886a42534adec7cfac73860b89b4e5298752f60aa5984641a0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/29/9c/47293c58cc91769130fbf85531280e8cc7868f7fbb6d92f4670071b9cb3e/lxml-6.0.2-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:98a5e1660dc7de2200b00d53fa00bcd3c35a3608c305d45a7bbcaf29fa16e83d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9b/da/ba6eceb830c762b48e711ded880d7e3e89fc6c7323e587c36540b6b23c6b/lxml-6.0.2-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:dc051506c30b609238d79eda75ee9cab3e520570ec8219844a72a46020901e37" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a5/24/7be3f82cb7990b89118d944b619e53c656c97dc89c28cfb143fdb7cd6f4d/lxml-6.0.2-cp314-cp314-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8799481bbdd212470d17513a54d568f44416db01250f49449647b5ab5b5dccb9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1b/bd/dcfb9ea1e16c665efd7538fc5d5c34071276ce9220e234217682e7d2c4a5/lxml-6.0.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9261bb77c2dab42f3ecd9103951aeca2c40277701eb7e912c545c1b16e0e4917" }, + { url = "https://mirrors.aliyun.com/pypi/packages/21/04/a60b0ff9314736316f28316b694bccbbabe100f8483ad83852d77fc7468e/lxml-6.0.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:65ac4a01aba353cfa6d5725b95d7aed6356ddc0a3cd734de00124d285b04b64f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d6/bd/7d54bd1846e5a310d9c715921c5faa71cf5c0853372adf78aee70c8d7aa2/lxml-6.0.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:b22a07cbb82fea98f8a2fd814f3d1811ff9ed76d0fc6abc84eb21527596e7cc8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fd/32/5643d6ab947bc371da21323acb2a6e603cedbe71cb4c99c8254289ab6f4e/lxml-6.0.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:d759cdd7f3e055d6bc8d9bec3ad905227b2e4c785dc16c372eb5b5e83123f48a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/33/da/34c1ec4cff1eea7d0b4cd44af8411806ed943141804ac9c5d565302afb78/lxml-6.0.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:945da35a48d193d27c188037a05fec5492937f66fb1958c24fc761fb9d40d43c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/82/57/4eca3e31e54dc89e2c3507e1cd411074a17565fa5ffc437c4ae0a00d439e/lxml-6.0.2-cp314-cp314-win32.whl", hash = "sha256:be3aaa60da67e6153eb15715cc2e19091af5dc75faef8b8a585aea372507384b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e3/e0/c96cf13eccd20c9421ba910304dae0f619724dcf1702864fd59dd386404d/lxml-6.0.2-cp314-cp314-win_amd64.whl", hash = "sha256:fa25afbadead523f7001caf0c2382afd272c315a033a7b06336da2637d92d6ed" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d5/5d/b3f03e22b3d38d6f188ef044900a9b29b2fe0aebb94625ce9fe244011d34/lxml-6.0.2-cp314-cp314-win_arm64.whl", hash = "sha256:063eccf89df5b24e361b123e257e437f9e9878f425ee9aae3144c77faf6da6d8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5e/5c/42c2c4c03554580708fc738d13414801f340c04c3eff90d8d2d227145275/lxml-6.0.2-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:6162a86d86893d63084faaf4ff937b3daea233e3682fb4474db07395794fa80d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/bf/4f/12df843e3e10d18d468a7557058f8d3733e8b6e12401f30b1ef29360740f/lxml-6.0.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:414aaa94e974e23a3e92e7ca5b97d10c0cf37b6481f50911032c69eeb3991bba" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e4/0c/9dc31e6c2d0d418483cbcb469d1f5a582a1cd00a1f4081953d44051f3c50/lxml-6.0.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:48461bd21625458dd01e14e2c38dd0aea69addc3c4f960c30d9f59d7f93be601" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e7/2b/9b870c6ca24c841bdd887504808f0417aa9d8d564114689266f19ddf29c8/lxml-6.0.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:25fcc59afc57d527cfc78a58f40ab4c9b8fd096a9a3f964d2781ffb6eb33f4ed" }, + { url = "https://mirrors.aliyun.com/pypi/packages/bf/0c/4f5f2a4dd319a178912751564471355d9019e220c20d7db3fb8307ed8582/lxml-6.0.2-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5179c60288204e6ddde3f774a93350177e08876eaf3ab78aa3a3649d43eb7d37" }, + { url = "https://mirrors.aliyun.com/pypi/packages/12/64/554eed290365267671fe001a20d72d14f468ae4e6acef1e179b039436967/lxml-6.0.2-cp314-cp314t-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:967aab75434de148ec80597b75062d8123cadf2943fb4281f385141e18b21338" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7a/31/1d748aa275e71802ad9722df32a7a35034246b42c0ecdd8235412c3396ef/lxml-6.0.2-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d100fcc8930d697c6561156c6810ab4a508fb264c8b6779e6e61e2ed5e7558f9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8f/41/2c11916bcac09ed561adccacceaedd2bf0e0b25b297ea92aab99fd03d0fa/lxml-6.0.2-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ca59e7e13e5981175b8b3e4ab84d7da57993eeff53c07764dcebda0d0e64ecd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/99/05/4e5c2873d8f17aa018e6afde417c80cc5d0c33be4854cce3ef5670c49367/lxml-6.0.2-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:957448ac63a42e2e49531b9d6c0fa449a1970dbc32467aaad46f11545be9af1d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0f/c9/dcc2da1bebd6275cdc723b515f93edf548b82f36a5458cca3578bc899332/lxml-6.0.2-cp314-cp314t-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b7fc49c37f1786284b12af63152fe1d0990722497e2d5817acfe7a877522f9a9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9c/e2/5172e4e7468afca64a37b81dba152fc5d90e30f9c83c7c3213d6a02a5ce4/lxml-6.0.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e19e0643cc936a22e837f79d01a550678da8377d7d801a14487c10c34ee49c7e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a5/b3/15461fd3e5cd4ddcb7938b87fc20b14ab113b92312fc97afe65cd7c85de1/lxml-6.0.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:1db01e5cf14345628e0cbe71067204db658e2fb8e51e7f33631f5f4735fefd8d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/05/33/f310b987c8bf9e61c4dd8e8035c416bd3230098f5e3cfa69fc4232de7059/lxml-6.0.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:875c6b5ab39ad5291588aed6925fac99d0097af0dd62f33c7b43736043d4a2ec" }, + { url = "https://mirrors.aliyun.com/pypi/packages/70/ff/51c80e75e0bc9382158133bdcf4e339b5886c6ee2418b5199b3f1a61ed6d/lxml-6.0.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:cdcbed9ad19da81c480dfd6dd161886db6096083c9938ead313d94b30aadf272" }, + { url = "https://mirrors.aliyun.com/pypi/packages/56/4d/4856e897df0d588789dd844dbed9d91782c4ef0b327f96ce53c807e13128/lxml-6.0.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:80dadc234ebc532e09be1975ff538d154a7fa61ea5031c03d25178855544728f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0f/85/86766dfebfa87bea0ab78e9ff7a4b4b45225df4b4d3b8cc3c03c5cd68464/lxml-6.0.2-cp314-cp314t-win32.whl", hash = "sha256:da08e7bb297b04e893d91087df19638dc7a6bb858a954b0cc2b9f5053c922312" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fe/1a/b248b355834c8e32614650b8008c69ffeb0ceb149c793961dd8c0b991bb3/lxml-6.0.2-cp314-cp314t-win_amd64.whl", hash = "sha256:252a22982dca42f6155125ac76d3432e548a7625d56f5a273ee78a5057216eca" }, + { url = "https://mirrors.aliyun.com/pypi/packages/92/aa/df863bcc39c5e0946263454aba394de8a9084dbaff8ad143846b0d844739/lxml-6.0.2-cp314-cp314t-win_arm64.whl", hash = "sha256:bb4c1847b303835d89d785a18801a883436cdfd5dc3d62947f9c49e24f0f5a2c" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.0.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147" }, +] + +[[package]] +name = "markupsafe" +version = "3.0.3" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219" }, + { url = "https://mirrors.aliyun.com/pypi/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12" }, + { url = "https://mirrors.aliyun.com/pypi/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed" }, + { url = "https://mirrors.aliyun.com/pypi/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73" }, + { url = "https://mirrors.aliyun.com/pypi/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37" }, + { url = "https://mirrors.aliyun.com/pypi/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19" }, + { url = "https://mirrors.aliyun.com/pypi/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009" }, + { url = "https://mirrors.aliyun.com/pypi/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287" }, + { url = "https://mirrors.aliyun.com/pypi/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026" }, + { url = "https://mirrors.aliyun.com/pypi/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737" }, + { url = "https://mirrors.aliyun.com/pypi/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97" }, + { url = "https://mirrors.aliyun.com/pypi/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe" }, + { url = "https://mirrors.aliyun.com/pypi/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab" }, + { url = "https://mirrors.aliyun.com/pypi/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634" }, + { url = "https://mirrors.aliyun.com/pypi/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50" }, + { url = "https://mirrors.aliyun.com/pypi/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523" }, + { url = "https://mirrors.aliyun.com/pypi/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8" }, +] + +[[package]] +name = "more-itertools" +version = "10.8.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ea/5d/38b681d3fce7a266dd9ab73c66959406d565b3e85f21d5e66e1181d93721/more_itertools-10.8.0.tar.gz", hash = "sha256:f638ddf8a1a0d134181275fb5d58b086ead7c6a72429ad725c67503f13ba30bd" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/a4/8e/469e5a4a2f5855992e425f3cb33804cc07bf18d48f2db061aec61ce50270/more_itertools-10.8.0-py3-none-any.whl", hash = "sha256:52d4362373dcf7c52546bc4af9a86ee7c4579df9a8dc268be0a2f949d376cc9b" }, +] + +[[package]] +name = "nh3" +version = "0.3.2" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ca/a5/34c26015d3a434409f4d2a1cd8821a06c05238703f49283ffeb937bef093/nh3-0.3.2.tar.gz", hash = "sha256:f394759a06df8b685a4ebfb1874fb67a9cbfd58c64fc5ed587a663c0e63ec376" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/5b/01/a1eda067c0ba823e5e2bb033864ae4854549e49fb6f3407d2da949106bfb/nh3-0.3.2-cp314-cp314t-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:d18957a90806d943d141cc5e4a0fefa1d77cf0d7a156878bf9a66eed52c9cc7d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/30/57/07826ff65d59e7e9cc789ef1dc405f660cabd7458a1864ab58aefa17411b/nh3-0.3.2-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45c953e57028c31d473d6b648552d9cab1efe20a42ad139d78e11d8f42a36130" }, + { url = "https://mirrors.aliyun.com/pypi/packages/af/2f/e8a86f861ad83f3bb5455f596d5c802e34fcdb8c53a489083a70fd301333/nh3-0.3.2-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2c9850041b77a9147d6bbd6dbbf13eeec7009eb60b44e83f07fcb2910075bf9b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d8/97/77aef4daf0479754e8e90c7f8f48f3b7b8725a3b8c0df45f2258017a6895/nh3-0.3.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:403c11563e50b915d0efdb622866d1d9e4506bce590ef7da57789bf71dd148b5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/41/ee/fd8140e4df9d52143e89951dd0d797f5546004c6043285289fbbe3112293/nh3-0.3.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:0dca4365db62b2d71ff1620ee4f800c4729849906c5dd504ee1a7b2389558e31" }, + { url = "https://mirrors.aliyun.com/pypi/packages/87/64/bdd9631779e2d588b08391f7555828f352e7f6427889daf2fa424bfc90c9/nh3-0.3.2-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:0fe7ee035dd7b2290715baf29cb27167dddd2ff70ea7d052c958dbd80d323c99" }, + { url = "https://mirrors.aliyun.com/pypi/packages/79/66/90190033654f1f28ca98e3d76b8be1194505583f9426b0dcde782a3970a2/nh3-0.3.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a40202fd58e49129764f025bbaae77028e420f1d5b3c8e6f6fd3a6490d513868" }, + { url = "https://mirrors.aliyun.com/pypi/packages/34/30/ebf8e2e8d71fdb5a5d5d8836207177aed1682df819cbde7f42f16898946c/nh3-0.3.2-cp314-cp314t-win32.whl", hash = "sha256:1f9ba555a797dbdcd844b89523f29cdc90973d8bd2e836ea6b962cf567cadd93" }, + { url = "https://mirrors.aliyun.com/pypi/packages/94/ae/95c52b5a75da429f11ca8902c2128f64daafdc77758d370e4cc310ecda55/nh3-0.3.2-cp314-cp314t-win_amd64.whl", hash = "sha256:dce4248edc427c9b79261f3e6e2b3ecbdd9b88c267012168b4a7b3fc6fd41d13" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b4/bd/c7d862a4381b95f2469704de32c0ad419def0f4a84b7a138a79532238114/nh3-0.3.2-cp314-cp314t-win_arm64.whl", hash = "sha256:019ecbd007536b67fdf76fab411b648fb64e2257ca3262ec80c3425c24028c80" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b6/3e/f5a5cc2885c24be13e9b937441bd16a012ac34a657fe05e58927e8af8b7a/nh3-0.3.2-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:7064ccf5ace75825bd7bf57859daaaf16ed28660c1c6b306b649a9eda4b54b1e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7f/f7/529a99324d7ef055de88b690858f4189379708abae92ace799365a797b7f/nh3-0.3.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8745454cdd28bbbc90861b80a0111a195b0e3961b9fa2e672be89eb199fa5d8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3d/62/19b7c50ccd1fa7d0764822d2cea8f2a320f2fd77474c7a1805cb22cf69b0/nh3-0.3.2-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72d67c25a84579f4a432c065e8b4274e53b7cf1df8f792cf846abfe2c3090866" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4a/ca/f022273bab5440abff6302731a49410c5ef66b1a9502ba3fbb2df998d9ff/nh3-0.3.2-cp38-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:13398e676a14d6233f372c75f52d5ae74f98210172991f7a3142a736bd92b131" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fa/f7/5728e3b32a11daf5bd21cf71d91c463f74305938bc3eb9e0ac1ce141646e/nh3-0.3.2-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:03d617e5c8aa7331bd2659c654e021caf9bba704b109e7b2b28b039a00949fe5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/53/7f/f17e0dba0a99cee29e6cee6d4d52340ef9cb1f8a06946d3a01eb7ec2fb01/nh3-0.3.2-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2f55c4d2d5a207e74eefe4d828067bbb01300e06e2a7436142f915c5928de07" }, + { url = "https://mirrors.aliyun.com/pypi/packages/42/0f/c76bf3dba22c73c38e9b1113b017cf163f7696f50e003404ec5ecdb1e8a6/nh3-0.3.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bb18403f02b655a1bbe4e3a4696c2ae1d6ae8f5991f7cacb684b1ae27e6c9f7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/08/a1/73d8250f888fb0ddf1b119b139c382f8903d8bb0c5bd1f64afc7e38dad1d/nh3-0.3.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6d66f41672eb4060cf87c037f760bdbc6847852ca9ef8e9c5a5da18f090abf87" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d1/09/deb57f1fb656a7a5192497f4a287b0ade5a2ff6b5d5de4736d13ef6d2c1f/nh3-0.3.2-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:f97f8b25cb2681d25e2338148159447e4d689aafdccfcf19e61ff7db3905768a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b6/61/8f4d41c4ccdac30e4b1a4fa7be4b0f9914d8314a5058472f84c8e101a418/nh3-0.3.2-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:2ab70e8c6c7d2ce953d2a58102eefa90c2d0a5ed7aa40c7e29a487bc5e613131" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b0/c6/966aec0cb4705e69f6c3580422c239205d5d4d0e50fac380b21e87b6cf1b/nh3-0.3.2-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:1710f3901cd6440ca92494ba2eb6dc260f829fa8d9196b659fa10de825610ce0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e2/c8/97a2d5f7a314cce2c5c49f30c6f161b7f3617960ade4bfc2fd1ee092cb20/nh3-0.3.2-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:91e9b001101fb4500a2aafe3e7c92928d85242d38bf5ac0aba0b7480da0a4cd6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0d/95/2d6fc6461687d7a171f087995247dec33e8749a562bfadd85fb5dbf37a11/nh3-0.3.2-cp38-abi3-win32.whl", hash = "sha256:169db03df90da63286e0560ea0efa9b6f3b59844a9735514a1d47e6bb2c8c61b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/64/9a/1a1c154f10a575d20dd634e5697805e589bbdb7673a0ad00e8da90044ba7/nh3-0.3.2-cp38-abi3-win_amd64.whl", hash = "sha256:562da3dca7a17f9077593214a9781a94b8d76de4f158f8c895e62f09573945fe" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9e/7e/a96255f63b7aef032cbee8fc4d6e37def72e3aaedc1f72759235e8f13cb1/nh3-0.3.2-cp38-abi3-win_arm64.whl", hash = "sha256:cf5964d54edd405e68583114a7cba929468bcd7db5e676ae38ee954de1cfc104" }, +] + +[[package]] +name = "nodeenv" +version = "1.10.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/24/bf/d1bda4f6168e0b2e9e5958945e01910052158313224ada5ce1fb2e1113b8/nodeenv-1.10.0.tar.gz", hash = "sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827" }, +] + +[[package]] +name = "packaging" +version = "26.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529" }, +] + +[[package]] +name = "parse" +version = "1.20.2" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/4f/78/d9b09ba24bb36ef8b83b71be547e118d46214735b6dfb39e4bfde0e9b9dd/parse-1.20.2.tar.gz", hash = "sha256:b41d604d16503c79d81af5165155c0b20f6c8d6c559efa66b4b695c3e5a0a0ce" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/d0/31/ba45bf0b2aa7898d81cbbfac0e88c267befb59ad91a19e36e1bc5578ddb1/parse-1.20.2-py2.py3-none-any.whl", hash = "sha256:967095588cb802add9177d0c0b6133b5ba33b1ea9007ca800e526f42a85af558" }, +] + +[[package]] +name = "parse-type" +version = "0.6.6" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "parse" }, + { name = "six" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/19/ea/42ba6ce0abba04ab6e0b997dcb9b528a4661b62af1fe1b0d498120d5ea78/parse_type-0.6.6.tar.gz", hash = "sha256:513a3784104839770d690e04339a8b4d33439fcd5dd99f2e4580f9fc1097bfb2" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/85/8d/eef3d8cdccc32abdd91b1286884c99b8c3a6d3b135affcc2a7a0f383bb32/parse_type-0.6.6-py2.py3-none-any.whl", hash = "sha256:3ca79bbe71e170dfccc8ec6c341edfd1c2a0fc1e5cfd18330f93af938de2348c" }, +] + +[[package]] +name = "platformdirs" +version = "4.5.1" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/cf/86/0248f086a84f01b37aaec0fa567b397df1a119f73c16f6c7a9aac73ea309/platformdirs-4.5.1.tar.gz", hash = "sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/cb/28/3bfe2fa5a7b9c46fe7e13c97bda14c895fb10fa2ebf1d0abb90e0cea7ee1/platformdirs-4.5.1-py3-none-any.whl", hash = "sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746" }, +] + +[[package]] +name = "pycparser" +version = "3.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992" }, +] + +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b" }, +] + +[[package]] +name = "pyparsing" +version = "3.3.2" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d" }, +] + +[[package]] +name = "pyproject-api" +version = "1.10.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "packaging" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/45/7b/c0e1333b61d41c69e59e5366e727b18c4992688caf0de1be10b3e5265f6b/pyproject_api-1.10.0.tar.gz", hash = "sha256:40c6f2d82eebdc4afee61c773ed208c04c19db4c4a60d97f8d7be3ebc0bbb330" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/54/cc/cecf97be298bee2b2a37dd360618c819a2a7fd95251d8e480c1f0eb88f3b/pyproject_api-1.10.0-py3-none-any.whl", hash = "sha256:8757c41a79c0f4ab71b99abed52b97ecf66bd20b04fa59da43b5840bac105a09" }, +] + +[[package]] +name = "pyright" +version = "1.1.408" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "nodeenv" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/74/b2/5db700e52554b8f025faa9c3c624c59f1f6c8841ba81ab97641b54322f16/pyright-1.1.408.tar.gz", hash = "sha256:f28f2321f96852fa50b5829ea492f6adb0e6954568d1caa3f3af3a5f555eb684" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/0c/82/a2c93e32800940d9573fb28c346772a14778b84ba7524e691b324620ab89/pyright-1.1.408-py3-none-any.whl", hash = "sha256:090b32865f4fdb1e0e6cd82bf5618480d48eecd2eb2e70f960982a3d9a4c17c1" }, +] + +[[package]] +name = "pytest" +version = "9.0.2" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b" }, +] + +[[package]] +name = "python-docx-oss" +source = { editable = "." } +dependencies = [ + { name = "lxml" }, + { name = "typing-extensions" }, +] + +[package.dev-dependencies] +dev = [ + { name = "alabaster" }, + { name = "behave" }, + { name = "jinja2" }, + { name = "markupsafe" }, + { name = "pyparsing" }, + { name = "pyright" }, + { name = "pytest" }, + { name = "ruff" }, + { name = "sphinx" }, + { name = "tox" }, + { name = "twine" }, + { name = "types-lxml-multi-subclass" }, +] + +[package.metadata] +requires-dist = [ + { name = "lxml", specifier = ">=3.1.0" }, + { name = "typing-extensions", specifier = ">=4.9.0" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "alabaster", specifier = ">=0.7.12" }, + { name = "behave", specifier = ">=1.2.6" }, + { name = "jinja2", specifier = ">=3.1.2" }, + { name = "markupsafe", specifier = ">=2.1.2" }, + { name = "pyparsing", specifier = ">=3.2.3" }, + { name = "pyright", specifier = ">=1.1.401" }, + { name = "pytest", specifier = ">=8.4.0" }, + { name = "ruff", specifier = ">=0.11.13" }, + { name = "sphinx", specifier = ">=7.0.0" }, + { name = "tox", specifier = ">=4.26.0" }, + { name = "twine", specifier = ">=6.1.0" }, + { name = "types-lxml-multi-subclass", specifier = ">=2025.3.30" }, +] + +[[package]] +name = "pywin32-ctypes" +version = "0.2.3" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/85/9f/01a1a99704853cb63f253eea009390c88e7131c67e66a0a02099a8c917cb/pywin32-ctypes-0.2.3.tar.gz", hash = "sha256:d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/de/3d/8161f7711c017e01ac9f008dfddd9410dff3674334c233bde66e7ba65bbf/pywin32_ctypes-0.2.3-py3-none-any.whl", hash = "sha256:8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8" }, +] + +[[package]] +name = "readme-renderer" +version = "43.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "docutils" }, + { name = "nh3" }, + { name = "pygments" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/fe/b5/536c775084d239df6345dccf9b043419c7e3308bc31be4c7882196abc62e/readme_renderer-43.0.tar.gz", hash = "sha256:1818dd28140813509eeed8d62687f7cd4f7bad90d4db586001c5dc09d4fde311" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/45/be/3ea20dc38b9db08387cf97997a85a7d51527ea2057d71118feb0aa8afa55/readme_renderer-43.0-py3-none-any.whl", hash = "sha256:19db308d86ecd60e5affa3b2a98f017af384678c63c88e5d4556a380e674f3f9" }, +] + +[[package]] +name = "requests" +version = "2.32.5" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6" }, +] + +[[package]] +name = "requests-toolbelt" +version = "1.0.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "requests" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/f3/61/d7545dafb7ac2230c70d38d31cbfe4cc64f7144dc41f6e4e4b78ecd9f5bb/requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06" }, +] + +[[package]] +name = "rfc3986" +version = "2.0.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/85/40/1520d68bfa07ab5a6f065a186815fb6610c86fe957bc065754e47f7b0840/rfc3986-2.0.0.tar.gz", hash = "sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/ff/9a/9afaade874b2fa6c752c36f1548f718b5b83af81ed9b76628329dab81c1b/rfc3986-2.0.0-py2.py3-none-any.whl", hash = "sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd" }, +] + +[[package]] +name = "rich" +version = "14.3.2" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/74/99/a4cab2acbb884f80e558b0771e97e21e939c5dfb460f488d19df485e8298/rich-14.3.2.tar.gz", hash = "sha256:e712f11c1a562a11843306f5ed999475f09ac31ffb64281f73ab29ffdda8b3b8" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/ef/45/615f5babd880b4bd7d405cc0dc348234c5ffb6ed1ea33e152ede08b2072d/rich-14.3.2-py3-none-any.whl", hash = "sha256:08e67c3e90884651da3239ea668222d19bea7b589149d8014a21c633420dbb69" }, +] + +[[package]] +name = "roman-numerals" +version = "4.1.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ae/f9/41dc953bbeb056c17d5f7a519f50fdf010bd0553be2d630bc69d1e022703/roman_numerals-4.1.0.tar.gz", hash = "sha256:1af8b147eb1405d5839e78aeb93131690495fe9da5c91856cb33ad55a7f1e5b2" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/04/54/6f679c435d28e0a568d8e8a7c0a93a09010818634c3c3907fc98d8983770/roman_numerals-4.1.0-py3-none-any.whl", hash = "sha256:647ba99caddc2cc1e55a51e4360689115551bf4476d90e8162cf8c345fe233c7" }, +] + +[[package]] +name = "ruff" +version = "0.14.14" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/2e/06/f71e3a86b2df0dfa2d2f72195941cd09b44f87711cb7fa5193732cb9a5fc/ruff-0.14.14.tar.gz", hash = "sha256:2d0f819c9a90205f3a867dbbd0be083bee9912e170fd7d9704cc8ae45824896b" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/d2/89/20a12e97bc6b9f9f68343952da08a8099c57237aef953a56b82711d55edd/ruff-0.14.14-py3-none-linux_armv6l.whl", hash = "sha256:7cfe36b56e8489dee8fbc777c61959f60ec0f1f11817e8f2415f429552846aed" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a3/b1/c5de3fd2d5a831fcae21beda5e3589c0ba67eec8202e992388e4b17a6040/ruff-0.14.14-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6006a0082336e7920b9573ef8a7f52eec837add1265cc74e04ea8a4368cd704c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b8/7c/3c1db59a10e7490f8f6f8559d1db8636cbb13dccebf18686f4e3c9d7c772/ruff-0.14.14-py3-none-macosx_11_0_arm64.whl", hash = "sha256:026c1d25996818f0bf498636686199d9bd0d9d6341c9c2c3b62e2a0198b758de" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a1/6e/5e0e0d9674be0f8581d1f5e0f0a04761203affce3232c1a1189d0e3b4dad/ruff-0.14.14-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f666445819d31210b71e0a6d1c01e24447a20b85458eea25a25fe8142210ae0e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/23/09/754ab09f46ff1884d422dc26d59ba18b4e5d355be147721bb2518aa2a014/ruff-0.14.14-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3c0f18b922c6d2ff9a5e6c3ee16259adc513ca775bcf82c67ebab7cbd9da5bc8" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c8/cc/e71f88dd2a12afb5f50733851729d6b571a7c3a35bfdb16c3035132675a0/ruff-0.14.14-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1629e67489c2dea43e8658c3dba659edbfd87361624b4040d1df04c9740ae906" }, + { url = "https://mirrors.aliyun.com/pypi/packages/67/b2/397245026352494497dac935d7f00f1468c03a23a0c5db6ad8fc49ca3fb2/ruff-0.14.14-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:27493a2131ea0f899057d49d303e4292b2cae2bb57253c1ed1f256fbcd1da480" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5b/06/06ef271459f778323112c51b7587ce85230785cd64e91772034ddb88f200/ruff-0.14.14-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:01ff589aab3f5b539e35db38425da31a57521efd1e4ad1ae08fc34dbe30bd7df" }, + { url = "https://mirrors.aliyun.com/pypi/packages/41/d6/99364514541cf811ccc5ac44362f88df66373e9fec1b9d1c4cc830593fe7/ruff-0.14.14-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1cc12d74eef0f29f51775f5b755913eb523546b88e2d733e1d701fe65144e89b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ca/71/37daa46f89475f8582b7762ecd2722492df26421714a33e72ccc9a84d7a5/ruff-0.14.14-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb8481604b7a9e75eff53772496201690ce2687067e038b3cc31aaf16aa0b974" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2c/10/a31f86169ec91c0705e618443ee74ede0bdd94da0a57b28e72db68b2dbac/ruff-0.14.14-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:14649acb1cf7b5d2d283ebd2f58d56b75836ed8c6f329664fa91cdea19e76e66" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fd/1e/c723f20536b5163adf79bdd10c5f093414293cdf567eed9bdb7b83940f3f/ruff-0.14.14-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e8058d2145566510790eab4e2fad186002e288dec5e0d343a92fe7b0bc1b3e13" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3e/34/8a84cea7e42c2d94ba5bde1d7a4fae164d6318f13f933d92da6d7c2041ff/ruff-0.14.14-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:e651e977a79e4c758eb807f0481d673a67ffe53cfa92209781dfa3a996cf8412" }, + { url = "https://mirrors.aliyun.com/pypi/packages/55/ef/b7c5ea0be82518906c978e365e56a77f8de7678c8bb6651ccfbdc178c29f/ruff-0.14.14-py3-none-musllinux_1_2_i686.whl", hash = "sha256:cc8b22da8d9d6fdd844a68ae937e2a0adf9b16514e9a97cc60355e2d4b219fc3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6a/5b/aaf1dfbcc53a2811f6cc0a1759de24e4b03e02ba8762daabd9b6bd8c59e3/ruff-0.14.14-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:16bc890fb4cc9781bb05beb5ab4cd51be9e7cb376bf1dd3580512b24eb3fda2b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2c/aa/9f89c719c467dfaf8ad799b9bae0df494513fb21d31a6059cb5870e57e74/ruff-0.14.14-py3-none-win32.whl", hash = "sha256:b530c191970b143375b6a68e6f743800b2b786bbcf03a7965b06c4bf04568167" }, + { url = "https://mirrors.aliyun.com/pypi/packages/87/44/90fa543014c45560cae1fffc63ea059fb3575ee6e1cb654562197e5d16fb/ruff-0.14.14-py3-none-win_amd64.whl", hash = "sha256:3dde1435e6b6fe5b66506c1dff67a421d0b7f6488d466f651c07f4cab3bf20fd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9e/6a/40fee331a52339926a92e17ae748827270b288a35ef4a15c9c8f2ec54715/ruff-0.14.14-py3-none-win_arm64.whl", hash = "sha256:56e6981a98b13a32236a72a8da421d7839221fa308b223b9283312312e5ac76c" }, +] + +[[package]] +name = "secretstorage" +version = "3.5.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "cryptography" }, + { name = "jeepney" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/1c/03/e834bcd866f2f8a49a85eaff47340affa3bfa391ee9912a952a1faa68c7b/secretstorage-3.5.0.tar.gz", hash = "sha256:f04b8e4689cbce351744d5537bf6b1329c6fc68f91fa666f60a380edddcd11be" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/b7/46/f5af3402b579fd5e11573ce652019a67074317e18c1935cc0b4ba9b35552/secretstorage-3.5.0-py3-none-any.whl", hash = "sha256:0ce65888c0725fcb2c5bc0fdb8e5438eece02c523557ea40ce0703c266248137" }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274" }, +] + +[[package]] +name = "snowballstemmer" +version = "3.0.1" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/75/a7/9810d872919697c9d01295633f5d574fb416d47e535f258272ca1f01f447/snowballstemmer-3.0.1.tar.gz", hash = "sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl", hash = "sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064" }, +] + +[[package]] +name = "soupsieve" +version = "2.8.3" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/7b/ae/2d9c981590ed9999a0d91755b47fc74f74de286b0f5cee14c9269041e6c4/soupsieve-2.8.3.tar.gz", hash = "sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl", hash = "sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95" }, +] + +[[package]] +name = "sphinx" +version = "9.1.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "alabaster" }, + { name = "babel" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "docutils" }, + { name = "imagesize" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "requests" }, + { name = "roman-numerals" }, + { name = "snowballstemmer" }, + { name = "sphinxcontrib-applehelp" }, + { name = "sphinxcontrib-devhelp" }, + { name = "sphinxcontrib-htmlhelp" }, + { name = "sphinxcontrib-jsmath" }, + { name = "sphinxcontrib-qthelp" }, + { name = "sphinxcontrib-serializinghtml" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/cd/bd/f08eb0f4eed5c83f1ba2a3bd18f7745a2b1525fad70660a1c00224ec468a/sphinx-9.1.0.tar.gz", hash = "sha256:7741722357dd75f8190766926071fed3bdc211c74dd2d7d4df5404da95930ddb" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/73/f7/b1884cb3188ab181fc81fa00c266699dab600f927a964df02ec3d5d1916a/sphinx-9.1.0-py3-none-any.whl", hash = "sha256:c84fdd4e782504495fe4f2c0b3413d6c2bf388589bb352d439b2a3bb99991978" }, +] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "2.0.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ba/6e/b837e84a1a704953c62ef8776d45c3e8d759876b4a84fe14eba2859106fe/sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5" }, +] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "2.0.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/f6/d2/5beee64d3e4e747f316bae86b55943f51e82bb86ecd325883ef65741e7da/sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2" }, +] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.1.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/43/93/983afd9aa001e5201eab16b5a444ed5b9b0a7a010541e0ddfbbfd0b2470c/sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8" }, +] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/b2/e8/9ed3830aeed71f17c026a07a5097edcf44b692850ef215b161b8ad875729/sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178" }, +] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "2.0.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/68/bc/9104308fc285eb3e0b31b67688235db556cd5b0ef31d96f30e45f2e51cae/sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb" }, +] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "2.0.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/3b/44/6716b257b0aa6bfd51a1b31665d1c205fb12cb5ad56de752dfa15657de2f/sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331" }, +] + +[[package]] +name = "tox" +version = "4.34.1" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "cachetools" }, + { name = "chardet" }, + { name = "colorama" }, + { name = "filelock" }, + { name = "packaging" }, + { name = "platformdirs" }, + { name = "pluggy" }, + { name = "pyproject-api" }, + { name = "virtualenv" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/5e/9b/5909f40b281ebd37c2f83de5087b9cb8a9a64c33745f334be0aeaedadbbc/tox-4.34.1.tar.gz", hash = "sha256:ef1e82974c2f5ea02954d590ee0b967fad500c3879b264ea19efb9a554f3cc60" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/ec/0f/fe6629e277ce615e53d0a0b65dc23c88b15a402bb7dbf771f17bbd18f1c4/tox-4.34.1-py3-none-any.whl", hash = "sha256:5610d69708bab578d618959b023f8d7d5d3386ed14a2392aeebf9c583615af60" }, +] + +[[package]] +name = "twine" +version = "6.2.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "id" }, + { name = "keyring", marker = "platform_machine != 'ppc64le' and platform_machine != 's390x'" }, + { name = "packaging" }, + { name = "readme-renderer" }, + { name = "requests" }, + { name = "requests-toolbelt" }, + { name = "rfc3986" }, + { name = "rich" }, + { name = "urllib3" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/e0/a8/949edebe3a82774c1ec34f637f5dd82d1cf22c25e963b7d63771083bbee5/twine-6.2.0.tar.gz", hash = "sha256:e5ed0d2fd70c9959770dce51c8f39c8945c574e18173a7b81802dab51b4b75cf" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/3a/7a/882d99539b19b1490cac5d77c67338d126e4122c8276bf640e411650c830/twine-6.2.0-py3-none-any.whl", hash = "sha256:418ebf08ccda9a8caaebe414433b0ba5e25eb5e4a927667122fbe8f829f985d8" }, +] + +[[package]] +name = "types-html5lib" +version = "1.1.11.20251117" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "types-webencodings" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/c8/f3/d9a1bbba7b42b5558a3f9fe017d967f5338cf8108d35991d9b15fdea3e0d/types_html5lib-1.1.11.20251117.tar.gz", hash = "sha256:1a6a3ac5394aa12bf547fae5d5eff91dceec46b6d07c4367d9b39a37f42f201a" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/f0/ab/f5606db367c1f57f7400d3cb3bead6665ee2509621439af1b29c35ef6f9e/types_html5lib-1.1.11.20251117-py3-none-any.whl", hash = "sha256:2a3fc935de788a4d2659f4535002a421e05bea5e172b649d33232e99d4272d08" }, +] + +[[package]] +name = "types-lxml-multi-subclass" +version = "2026.1.1" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "cssselect" }, + { name = "types-html5lib" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/e4/fb/ebc136cfd87b9719c631ba53f8f12e2f2874f97ba60e9ce15015d3367566/types_lxml_multi_subclass-2026.1.1.tar.gz", hash = "sha256:e871b63ab95221198a4a39ff581ccf9b558341e96c67f07909a96ab15b1c2a7a" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/2e/bf/13bbbb68bc10b506794ba525db5fd9b96fe42944eae06823b886bbf693b1/types_lxml_multi_subclass-2026.1.1-py3-none-any.whl", hash = "sha256:ec8ee8c2adba9d77e13c2c66ce580dfcb57a590185bc36cf1f18887ff0064b1b" }, +] + +[[package]] +name = "types-webencodings" +version = "0.5.0.20251108" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/66/d6/75e381959a2706644f02f7527d264de3216cf6ed333f98eff95954d78e07/types_webencodings-0.5.0.20251108.tar.gz", hash = "sha256:2378e2ceccced3d41bb5e21387586e7b5305e11519fc6b0659c629f23b2e5de4" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/45/4e/8fcf33e193ce4af03c19d0e08483cf5f0838e883f800909c6bc61cb361be/types_webencodings-0.5.0.20251108-py3-none-any.whl", hash = "sha256:e21f81ff750795faffddaffd70a3d8bfff77d006f22c27e393eb7812586249d8" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" }, +] + +[[package]] +name = "urllib3" +version = "2.6.3" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4" }, +] + +[[package]] +name = "virtualenv" +version = "20.36.1" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/aa/a3/4d310fa5f00863544e1d0f4de93bddec248499ccf97d4791bc3122c9d4f3/virtualenv-20.36.1.tar.gz", hash = "sha256:8befb5c81842c641f8ee658481e42641c68b5eab3521d8e092d18320902466ba" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/6a/2a/dc2228b2888f51192c7dc766106cd475f1b768c10caaf9727659726f7391/virtualenv-20.36.1-py3-none-any.whl", hash = "sha256:575a8d6b124ef88f6f51d56d656132389f961062a9177016a50e4f507bbcc19f" }, +] From a38ee1da20014bb143ec1ca32d07d85716b5fa42 Mon Sep 17 00:00:00 2001 From: Ethan Date: Wed, 4 Feb 2026 10:05:11 +0800 Subject: [PATCH 084/115] update history.md --- HISTORY.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 12e34db8..3f1ba6f8 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,15 +1,15 @@ ## Release History -0.1.0 (2026-02-02) +**0.1.0 (2026-02-02)** -- UPSTREAM MERGE with python-docx 1.2.0. +- **UPSTREAM MERGE** with python-docx 1.2.0. - Backward Compatibility: Fixed a regression where `Font.name` returned a dictionary. It now correctly returns a string (ASCII name) while supporting multi-script assignment via setter. Added `Font.eastAsia` and `Font.hAnsi` properties for fine-grained font control. -0.0.12 (2025-12-03) +**0.0.12 (2025-12-03)** - default dpi for jpeg #33 -0.0.11 (2025-11-17) +**0.0.11 (2025-11-17)** - round-float viewbox and enhance svg unit parsing #31 From 4e3d1d7106584b93f8101ddaa39c0aaa47da445e Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 5 Feb 2026 18:48:10 +0800 Subject: [PATCH 085/115] update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d554149b..b2ff619b 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ _As a Brazilian jiu-jitsu player, OSS means anything and everything. It's a term used in BJJ that is a way of greeting and demonstrating respect to others._ -**_python-docx-oss_** is a Python library for CRUD Microsoft Word (.docx) files. It fork from [python-docx](https://github.com/python-openxml/python-docx). +[python-docx-oss](https://github.com/lsaint/python-docx-oss) is a Python library for CRUD Microsoft Word (.docx) files. It fork from [python-docx](https://github.com/python-openxml/python-docx).

    PyPI From bd32214a30ea1d900f72c97312d2b0e311dbc03c Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 21 Aug 2026 18:14:29 +0800 Subject: [PATCH 086/115] Add DOCX round-trip integration coverage --- tests/fixtures/documents/word-blank.docx | Bin 0 -> 12101 bytes .../drawing/word-floating-picture.docx | Bin 0 -> 84596 bytes .../fixtures/fonts/word-east-asian-fonts.docx | Bin 0 -> 12612 bytes tests/fixtures/images/word-svg-image.docx | Bin 0 -> 1741208 bytes tests/integration/__init__.py | 1 + tests/integration/test_word_roundtrip.py | 131 ++++++++++++++++++ 6 files changed, 132 insertions(+) create mode 100644 tests/fixtures/documents/word-blank.docx create mode 100644 tests/fixtures/drawing/word-floating-picture.docx create mode 100644 tests/fixtures/fonts/word-east-asian-fonts.docx create mode 100644 tests/fixtures/images/word-svg-image.docx create mode 100644 tests/integration/__init__.py create mode 100644 tests/integration/test_word_roundtrip.py diff --git a/tests/fixtures/documents/word-blank.docx b/tests/fixtures/documents/word-blank.docx new file mode 100644 index 0000000000000000000000000000000000000000..6819df7232ae17c21b1b427085d55dc5476a4c1f GIT binary patch literal 12101 zcmeHN1y>wPw;doz2m~j%LxQ^`5C|S5xCD21*Wm81!{F`?!QI^%+#P}k0=&tUckj)2 z*ZTwS>$RqPYO40`>Y8(^>g+x;5-`s&0dN2W002M=Sk0L`sv6?2F zvI@|8R#!!tLE6hSbikK(O8D+T8GPWrKb;=u zo+uM#3-+}mJd41?;Y*THj(|V1C$?vkrS0z}%X88x3@vw8PQj0``||8>Rx$Nu-XM=y!# zFzsSO`f%#|;5*SGyV!w~Eybue4#ru4M^F=!!~oBm&OJWx%+Et>?CXdQO-{v*yV?Oo z9MFWeeH_;nQ51JRJL zGLe-&DzbB>N~2rhAhv-e+?4u?4$qv4krEiKTY`vp);w|Gn%$P)6YNj-Jo9-lQ~ENLI#5w;ynZa1SlsfTYbjgokZVC z&%pw+di`9s{&W~9$l3+r`Tu>C#0)_U1~Pa1Kl&zpq38Z0Bd}#IP70oV00m&))C?qHtm+5(Qk{o7gp{zN8?;bRDQybYNl*Co%C9bndSy}Vtw1RoZD^JR2{S-F5&n5nuP)#2;mPtY=YFAiEB4nI6 zRF5TJhOVeRyQi>S2UOgqQ3aY}c&sDtJ*`NxYfzcY{1!pmQjZatzW0Vyn%DI^WGnNZ zR+HX{IM@T3QI`+_05pg({AM+Ox0jp*uqBWQHQv?{nLFWgqP&~y?0 z3=c+$sm}bg3Y>qMv{{#fCSi$9eEnpIGltaK!WYuX&1BI)SI^t}(mgU>fvS19?y)>w ztDJ0=H6iXfwf;ceV=(U1m7`~p-ZpD751EgxDK zHkCYQ4$}^8vaN_)e6Xg5eHxKriw)tW1 z{`FD-fzZT5xtz0Z;X`@td$v9%Kz_q2DD4g2*ecbAcBjcZq4K1S&Q%U>>1X<9+RjSG zqduXpInrOEMgYtPsXXZ3iA=Mg5*C4NZo8`vxJC-OUJ^rxzP@hvOnVEH)J^qWIIbd; z)>c(lOiD6+FQT8p&U9u|YJ*OM#!ZWq$FxxyCcG{3nysdLP(zAAyB5|#b8F|zD9^4C ze?BIg$DnxOKp7x1gNLWzx||p4=0)%Z(Nz@Tp@Y*b=#cr5aH+_Vwj29e)-zl0UxuppIZ3r`m)UWap4 z#*e3++2T&`I4AfL62M;Bzb=i}ooD#$T9?Wi!?brXf!Jh1lj|@wLS;W?Zgprfo|Ik1 zRAGvliJEWFV4AQl_q{+POxI1WLiP;Z5;%&9)M_Wuu@C!lIbHUq_o^ZoAFnLe$rEDH z|7r8@V25$n;Q)Y95&!_}Pn)+lHn1>Y{O!#AbDlg>Q8U9A#q?mjs4xh<WxNnB&9H%eU#~n4!b3y1X>VFmOT}(K6B2vLt*r zqI}3RIXipA3l(TZ06leBz8?!(-r|uGt9rKm*c?HTesaCdy{+baWp-I{`^t_A-d*x$ z3sD9`VSc@Vj&DB9B}p|9P;Xwj6h(l%_TEwrhlzno)luwWzGq~pCl__+Z53`~>s|8D z2yDP+NKAIequjWSdj72Dfihrt&Zfn+e72bWiW+eCrEg*Zr!wkDSIKB-}(>o@wI^guCWjX*?X3~D{%rbvr|KJYmjmhln*_B+=;WT?Qv_DSI zCcFJWsbWiyWnvUshnk4VBzaGKOAqwQ42_GVh7mB>=#@RcQT?0%N^4E? z=||7u>QhafENVzYs#g*dvuaV?U2f4WqbK2v+)G$|RDHi#()3bfv3J-P)G22PUp^Vv zvPLO0Y7z0d+Wgq7-|UNwBz|Dga?`MU(ao=PavZ7kbbpk2HCDdb_T@YrcdW|U!c2r~ z&iKpykE_t#a*)T>PX22+=Tx5uI(IL!{u2DN{;$GhmHb`M*6FS3-6YT6&`w0a!0D10 zAng&MuwRDbwzqp7eprrhD(J_iTASJT7I9|Gk&i%XKh(*Aazf}J6bN_w$}l&ms)Gl= z)3eVO+63F4X<}j3Gt{y#gf@Bf)z@7d2iNA1 zq3Rs~_Y=#9dsVhv0kt>i9?8iFh@NJ33ypdX2pol{oq~kaqj2q1@u+5o&4_sfLL$8+ zohn-#Ynj1YD`9sj9k{PRFG;ABtPpTn2bOYJ!%rMYCKD!(xt+21KMqdJ`z^uw=|^j@ zTnnIn3Ioa#7*?iNRwBr1AER4R@Lyt(-FKppj5^#9K4W)EcdxSwWz&C&`j#~}j~pu4 zgUHDFS%#QPs)%Zcg}i=P#3J7|5|~vr5sGW4x)Ff3g*Tfv96$w}XHP4{c9Tzb z&P82WC~KKRyf}^A6QA;0;F}oixcL4iNNb-QF-&>&J*)Ou-V!s6wEW)IcFfE<6-vG8 zw6ovKi9W3<`wq4h{|!9m4~*g|p)ot2T9aF8yP*O*Sy7E|^oPlIW%_e!LtOzi&coR? zLXBhYA_$xBdAqDr3yT7StND&X`DbJWhD0S}W!QFyOd7nPXX@Upr;`(%_-m6TP#0rC zb0`xsnF%Dl0Zv!Q)&tw8j02HkCv085Daa!LKoOyxX3PvlY@o2&gZ<5>T-TWw(|WV8 zP}KLl6fB|p6h(08S3PUbDW*q9{e-95vq)!lt7M4n%7campwAl{4k^Nf8iJ#U#Q7-C zUz~y(^Dn{*t(tV_HRWyJ<4c=Su&n3B_WS9)VThbrXT5e{btn{(PSH&hX|W+{O%T(k zC9(^@Qh&2V_i=-iqmv4i?y}RWe$^ae4p!2H=Chx*R{U@}I zC{-L`ve|0OcALRc^}?a|9ywbnxshYG2jqwPTzLHHyJ0yR%!zN9M?vUx-1;;hPyM^d z&4{J<=}C~bXNM-e1iNo1Qv`)rJJM8bC^beRv##qX-)8}&1(@1os|I+yi?3s(42eVb z56Uhd-C6Iw?I#PZmSg?5gs4n*)Je`~*>)o@nzmR=CY#GE#pP~H%gh*THCE_t?p}}z z(rZX&Q{mzlJ_%^YCb+#>`KWJN;RbKS$b~cC1?fmEi1mv{um?SkxsTHh3c5u6=151_^Ya)qBr4XI85mTzzST6_E1%3%O z;N21oA*0@X2oxQC$1Rg0&Kw?7tvL-9J>(N|%=WcSt#?;e6rT*SGsnxs9zgh|;r5~a z<~|rsPv(i_vrTrbuoX3fdVHbqKU{mvgH0H}8;yUCb-CGr>{Yi_sF! z->NO3(!mUz7^TkJU|(K~ox*~bB@_whHPJ!r1#!dtW;`UL0$vI=5rJbt5v^n6PSwJq z{ySo0rBdX?EfE<{VcNj1%|otH{0IhB(E0d=1J5QoiUme$*edq$b8iMo+18L;;`7DY zy6&i$Jv}TH5oZmVZ1QFA`nQuul!}{~SRpbt)Rst<00B{)ohnimZGl!|0Z!yKn%O)2vcD`N6Rcab#WxCcQjnI zY0?-$qVPnSm(dR`S};T%X$RhywP5te0Y1ItzFv)r8q`7ua0?|xM{MNi(ouWl1T&L? zSaYqWoQM|q%|wiI2OCL>0zP`9Ts0L7%Np5UEd}4k$gKUs__JndKmY6w#n$xd^9Fu? zu3JK)-5;vhTs0F46N$>T?8XsCY@AOH6wLR|2y4)iBi=fbeq#F=!$RMlJMl+P7~LMD z{h$M&&R)DSFK!Zql^{tHZl?7NXLT}^5GiKwS&`w)YCpL%7~M03K_ryX)eg51jbCcw zxes_y^r-A?&18|Pg-S4gWJ>J)=<%gMeE8~#TWoH4d5X6SB|{*vhh8crn?_S3yV!}9 zxKOw)&^{8$U6=1!Yf(j&!TkElM$DO{?4$}<+P`e3f4U18;$`G@fg=@NGYXBGy( zs_XW9)@~8dG*IIeu2#)13r?t?kXeo2pnI_2s*=Z>76sPFi{6ANv^M*Qvk-73D6E;U z@s}OaAuB;!MPVQW-Xx~kx|mK?r{nN2%;nKeN*SVl`(lcM7{tN)X@Jd@W^-ulQ!Z2d zqI>{*A&nN@0!OmQa72E03a&ft8TnL;KG?(eig5NO$&Ivena-3mRB0Ba3ZsQT3R!i5 zsXw6998*7AiQ{EeWqdpr5oY!V)FB65sXIAttlOJ1wI9g^jlLxLpP%h}8y#!d?l6n6 zbIAG6MMTqRdvej?Hs1F)7!C_$7>~WqC zHEMZeAsXBDUDzX3dU83JmcL&wZ|`aQ*Il|jSv8p{M4{M+M5kyFJp&Sy%Gg?2+cD}{ z*&6&I!2egofD9clM#HR=2{Ygn{vL($hP~9ML5}vQi`Kt`0KaJ{Cfkt1PIdO6FU;rHFWysrBO!w_)(pRl$9%rI_ZLOcM zyqdd2(Ohw6`T_=f}po}kF>CLuXwSP(-Tc$7xuAq9+B<( zlGy0_#lMA--?6fkh#4;P&%-)-LSNN@mXE4uW zMFd4ylY!&K#C>AY1RxZyr@ADl_AQQb5!sEEx$$ju2^!rZ z(&%ut=_5aG#NFtO(3@O^6mwIO4rP?JE?AShw8}vx(Da=+0m#YS!oc*FxDByt_kfc zp|iXBVtq5kzU>61mS*ylrhvt$b;@UThQ6%!@VVCRZ6c-U25*wfXXlEqH1fMEs62&C z@+n$;D&-4y+lMe2#xg;6DKP9^vq08ZP@^`Lv+n&`HhP-!Za}y8M;{{@ZMe;6(w=4? z)%I&i7w!7E&i9a9)KLgjylvm7FSj{9Yr796*H#^BT#9xydq(W6vcNb0jqfzlQagd~ zU*+3VL~1E1NR0WvlKAAdQEVR4Ty@`3c*<>KS*dATj!hpuTY{Ws9kM^4TjMFyIa}PFU!gwyc z{lZ{Ekm34+Zev4BGN%g6p>j~Pv|MLM{_wuK0`qKgTn?>uNWf>`-4S$O`RIHd@-#$Z zuxrM|3{6UHCDq9`*QflAc0V&rI*IIcsH<7;NR4JBZ51Ku_`>}H_BmtZfUK7V-a&^p z*L`+_w-~Hno4kM%P|t_Bwsc?OI$#DyPFijqF*5DLhcS8;259i@mUAzejZ|;^h~j36a5OK?Jk}NXcB6EOCMd|mR2!3@dvc_$hP1e{=4nDT?LUy9!9^xQPEhZ`|Kd2N^v1a zPu@G58;8?}H#Fi2l#)eZ>5-bw%y(Ctt54TMQ!28pA2o&WqOgoi+<8^ww$IIZ7&c&~ zRlZ5lyX36`i+K!kJ(5==`elI^4`HjBF` zE#BIU=28`vd=4_07zf>rgA_n?c32l#<7rX`Jrc?Nvq=MJfLyXs#mt>;?&ajK!q~Z8 zukWwR6)XXLTODJtQyf6u@;J{UVVJ=N~Pkv^3CcGqo=Jg$EN+xz3gj&tc@}E zQKc%n;h`TKUY5j0Of;t_ z|8N>MZ~IVmH(k6wqcqo>uJm2BZD@B@;YWL{N#QCN@o}o-emGy5m0hN7n%<}=G4C{f zJ`a{MnV9pAJCj*yYawS!v&j5THYz+-mbEK*RK4Y(=>gMJG|;LxJG*{y z;+xv>-d3rj{hboG>yr|9RnpULgiyjBofRL76HGx97ZGRHTcYaBw?vGPPjSXuqSqO3 zLBSC_&O6L0o5^_yQiZy!boNyDnMQR^c230PoefPW&vllTMZK6#PW*^_m(y0e8k(kD zaGad3Uv8dA%{p7wPKT7$j#SxJ4DE==C)2p-C*=E@&`r^)MNXa#^GEJdq*1ghB$x7{ zqU7}qx30VwED`I9+|8vvBx8@<*;v7R?TbHJEy^$xBT6U67Kxfpp4+ z>H*s7PVwjVJI9qy;&v>lSGloZkD+g@n*~vb>AcTeC{o9XMeq?ztKw4bO3lMj@wlZ5 zS=TclnaGci0|s5C8HT9Lo-MZP1|-5^vo^C-B(3{DPg8M(*pr=8qFgd9f-jgE>n8cV=es0@bk=Z7mC+NsI(4BP zOndIxV^&ALbcJ*DWm$r$S&AZumNc@RlInh?E_nM;5rZ=J$bL;TqUes<=5_3*i6Q;! z4^3HxMtQ|53#O_P2L_AOvBjqR+)EZE1iW1waJMw)KErUwpM7wDEYlf<12L1WrUuuM z!4(1E0|zBC3(ar}<6MPrFrV;RT~*H26Ae&&#kAt%4uW6Xcbg;^o0c^u@KwZIR{cn{ zZ`Ag$sGY>lddh5Vydn9jGt@!&HC|Gm?dz8XiR37>WyFnxlN~kt{Diz=HW)#eA31|^ zx%$I*l52b(=L>u$c+Q!jYe)VC^{<5T1L=>^&|-Wp>MGY=RLsep<>&WtH$qkZFM?&3#S$8+$AE`>Wp&P8eD@-!$c zKo#IGORb}$!15U<9u8ZCru~fDo?!kA{PX1IK!Y=Z-tH|s!aCW-H=#%bFTy@X7iJ1l z!I|NyW-4-VynVZI(Wv=sicpt;Vg_gzWe=ZHvb8U_P3K7};1T@;ga#xjHLh<=N!|UR zptRim$%}2bfO1{8sZ%!iN9}%+k?wB8t-an@0%No-5JQLN4I7-Sfxv6h;gWmem6m$~*)>EtSp!s1IHvbXD zLF3S0Ug@kL-fsS>b4DrQTcqBp{if*UD7S~u>9Z}-%R!+PYX$LhdDmSkzAUGhbMo;8 zL?Sfn1;pOXDy%S+0i`JPm{PbB=pR8VLr{Fs779Th@EzL4J0d^eV)?=2V#$q*_#@QF zl0s@40A09Py_;c(n}T78)TAQ*n7{uHL12;n-VA2$dgY8HTL5vf0M(m=MkpiPbS@MI zg0Kf!Xqfaq2RU~(Rn=m=3~Znk<@UDrYhtO!K!9(cCFb_-ixwL#&yIA9 zm>Rfyl>4xk67h0-i6Jws%Lyt}Orv5^vGc^~ zvUbzT$HBiKRP!0W$8O$4U3dzlUdzbr{05YVoDR%^=ErzlZo z>>;3a^~0}~9FLx#08}8tbr}f3h9N=r4Wjw6aQZe7ZP|8D-eZbJVLQ!6*n^iVFUL8899|8$w zfrdB1jWM4-z88K9OGRc?WH_Lj)tO;TuYIEUoX4W+`Sm**6PR~C+c~odb51LI`*4DH zFJ>2PWs%KU{q?(j>6D1yft?z3TQoUi_2$@tw@;I1S`3)U*@Bt>0T?wB8i~R)yG4O(|_5k&vXZe|g_aic_v)1_`Zx<~gALT}jfh zw*Ie>1c`P2IDm4Wq#@~3E#%*bi&pCG38>gy_>B>4*7PP3f!W;_{H zKHC`$?{c0(XkJ&h-O3Ta-?u5Kyb+<;ifo)3j+b~}5$(T7sbjiKULHgQWiA{V&FF;; z)%-O>w+t70-kuC0+1N7~NYZejj+*@)L+Lz6LBhf(qA=u8PM0_x`VI%R^hM<3;xi CjH5{a literal 0 HcmV?d00001 diff --git a/tests/fixtures/drawing/word-floating-picture.docx b/tests/fixtures/drawing/word-floating-picture.docx new file mode 100644 index 0000000000000000000000000000000000000000..9a9141067f1f094c7ef484d66a5b09e739f50a9e GIT binary patch literal 84596 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 r{@-lQ-@$*cYX1b+i~bY*mx@e-jwM+hv literal 0 HcmV?d00001 diff --git a/tests/fixtures/fonts/word-east-asian-fonts.docx b/tests/fixtures/fonts/word-east-asian-fonts.docx new file mode 100644 index 0000000000000000000000000000000000000000..cadfaa846ab6ce619f4a68a8738b8d6520b58d8d GIT binary patch literal 12612 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%0DWU$wuRauAN2El0@A^Y&s0N|uM;<@Ro@!Cc|2J< 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 z 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

    MGyZ-wf`PDzYQb3*6ekj|ne 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 z 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�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⩔<98L>D{9>QwF7Ga3w><1;48qv9r){A zg3@G!ed*x@c>KhBwaqt`OFbG_qA6Wk9j6FVN4gOjMuC^={pD?pTp47?89?#fQ9-dyIQ3*}>1#!p7`; zL=BahKLI`~`PK86uFs6e{COrfpc^$on$f)vCSq`i?RsrsBu{r2YXPG6Z*0a z<=b?=+!ZP}5ZyF)-CW|xf?HqlE4bnbZg#)0l;!jH7n}PMcel@34EYjUhs>@XM9{V3 zX%9x$$7F;|86A>HJ>7Z9@7TqfZog&(TXQm+gAl&g^fYMdd%pep?5PiPol)f|pZ)N* zFu(;!z}d^LUdq3ovO-ZCo_%Nz!FCn{^qRL63^5JEuukA8tV@gu4kRcnTX0g#gIgGV zDjZ_>m}_F;pMg?3%pG4g}ZNA?2e;PE0pQI1&b zq&U+2;tTbC?GJ7L0`;(x=lcXPF2cAW#fVAC*736v4Y9H-$g4=8^jXsMU4*wou}wTT zvgFoyY9v2EZ4Aww!?;o(9?Eqf`lA&Yi(^NoA;V=om-Ug0kZSvf>btmRWn1el;)?CB zzbzISQXC?@u}aL=6$LL?=XVOffRS$n{|jB?6Cqd^;qU%V*9H6gW?W9%H_U)y!H87Xb9wd3~mJE5oOB_1DG% z>*#qnokvU%HVVPxUYcIbo4ev}f*&uYUl6(_iq=dN?A0D={mBqfpZV(=oZ)iSIDYIX zF=W3p8LQNl%5St;d&oDjHIQ{8RR;DB+~Ij_E8xMIH4_N^n8ACt=KdviDH$jiQrSnn z<`knlg`GA7aFG)KAvj^UblqDbYnAHb0!~hIf&MGiT3`J2ncH7KHKfub(cJ1ToFpqq z>@2obqjXdEt8s|+Hn7dvzYQ6tT1Y0lT%(AP`dP12_efpHBJ$A{Z zh-osmnZJg`*jX0HMWR*U^zx1y)S-0SHuGY#4{NyJC&Q-ciO1r=I#}s{d_}$74hxKp z-&inhcrM`^$!XmR!Ha23(8~PN_En7b2dtx)kgqe%WDj?%+*yF4#P8qDF^a9Y!*>5H zhsSepJMC|I`+c64NRoK68YJ55LkGxPtQXix{H5+@5CwyA4s=8M{-q9_LZQRcAca8GT=y89Nrte;MTy__SVw z`D7BKZEYZ>Vt*ernxrDIDnpAAS$C808I*~PeF$+mlzH5156k{~7%=jR1XHgTfor)n z@Mc8C6aVx}C)1XI+o_2AT(0*2vRTLCqh}3`qDlMHOMhVgl64C-9IYvl> zh|=ASw5W7xaRU#uTCp?hB7L*;Cw#zTq_vwj&jprryVJAedzoAdW@V7z%du(3Bv4|67GMYB6#Y%N@oA$bg zO@g{hv@BMFyPmx`H%|}D>B~_`&B1x#Hm3%O5i4FSRt`83?ZDEFt|_01FS>Nt0)ci(+zjct=wYJ{CCYs064k0yv+BX zkRsrRVLDO1mcXvXsk{D4K~%+(qK%DTcuguHoD;6WV5ufyJWrCd--jT`N}BXpS68QX zA5A8S6;nOy=V{?y*hiHJ*3MbBLi@#{+1ex45LIX2W?{mLI%^DR5VIXBsb1RbPm1_eoz9>?eLq$zT~hIsPZy_ zITb9#2F}%ybI$|iL-3hq8E5a7f94Nyc!MBij)88g5Rw+EF}O`DffT6mV}yy;Yb>?% zVtGh>zo}U4;^zK_^s>LTml$B2vTC7pX#EO#PS>-i;{T-|J@D9xaDBesH#3TITJLW> zkg+`A=Q-Re;FrjleICe59dhxB@qFwyBy!1ME2seHM0MlItA#w|M!>$25%32lyx(8aIhUYmq8wg`yq#k z&v*Gg9Y-DfxJF&H@fh9hyU1{7#wfYr1I0cx7oCN_o7e2%{~p7UYWTh+>$i@WG3!K% z(*RY>WN^;W=jUSC2;yymCJQhGWCuG2-Hy`JxBW4?*-)fN16S?H~VB!gV_xcJN&R$ z8RT6@A=i+-5&=^_d9Pt%UwZX;r0CASC)tn*l6GQ>Ig^=E?Bxfu$R!(PZ?qDy4p^5y z;LQ0>G}x$%(2vKXZz;FhurKByct%i=D3<)<+#muU2?zNqM6^>tGm86C2X1S%BqK0N^^O@md_Pnt=hcK(n;Ua4oGv#4ZO)kzS^ zF!MzMMCdVGU`?Qy&?`6@alTJxJwnO<&fQ&Tm9cn3P!iPQd9a$Et+z-H0DC!CFBrvn z=08fWe+dtdEs`uI26S>o;Ac>HT7d}j-99Q<{5Lyf;7#LXR?P)oqkeu!4|G62^rl@& z5291wkoNfVF4L5GvW`|;r|1S*{g6eb)X>vwXEW|Mmo{njRF#f5W?yz3u_TVx@RMfy zEchhd-92yC*%TRfZON~ubC$s6j5z{T9coXTt;6?3c19%uaq^td-yz_eamIqitlket zS0#@+`tUIF=wa;5xBaBvaPaGgQu>+2T8+%n^Pwa{$(@%%m`TFZaZH)6izp7eP8qt8nylZfETC+#)5R#Xen zx1w={qz_SVv`*mxA4V(@ucmF(vnLMU4r%2K`(k!_i-J{3?3N+fGD#u0!s%JL)ap;q zzcsgmN!YTCsM=0}2TX7Tp~u6MhlRWr+@BIA^TsEJ=4Qv zB+{d0=WLV~wep43_WA5U<28U$JM66~!B*ShYgmd=nJC>>U60Dnt+uFW*nK(=x`HT` zP$E;RfVh!`qdLaMu?N>Vg(BYdt*ud$z1$O*xCn-Xcm={VuJah}L1*zk@q?V=@3A{< zX`12VHdi+4ylXs!(Fy58+UuBkCn?`E=bOyg^E|@0u15ot@-Xu=7=CEL)|pzfDNn~3GVFkMTC0sIW;NW z<}%!)_mF{M<2@ED{VI24huj8rOq(1gWkw0AUv7r|RG~*x8*K`BU5m(jG@W zgV$#B8JGC|b&LFAZg57_%JNsLjPLx!57D$3IloXRr0-k0mz}~SeQ9`83DKCVJRbv( z%suwIHHu^vWMYZuj;ngrnfFloWC1~QT-H^O1Fc$1yf%df;zKtYIxfo+r+Faxp=f== zU;ge}YmHK+V+dC-yFQ4$2O8eYb+Drd?x7pt-IeAa_jC4?A1V9w_p-!A@{$vXqCsiL`mo|wfdMA~Ep#=hzR;WRD!S>FwTDMM=1&e+ z#FFEL|JO6w9=?54;{nXr_J?!!rS(MtyXBvk3^`qM*r5>6L_(>im;63~7Y&kl|9cMqsV<1a0 zA~*rw>!uEUlyzU~ezLaTiRM|e4w;i`Owk#&D7A&%c%osbwrYtIH0J{oyq zsY&!CKXqRnUhC&t$$1kaj$EnOxx+I_ODPo+v-2bxBH#G&Kmg~_3?k>+B5ztHm7HAl zvcZjV$NdPs^0k~H#(I&$ubW}F-Q);i{>4Yl&rtgx+jE^|>hE?Vq49nszoy^)?Wq$* z%+or1*Yef`!QB>T?^Q5#*{2PRd&DYEN79rt=RRQKjp@HV@v^UI2Y71_<7>q4y;FE1 zKKAryzA8;?9oev=hw*DfS8>#dnmZ9=LN3~CA$#2&`+bP%06mx05Gn${IWi;mk~7`ICZ+~|iHtUtjpnYd<0aof?2-r=UQ zfl|CIU&G|*!bSS(kE{vWJf=n#)C&N?q|}gd`2S(I;UHFtClE z+CU{)_@D=+qT|KK;GGwh3*^tBjhoPivbTK~2Jy1$wNy^t(VB~ME9z3P8CrUD`R-`M z6?JD$)9~ktu=^I6*V9d+%{E44hx#YWG~>8jP{qGHw0c821$zC*=$CPRw`qL2ZN5^~ zLKV|MzAAmw@K43dNx}{EQ(melRxbv-CKvN}0NzfV8vTpQ6K82W!f^5*<&F5%%tC_{ zZ4{j4DDyZDV@PO0pi%{=a4Os7-Jwbr%rnsxrw`hxEE87u0VyGCXgnG(6JxUMZ8lt* z3r8nO604;7LhqaPq8CmtU&mJkXo2AezQ5J7qFW2AgnHU_Jv9co%1+*5fRfJ@BRC=r zhCL`5L{5{&vwctda#z@@UDFT=0Gq_wMjXn!Cu_sG!ZY z9k2;y&qUlF{|kiseTV1MSdj?7ebM7y54eZ34p@G8`%=2HqP3x+;Tv>Q9F1WT(D=T8 zZEoBH##akq4L{kAa*ty`M3XgTjp9v>TC0n@<+y-~Gxj5)BE=b9!eW&~-lA%g59EDc z6uBPKFXg%EJ6|dDrzeDfYXUXX8JLZ)0T9@|0J9-iqXpN`F~>d?7M->)ttja?gbVAW zjl4Q6Ag7ulK%w2CnYiNDN$yc<51s!ELhOlZYh@3WKwIxlTI zx4GyIV8u!$#b_BrvK&QsG<%es&{f~rk#X482hwH@p=(>53dXnxZYX1(&{D z%q<&lJfY!cxQo)-q5lsiE{LEV&pAsYslnJ5qHR^-AY?G@ww)ifT@tjQ0Q1gjNDF{H4L57# z0Z6h4gY2&P@RS|_Dp2WlioXQbRZyS3xMA%H(3~|B;%34V84==J(mV{cDV$+j7&mq? za_yum4FM-DosU5MtFbBVSNHt7pHR)48=Q`9(fo^FXCpY;37EXdu4M};jeW|4!}8dy zvMv<8hG`KOrdtK%I=K9ds}r2aZCf;?xlQwIOxbn+H{Q{4%^|k9!C>cZ;MJfd6MS0PF1(x0@D9HZ{x}K(+ySiD?O}F4+!XJ(5x?IWfYtE_r2rF z%yXCJV5?Oy%|j<8$(tNPtd^>0-af}6xrTBdy=8nPUA$8NJBX{*K7u~#_gsPvHWKd% z&nv32KumfstCw45WA*SDMrmw2xjAXcwdC~k*mspBhAQqJPe)gGxJV?b2-6gNM6txD zjtI7llG$Qr>&aCKaJi`AIzga6MfbT_gT>(BJ689K#P5$ellnbU|Ku3qkxRA>{TRbr z*#?r-z%v?Tlq#OROYn!u*pxw#^;Pj!10dulDXIVl_dksb-gfbPQQ64TJF*frO%CX? z&$n4nY$lfMs_mJ7m-ze7;KpN9%SP4NV&jsX;#+okF3VN0FEuMZvlj-JI-u#XjM zsg4EV2PwnMNx3Uj^^N0+HIQ z#eyHik=e%2N4OsDN+Ta;*g$5_O>J>T1@;RL!YYL3SO%is<>~$`+=oe@@44I)l?CB- zTd97H&3I1LJ>T0C5lM>6Tw4il+g?4V^;)CEcZP&~Ce6Pr+qB`PmU{?*n@6sCwwb@I z+V90F#)0<#N_9gjNRi*i)z#J7)^@9GUF7s9F;Q}37OJidbFA&=*#;%(9D9bQ!Rij8E?v0 zE8+vb!dPC1^OsvWN$bKZ)5?47qb=74m;sX{_U%wv(qj1r}g@WNOKZ*X*UhpS0GQHav?Tw3a0BWIL?&=Q1z*%YU2z~{LE5=MuFyfw#teS z+`X8Tz7x3bDYjR%7JVGkVS3l2fW?x{^T`s3ZFJ?$Mf+Egi!L|&=8qC1jrF>9CG%5U zDLgN*cC`O_*07A+?!9fgyy8q>-@Ta7qDm#mw%bZc#QuSHDD3VVkpbfug?v+rt`@(p zwO~Xm?{%?lT^7ebF%D#oP^hKnd!sX8XtkM}tR!_1+s?@;MRA+K-nSOa&S4_4`1jRjv~&X|nfzsg z0QjsBvv}MqpDe9ur^ToLQR+&Nbz{!xNyNO$BuZ?+YDqhx2Y&R0!l$9jKLhV|$<1Tj z<6(7MDEI=ugYWNG(q^gZqM|IN?&d;6>6slQH@lIMH2J{b5DgrcqWzgPy|&;K;-v9S zK@pI#A2I;m2}OBZE)}5QQxkU?Fe-l3b&GLJ6%8r3m##e&bCiAE>5+FU3bIn1j{{;B z##!Tt>Lpcr0Du3tlK%aGLwja{q zcPY&Jlj=C*%MS&~r$fA9*v>D6h`aQrBhVEg#NXBX@FWAI0wqN3Jtz=Ha*AFz4P|Rd+Ez_$-QL zZVf!aR@)<(;cP5fGJY&rTbQ^92~l(8b4;OKI{$PM9G1J1l~T+|2N!WmLwpkT=ZrWI zZg{*Hy6qVz-#s#9A|G13;FXYcQLr11AV+h4i)u3v84-tXqZ>^VIj))6Y*x7v4;uMi{rizi#jukcY&G{NiQ>SR+r z`t4nck=Dkv`|vk&zvrhYcA7E2W!rBHY5ymzmj{_gF6((a>H0jwGNV4OvDU-+dJ1$EV7M_v%^01l4ZIzMgzV-D;=7*iE;h4^Vii$O zdG255&qYe2OExD7oK%mqL5`6-x`&AoJMU%K%fs+1xEYyCqoR}rEPnuQyS41fwBa0QU7 zjUL^PVU{gdDj(x12eVLHrdlC0f`AzurFkYj?5%i2K-;(`_YGwhchYVIE_7fSEA24FdrRQoWD~< zq#r>_g-O&GhYMUV@P}nGJN6u7^DpO)=J)3YUD6#ZYJa$V3B$W$Kx0*|pwGl(B^Dls zY>0~`PI~BP*s=9X?VB90Q6yNAlZw(=k0sKcX3!Q3h(ag3WH^l;G2mdYjOWnMdT>qJ ztguwq@{Y5mCCWfKJtp2LbE)qG4N6W}5%G4te05tlAvc24iquu%xad3foUT?gmvcj7 z>209yUosxAB`6iKLxJ)B_CU0%j98IqnK#mhNwgzjD$_x}&A_nJV+WeSi``8UqVUi= zRxLb`$g>$Jw>`<9Yy*NCh>*ii)MF3|LzS?1M0Uu=Bo!x}`b+scV;4z?xi->hS$1d= z*7T-*&4c+8$+p&;SO2jm6h$?%i0o%W!=V9}^LXrqsLlt0MPj@k8BPD4ieIa@wtE?= zd+3Mmo9po7rNPAxY9aM2PmB!2^T-qlIAYaU&6QXT9j{|#O&cT<}2u~E{yVLdd@-NSr%F&0n?QM>p9c=`!l{R@a{AlC8BT^F1k@cUy z_{07{l(>f`pXr7W;hJRd&w2{8Bn1r%lkV!p zMOLI~m;}$45Z%`aRg&)(Jc~QgS*xlI(>{2_;a?Z{DwZY2MecG(Ni9ELz1_dBjz@(m z7@M1Ti?j1&6Uc;r5?m(97h)BO6WzzNUPw>WC!z3v3>7&aQ1i{axtkn?uRcOn9O+iSrqxiP zbQ_vWwatpvZ12oY6uP3^($hl2$XJR!c>OJY^d|{H1_q;~?lzQ% zpIp9Z`8TW1uH8cZ$;(zYL4b!(u}PEd2#;$6m{Yf!e0ggTW)YPKQR3fZ@+p8WRgGH2 z=n{URL+d?Y=}K7@mE=YBm&^nMd48D;M!0V{vUeuve=AO${=|TB&F-x#J7^*4b9dbnpVFH2 z{~_P|Z0q<Qvp*21iLdoTYbxXsCt|)lxDLT-QVmBNBtthf~4Cmbb{f3Tji6Q{h05__4 z+Sz>XJ9la9{n`nBPH~kgV@CPIS4U-Q<8Hr(i&AbohFHH^_K4{#K834Zh_ zn9~+yVVX?n9bjC(qT()pW`V*@L_Bqs9HUQgq^0XfujuBsmOV$2UOHB{R@C@AxO>2` zQCIah#7_8eBONy_i=b1%^gSeG^G*hw=o_MDk)=2n)snf+g!oCd4fDzP9lA4QVNAJ2 z9c;8x$E-06*6`7d7yTn}j21oA9NlNdzb_#Xyx;H?aB!DUz9zl}gvSCW-~af<5j# z>4-C$m_JkJ975T;Q8LW1^**}GNLKd8pA9SH<-q2Ac-%-S?!fCjDCsD|hRo>Or-P!C z^ZaaXNX3?TbPMdo8P%snjvJ%YjuYp8${_{shjb2YMTOHIEF@>1yi_8w3;46mbdiXl z)eZPTHuJc}wn%6Eg5Du===P=~`-7$J3>o&02hQq|YlDuczNXM-?k<+p`wG55n~P=X z9O$RLdfgOEB$;f=10m7L%1qVCU{^)S(F)d*_4XQKddo+BTLVH-w=={{8Vl4$WV7uD z-lcJC6dnpvUfIC9qWm(g&FKJ zXIE|^*|UoiL~C2Pv9)U*d(3#dLji?u7fTe+z<(&zJbPo1K9P9S>zom9Qc)YW@bz=Y zW6ifMj~AG1lQwZ@IUjeHkyAG;nMGGc-YV{bo$EDG+q^tE@^kK@1<^o{c{=rcV$l(U z08V>5Su)>lW~VEQ6*U3~!r7FF-9BI9{&daUG7-ufBql|o#z7J|gjtZ<*r>_GA6@cV zZs00HRRM8(-E>b?g%)7UkxB6Zh-L|`-n@{Dq4SOkleq_z(z=r+Nb=Knq~6S#miOZJ z6*38%zb3gogH^D+P5Y77$Ay1%W?HT5(qnH);;%zzYQE3N*UfS6y_g4r=w@GSi#6JV z>Te#}JLPWA3EpPm^^N67Dct<|O^w!gy@54>5j{w*&8=mg?OG85IKmiP-0zs0VI+#6 z+Sb5sLys_-+XU)RTUiG~{_x}HBJd{6+0E8iuII9aH}AmFkh!kDe^_Wz2B5Br0&DXAXorceIZhDVUm53_HnL#fy*+X z>xVG8e=E^IJQ`kr;MUt`G53Uv1rF>F^%4m-$+?KV*Ltpe%_FQuTQQ0VdXjjPIm(sA zCD7QBcBALOoygC!{Dh4=&zNoDCfdV zC~ZZcGvn?#zqc#o?)WbCYU<{vgyP)<*j_XItd|zm$k{Jo?bTM%etRj{FT@_`Av9q9 z(V>vXP0eT`aP(N*LH2_aStdrs9rrI1BlXOvfcx{y#%4Ma+%}dU$TrvvrkGP^ATx2= zS%@PC)rwo}j&JDgtMBw&mJyMA^`coR>6BeF*!J0AUsPxp)j9GE3Y_z(T8ado5TP>VvfuuXoBQ95$a}_VA_Eva(>0YLqQrk*Ak=Ds) zn3izkL?I-_K^ucnFW>c zG$M(`*<@4R`)6k+2_CudaRWLE&j>X2EG8q}lO@TE;i*QUOU1TLVSwJ5Hl{a)hU7$u z+gSkQtkCr9ToIox+|-jGAQ-*%dCzSJ2Xc^$jGu5-7PS{`pc^a>YpsZIkUQmOKkrpj zX)IiSK{d$fgD8vr(57zUkrVKRv&chFKz>#4qM4Z)(ieLp;i~QXjprFjXw0(+f>;Nx zBFX76P!Y5rJv|xrrTSI{H-E7jAb#tTLu(A+!?w62h0(Zt9|d|U>V zkBcgKTCAm9?6252IK;N81w7@wW%0)nqT-`W7?_cqFLjnl^>cbm--pdZ9CU{aRiIM# zQ1t;c5%OEPeS)oDrh!rU-L zR?nzTmkr36Eb9}V?0^fQ#?~Q+u;{Ti#1DV$t_Lv(!DuGluP3|1hNc{u?tpiz+3N4V zXR)P=%pS@I5ou7Ib$kA~gO}8b(a35dr$1N2(|j)Y<|*e&?Mh8j&wJqL(_@j{it$Vx zL((#Guv!XfUhT(z5FzJhqE%qzu)Xs}4Mzq6=Nwyeu`dxR^sC~89Lt2J>F(nRh(N(2 zz75)T1N^xN`Dr>4DOb*gtTDFvvf&8Aj@8P5a>>G=C&$}y<}_IQxq=UZZ<@ONfDvST-7qk+aU)a;?<6! zEZZh7b#aG}^|wO~?rRLxf4I*zNR)w!e=k~5HlJG+?>hH1t;p*R>=67{piudP7~C1w zKKxlk#!LT(qlZ-Cp>}tRY+QcvqsH5J&vTkl)8%G+$Yu|yPWzC`H3;{mCVZHITx%cx z$w`v;LTscRYONL^U!5y8=DRgX=u~7L-lp7>e3YINPU$7%|L=_13L%DaYjK-LsV?-9vU^=; zUzN;(BCWwR9maA24Ir3cC|)>j;tmOVx9+LF;c2qz9yqYodnDp6TU>g>GFR5FOTX3A z0K@;KbpE6%PLCe?ty)f?FUod#-Z}kunBW^o*M=LW=HMB?OC3*R!FEi8b32nn-OWoP z*cE6&7bC*Adnjydj-RyQHq);n&-VQ6tH@Z6KTld)iRg;G7x^Sx+D_o&#KK;FZ=gnc z4Af5b>mnh6}oljKo-&F;VK~t`k~f7rH_l8Zi(Y*zet7ehx2*n?)K@OY z24?Tk2v0tBuaeRGD9=w32ikOxR}}iSj~;Km_5R%dRiQOj=h+O`hoOrOpWnkfam|wb zDeGgm{+Veyci|!`^s!{m3H;Hwf=CnQWz`l=8_yMB_@qQ@6&=xoGXB`Mt?8B*Ei5e#HTq$t zx!B9>23gH{)uJnvalfC@>Jedz5IaJv3aNWP!1Z4IymC%V4e6jfo`z$4!eIz*@GUD3 zqh$3OroxQ*g}mjDW+bQQ=Pf5NK&3@j{e$UKZv!e0dPk!B39}{qze3L{UpNKJ>S5F_ zeLP$(#d=L7IaWC99rZkQ?Ff9u?G63t-IFi;4KbrAqtqklZ?A4a|9sfFz(`$V`wa_b z9Q|qdSY)`PlyZUaO6#U{vYqX!poJ>_xLG;hVM_37Ike_*g2I8Ljq8_;Hsqn?=upy+ zzZ+9r`Xw9S$@fXeq7%TY!9?sniIGb2!}u? zJ<1PzNgaXS9wi%|z0SD!I*)wsZa^$+y~eAd&S@vvreVxoTC&xpA$2W>b!i)R+Or$_ zk8mx&(Q!Oq4;{1jA2d~NqEok+RA2*nl$qL52*#D44Er5KDh=?e^QRd>Bv|!MqzOj0 zH=929nbw|$$B*h-KH*>VgIzny*=DTFFH3Uhm@IqystG14gf7jvZ`5FpY~1YS(H+z{ zj`4RJW5-gbJ0QiXS8oVJf7YwTURn5=H>wC}?Vg?1fz&NX=x6@%ro8`7NXKTmE>BP& z5}y;%%uiOD&+IE5s1b_+g?aZi-}XJxb%99_4p~y4dC{DuQlUgkm5TaG2o|`{f|Yy` z9iywEBY4@xpW8htH4JJM?qwb5W@aLoZ^XxVdk5e$Xm|&S3P zh94bp`(-eiI8XNcNowZ%3&4?tdBL&tplPi5ulgwK6;HJ0H3x#<{V^u7b@pH$lUizEAN3L$Ddp(3W<*Ya5`Gh@}=s{ zc6qz$PXW)N_#R-VM9=p>99}P+(p6bgk9Rm`Q)s(k-0K zLhwjkw933+gDN&)7tzo{jgNGHkIrAo_|2Pz16qj?a{2acTcRLJk~3|iOodHP_2v@w z!%hpQ-q#84EZZtm7?4Xfc=7Icm#JLio}(B3vNuSfu^UrNlNz0`C)`35U5J?WzVqAD z!-EP>jEJ9CdA8ksdupY(S3ba$`@dKDoFEwe0X-R)eI<9=kU#IT#Kpt2w^bzKbYsyP zo_X;i+vsV7lETDM;#X@1Taf**b*FPR$n{m^@3LH^v7zDY#0t`J#G1_fEMe$XJ?n=| zsIDV2p|d-AZ9jKyKkkSTWKKq_9!Y+mPG7~g{rX(EWyTN~ zQO=CrRheSMh!%v<&-!pU9zv4Qs9UAc=z^V88&|Kp^(;{KHQbmo$*V1y=uosU>gM`- zZA_)T>VyAF!SPNPvfp%QjMX>d%OBv+*|w=HUT`tQtueRFhxYgVd_9BPGogrX{_%F$c?x?r z2AU{I%UYa-c`zGhdRw%+g+T(J;AE1kpD;H_!$;}4CF()z-3ubXj-#D_%gfi<$Nx8i z{CdL8n=j8nu>2u$N$H&F-os)ZzTjo=Nk`%rIBnJdZ!hZy?JqDb)okt z$JmaCh=VwAVKz}wV>Gm{oBBwCZ#k9qVU)}fG0(UpH_W&@>L6kA0%z>w4cf;VU1euY z>)K-j8d)th-B6lVUw|`7zD=ym`%Q@t9rpR2)@`H2@|gwyd^t%}Tx*EK$I%@)CqyDz z)Q=maxtg zZWJ)qIIKI-ow*H^tKe98B39etVm>9}oODxfQ(5ll7;c>$Q&5^caEN=(3+h zprWGxT7h8nt*U!zK{B1qIP>{8w|do}{hVvF^@J(phYsJ+Uu3PBL%1Cc`I6IzHK2q! zBRBPj3|3aG^Fd=otLnTqmprt73OSN~t1n52;!|q2JY=s7b+L(mXuC(=^Vn_wSCM-+ zIu`y;5d}fUaomS(Rx99VUS>C8Rx4Zsazw+2l@?d8eaL|cayhh#9^`pBOWNY^(Wk$X zgN~2g$ExRl7x-b~w<6+EN_$+s0AN`deem+um)sY$Cuw>{?Q?^X46@6%96o_Sc;S5B zE2*Y8P79X4jk)eJ{QUZ&O_tLunufRuKXT;uP0ryldPa^T@L}KW8-fZM^Uolz%x#wo zCXc$CDsSn|t}rR#hcgiA1DFnfXu?@yBSZK}RsaWobaHYsz|A`chKGhkL<>5xm9Fu9 zCtrT7&XZ*Y`kZL{C-?tj#|+M5)IXp}8%0h^w$0z1UmNw z_83@Mv}h zA93tT^Dt3fUfloc&uq1QlQneQK(PAyJMn)hT$>$%qEQbq>Gg+hg1uIt&7M>u!?A5D zHekZzDm*Uf;6OF-;}Y&(N+;%37RIicfMC_+GNzG{rwglJ6ZC~=a@yE4g}mmX)lZ6A zpq4srdAmQ)zFYtmsWn8I;7dR2&eGi)lurCn~8hHLdeI?sG&hn4OOV9uO+i{!s-&ox2UJgc%PkNZbeC zDhw8TaXoKX*+{^DRK|Av3S@g6{(iC6L8q{tY&@zpKQg3Yxe}fefo4gYHkVk zuBO%!)P!1&9t^QvY2^8|KeSbMF|2R?!RA1Nz8ICgNxRZ?;-MXiVcKX}^_40jG49r{ zGJ~>9jp5PTct;lx$C`DyBA=BVd|*ZLjxq=hZ@JlO08oPAu9ZUU0?R_m1y&!v?nkX* zo4WFGG?@(CA6tTfCJ5mv^fI|U-3igaw+ z4W!Xc`5VEa?-X)2PY%idbqvnYAcOJhS1L^so-YaK`!0fWl$9=wYB$o_948khS9E5y zB=^;P5U|%HF~>NcQYx{d;DUUxG}ZW#cwHlH~};^}m`(&M)2R9j+Bsi{su;7mAZ z%62pTeI#uR#N31uwbtWB4r6iO60GeylKZwkh%Iz*^1UQMU+3+!qFZCH-ufp4-tb|y zsc}T}K^x0GoPIL?+z3Y|4%+_kf5G531A&&*?oYp;{0$@4-X6jM$RyTxPdoYLuSl$zA6;r&w>vlF6X?Xlmgk?^+jJHR58RJ7`ZW>eoG*^C zFY8F?mz4G=d$ZvCHA4c?DM&Gkr1DJ_KeFKr9JR2%lfariW*RUG?8GWLYDHaDFkwgQ`RBquVT^ zfM>4#`+=KRLASD>uh}{iT>&@Ze}MB|)H7Ng=Q~>CyDWa{UX5 zlnH*FcK7JnBGk8={;{4$Q0a%*wJ8}j2rz0PPT_}CCAG4yaUAx8yJ2t%e!{HJA9bQd zd4wN!wCIQ0lwUI*8XVMlzcR+Di+}x%S89IU?y=(t2AJQ1ePO+OVm0$Y+gF3k0{IyH z?osYlbzF&2Z3^MHD2;vA1I3nm0F;REv&Vbn$9Z?)4RXc$Q{7+cnv_LKvb8(!4K@?` zHAw%VZ!TdRxZC!52`fpsEgmnc>a6wthpl!q`{(lT|`on#b_Iq&R3#q|*wYi3H z$}HG3f}5iSnyM|1ETIu4k~Tvpnw_EQKMNc9mv ze!L9+xp#6E@V$(y;)?$67<7)}{iD*?lGFg>&q&Ke$-{QBAGC$^zu#SQr_b>zo5Urf zh7k?7xflNwiMVnx3(%Xb)JI`_!)RFQszB6Mo&)<;C_Gita-03 zsBVkHd&dCGCd#v}^N$UJt8IqP9sHY$O#`JkAa!@>Npz44PtDXC{<%@SE3mtiBc>Q_ z0G+G6u`(T;JFHut?cb=N%DAj&qIHxD`6E|kDi;Fa+ma?{fs0TR(}%LI6<$Tml+3OF zx8sh+t@$}99;Q#f5$s)Q>Dy!>SFjo0u|v2ho!A*$>@yuqXJZVC7PN#CdwXqz+Wpw!?W;-^^~_`aH; zzX!PRy!4&7aMHouMTpo^PvW_~lyST4rk{LLv=ND-*p!<(cXfc z7M&fbJyrD=P3!fryho5=u|_uLRy5B=u5hq}l{$rQX|>;rQ!P7cr`q1feqEt!@-N1W zd&aeGtyl1wVc^oG{wK)Ffvre3Y?vsasr!N#HZlFs4H8ZZuADjT| zQ|8&<+w!6396~GY+eTP|o*eek^*0NjY9OK^$=UH#h3}u3{ZU4956SKa2aX+Ny}x#> zA;MFq&9nv3z7Uw2_{6Zy-Pw1@LPJ_kyyWOIBL~gADs!YR2B5U{jRJ_Lh5k&Q+(#sF zJHu-Py4H_H=`7OcEM^RxATI{9qH$2_g4?rb43Yg61c@%|+fw>eDG_J7L^XG2+yp9$b*nJhkYGq7h--Ql-B z+__xuPO)#2*j3y7*z5e)tg{T=9=H)5Xt}pzV!@QvV%3u8N4n%LY2P6E z#z^HAPZDpte_?D!N`PML@Bs3=1aRLJu(@cM`i>cEy9{3vK3z z0e}{TYgT89)-=oPk-Ti3UuhU0N3MSLklC`Vjk*5LRmc~bZz9=J_Rgg&=o88dxwr>G ziWFYS`S#v41Qfnay13=b-u?-hsQ=BCJRM%wbF7_$@}gC+RZ!1Qbh78Lu7vdFCKan3 zsdz2Vs#TfAaUUt<(%D9S-1C1aHo85>GX0Ra&(#>gDhR3=C7`#V_KMejU3IU~P8Jmt zFAn;RibW=`f^JzYF`O25eCDo+zS}1`DO_>5kosrHFVW;Lljp-*M3o&p}Dw4}6y)nQKeGT^EN($#9XSnY_OsOj`ruvI@F$app#wIkS{ zJZ^pLaMQeIiz2d%7@|ww>}~;i(0%IlFeNj7FeQQ@%9xXFUVI-?Nw zw)&@qLK9QIiT_mY{0rI`D6-A3p|#bItx>YPR$vU@RL7GOPb!j{$Y;v&$MN4FU|bY1 zGtLwO@B}l#`i7{ljqt@{h_eK=NbP(f9WpcsDIl@|g|IfVdVc#2#EY6HObfz3qZ^>D z-Dq{M5Y#8`GqU#0qP z_O)2z3p1y3%OJufr|%{m&W|LvqAA8qjOaR&FJe)#+?{CmECn&B{j_i-qF8Htc>b+e zeoaq<=!h*=y|6BR184lR^BmoCNW&0?cTgXFz+$(Q!<~eo)dJA9Ahwdh0~u-q85*DB zg&;vqg(4}(6|A8XnICne1ibp0*D?LpCj}x;8d$v+rT~FB+dSuEk>$?^zqY-0U}$MD z0HhK(8YQLbje7I!jnDpX{wMM+FqDl6l6S|^p4Qrv(uwoA=BkX5OgL|-B~#zW=$FC7 z)^qPZ#^B+iowD-uv^1vp;pUExW}3*?IWw1xvqrlH-x3mF8CqNI|u9v}k|hz_04F zQad_av2XX|@ag3q-Vm`Q%apm3?3l30fsJVlDwF%oSKm~*`}Si7;2E3RrtE`H!`1#j zA@;KT=g{ZajMa8FsOLJx=lYkyy7kpd{yNDE93=#Q z&|*uyTxBdCa34W1VVuBemZVw?U7)ea5~(SgAc<20Tnv2Qm7RL5j52ine>|OaSd;Jj z{zY0!X{4m2VKjr$(%oGmBGM&{M!J!Z9t|QX-Q8UR0#ak7bdT6?`u==>2mf3QGEj!TKsF$a*2n%`ot;`)UkW-amPHIWO!RqB`unmHH;`> zGS}+Z%6+3Da?*3?s7Navw%&{~(FDvHvT+g{E{Bv$m%MEcN7%TwA$RPX68}k>&TOi( zkA_hA6FK_k;q6Xp}s5HP&(zx9M54tXvljZ<^M0W9VC}Xediqja5t*<= z(C(w*FBn;jx?c9Ilz1ynSo7$;>?B5A%?@DLtEHT}SmX z_Kg8oXkT>*(P--c=1=W>t1QL(JRMAMB{R3@W8J~z0X5TML)>RkTdGDF=vJ__4;y`vfs(&^r`IwGwI!w^i)F%}@vIi-%>RLw(@>(?bkpTs&45}0B(R@JPo?@7fB z^CSdUm22*jtsc6fzTA8EYTo>_XR}Q2oU;hkdgIH~1?Xn{a_xC#r`_H8@!OfhxQnxv zmIfDtCar7-kHH$^RF1tJ#o{LaGv8Utu%=-w{oFsdbV-RTQfeEzt0gE95MbqPq<@H* zv^%pXRpE5($jCq5d)MF7vi%0Brg%ohg3IgD#cEOa{!+eK?;E=o%jy|F-H6Cd4}Gw3 zJM+l&d>{6vaM9p~U%n;+skqX?FN~L7ixfw#=(ol$32ologKAJjx#Z9&mPqQnNB1&L zoxI4@64mx=R|n6-=%PH3I*OB<8jsf$pEymMf_Wc@yQ)DGjAWVp`~9t9f!5nWj?iBVEAH|K+FOi`Np9K%uFrvy zm0g%>8|W>9^I23GP*Qh%_m#xKZ=3YTI9&vSPkG=Bjyp{<|1I|-3qpFg^(IgD*8^{N z*;5&Nzg&__F<_Eh2x^8MTkq7j@5?s4P5Xi?>Erv+X39ufLu+;Msr{x0TI$9z?iX3>|LqDn5~a(uIoz9>-5~dRec0HqCh?> zi%q*=41(9T7Fr#%j`k2PSkB8X?)*!OY01Qr#pQ_i=#I z_2V^99}>ta)5xUi49pvtePxf|p|ct{qfU}f-hC2vnoUWbw{hIFruU~73jQs9fFK}j zWbaOO#>+{@`k1L+m!R&WF;j4oYu=P42N4f~*Q+|p_X*%z$BD+A@ZkHalquQ@bieNA zJ55cB>`V>d>}+gl8M#EXHSW5-GtMj4FXBO|qA@U2Xz}55(4exr>3g^;plc&NoY31$=4C&p8#6wE zGf}S_?7{SumgJEUAti@2q+1;+k--dE@`AF?`K2Jm(zr1&z|)Pr*Nt>eng4%<+nK6b zg~1&(tn=HfgTZj|wuy)sYBsSvFDDpna_wk;wf3bJg}w!C+S$emVs$7$o5`UFLhg{AcOPWOdf!?(L}Jaw@~6QBV85u z?%l47yxZ;F*~-Xdx6AS@?Sv%d^c|r-<`cw7tc}CKzV?mkt@X+la#bH2!w3 zLy>rq);c>az~h=6*rKz#wl;})#ru5{(MDf$kDoS#S@>MmyOh(WN2p#^HN&cRmNI2- zl>SM9u==|4Vdgs;(4Qr93!ZtIybvpy4atFz?9ZC}IZv}ce-@po<@3?fqPFesdChfV z_jy^%9IW-E=-J_k(=!43vkA%frpC{A$jlrwl*o81DzcIvKm-yHGT6x_|wOC zpQfIHVBK(R!)V5F1fmr^@l=AmUY!vgX z?vyB{|EW~gdEM3x2D&g4Q>dbrH6k_uls4BSZw&&aq*epwvsUPn1#d~1+sZE4&P@a5 zQ;wy@Jg*IHCfjA}QU2p?YOe=gbncQ*>*m{-q~3Q%PiXSe-cDFQEf_hg^io{?p78-8h14dl>d+3T_!6Kwpk z&~$-ZZZ>G{J{>q7wtbL4 z%lhtH4iNL{>XC;Po9|=Z{8Nal#G&FKlSMV=6Zga;9M()=(S1tCbjhI0K0y)gFzB4kij+qmJS;M^@&IK4Y`XVmg$mOM**clD zU=nSIKrJZ31%;`)d{cExm1Fko!!Tq&D)qRthc;$y6AUmK%ww~z2Ly2Bp(eOTMi;}q(X*~THMoGVj^lX}5a-)< z-^lzb`7Yq7ZSb9W+k@__`@;835A2o|YPeG9v*F%5>>dTmgk6(uk?c4CS2Q?`Jw>*O z>r`=yTqk~+awDv?k=>ps>%fUE{%{0Zu!$c{wk*iusGWI!Z(Aa7EA$|^TDL633RgXh z?X=W3eKFwvc31f3#aAyShI3*}u3@^+vHmYRLW~FLP`(ly#{e1dALb&Q*U4&iJ~wwG zYhM($Z$ECXkmI%g>lQu5{4Ql;As4HMzeP2b8;o43r841(qC;I^;`?Ut&Ei;Ubk`Q( zmLC>NWkEs``z*58j(vSbJ9@;*IlLsL3Q5w}hoGu>Yua<~Gg3370&h>lKz^c~EGi=o zDGasFE}MRdv-gb`u@q~T*v09a!;BCoZ<#~r{`;l)ZfrTfp+L*M=1R?zmGCUNNYW^B zVih3)d=Tl=v&a(bp`G{NBA~(-ryM%?9!vhlCtZ#gzAdb3F2wBjW>Z^@TiCj!{BCfu z07Cqzyv!(>1%8r>zp>9EifY|Q=GI$z?MTcou2Vb1>D(BJAc^?G^9-xQuw(T8u8vA$ zdQ7Cz=RKwHyWS-)|LHrWJMOac+|xvX&v)rgfEfW#2ppa%ou_>XnaHYA`m6@ zk`EKrYxUSC)G2v;UI>!1lluh2Y0Na8z2m0|RudkD?H`sSW=&J`)vqAVx&O7|xTrBV zi|0>~6Y^hK^5(Z0Hv5e1JOJcQP$&qq)zyY##8-&=iDnZ$2&r}+&b8baqz!mStt_Tn zxxG@h_ur_90vUz-Ss#=gDg+8$|KL1QiX3kTVS>Cez8E ztw;-o#}LX3Q+TP<2^q%SWe3K)c_r>Yl7WcnS@4=}p#q0GO@+^`@sj+Bf#ktp@t$ij z+tkKRMYYyd#!PRAE&f*yTa4?^d>2%i&XK|(UVGNU4lBXe?jMo9A7q(r$03sgsGWG3 zZ6{AqfiZSoG*50D7-WRiF5GI)zxppQWzR|Yo^GN;Rc(2S{``9x2DSoWC^eWea~^&H z@g)9bPRYzA5Z0XI#N|y_n7vuOE$ntDrQuIz{ioPo0{EtXtc=Y}ljE%Q=4Bz+U32er z8FG0nG7Jy9eV+kenxk1aY%IFW+${f{Rt2~|?|wZ$z2){TW_c~G>`~Mul$+6xCrWhc zKKz!D(r!6p(sA^;qp>>c;RmidZdAOJQk?$|gm5ZblCK#d_acpH6@Q$8GdE+UuG{LfC~A3dN4 z<=yp{t$OS0mKmz`R(8V)Jn1&q7nh|jkB(rP^AIifF2SBs{OucZhm$uSc_WB?Gw#^Y z7R;t6soeK4F7k??izenKJV8ITzBfRe012lTOwrdeA!DE zoV>m5yMjzbFkJrR{Rn?&IO$8>GMuKC*A?fr!9~%-+EF6LdbOD_{_mDV!}mfJdH3@# z!b&n8l_eR!FxduhTiCsm0z$=Wd;knNYh$4jP6Sg~ici(2Fm174G2<-;sjHy*Y7--g z05hLMe1W7?!xnORn7$;)<`ZC+ie>ookC$VEubzrex0f@jXHju+adpf_9x)7;;W@DQ zC$#n4#25>v-N=PTB--q+qc}(!N@uPPB@Lp{OnOeLs;rQPgH&q*eQ%|>QW==M_In6i zyZS`3+DSfxC{+UuEs+bAwb!1tV#wRup|dfeGaQebf}BPqJI`Uf*9jcKi8Z$}4(-K*NDM!xAdg8f3>auh z{-2~9*`A;R2CkkM)c6~^Il6}rD}N%&FQ^m$2@S1*J1$NH@+B$p1E53E$n3Y@@mfHF6TG%lc?Jrus%&2G(zrM}qBceHF2Rfx)FG388mNs|xm^1hVEp2KAQkh4(ibKDcx3nq7IM%LqgeF(8HV zLw}QE*El4jS8_cNBb$MfKMl<)d%QxN{5_B2Ktga(e=sE~(W&49f5KmU5OCD`NWXLq zOk)drCW7k&khTnlWk_!kXR=R?GUJZyi!R8^#ayFs8T5ffMmw4&MtgeCABP{7WjpX^ zi?wgyXcvlw+O`}$P9KR}3@O8XjM9#4gT8^bh>2_@4#zy_^gNA!0S@hhiwIOE(#Ncb z2W_P*ozzCq&Qb;}@L{5BA}8S1F-($6Y5>rr(>Y|w#-q!w9%mBUhm?9{ESx^%Q;TDG z5gUcXE@dO+1dZJ99aXnB?SSCAHfBxi&PR>+hswkKwWaJ!$rg0MT3F~r!a4QY;D1LL zcM>I_)z`=CmpO;)!M1}R)bkSW>>g{4MJZet?C8a>W@fD2v9akXiZw4>5cZ=|(>D1; z#dGO!^59cDSlqU;2(LIqh^6Yyq(}XRTpQPkL)}@8pm${>9&*urbx(6yB-(HMZc|Y3 z)Jp?QWH#oRZTbOa8NCt>>izb2Ur;}v&?yFCrs9fRUy|S0Z37dpp$v1da7y!i#ij%+ zA_Z5-%+bN2UGx5fo7;IU+#0JS|9?3H8>TlE(kNi|ZY=;I_9_!O#yPG#@+}n(2l;De z?WD|9h$as2E*T8+9$WhjFD1(uQK4%D=zIl9w3VVIao$&wv(L@635VYCn`p5;9 z%14tt&PACjY{JXE3|r1cG@d~9@8;HvH7E+0rO2naPs)ns8M zKnhBP8P}Yb>=K@Ngq6gTb;k1~@^Z(0Kr!cI=6*hRx$dW}UkAMf`a1(3k!nNcP#$`3 zFX@3Pg%UgCZl3a91^NDAO}&w05_K`>L7KasCBfxY*sHPDf?GULt_8Vf3+fTfdS zO~H>3>v+rWdt24ue9y97Zl51`W@dcAXLIVIOs3r#A@Kk(k z-sBNWFG^6=#Jx<&WD)i%4s}Y8)u7Crg3Por4u@&HIP3<36jhI%jO?e(POrma-jfy% zr7!e+zE9-qjI*8#<9XGItsa8?5TTtwu(d}7q6<+UlJsX+d*r~5-=P4@t?wdT7knrw zDZ4B~#*hC4Mr{cPZh9C_s^%f3fiJj4ZOD`)C-e zNS2}wZ4ix3g%VN_2F!FGGTu$4=;;d^SQ&)hBKU8;BvShB!-C1Vw=`ECWqFe_=Oh&4 z{F7HM4xK|l;UlU8T~_5k@|YhrF5qu!^Z%W=za!z8Zj||`lA`OLF<;uqL;J(2%ISh5C7GKgejn{{*GT{Q&0yDoIjinfJrHy2HEZ<3$Vn zlLNW9V(8YUTLJ*cTKp3Fm2FyMiSZi}`J71cm!|HKpT?~2(^Gj?^6@{d>6m{#&F>y% z4(UJ{79qQ4B?z}|bx{_skq2*6<2NQ$)yx19k%6`Nb?ne5{SuSDfJm%qU;&i51H8S1 z)uk(cOF|-$wW@IPhU*H*@98Bl`?YW{0cFFq8|{)sSjBOEZzeOoavLiw1wJkm7+sgZ zY!H2hn4D$y5|q zJ3KCjYybB1t^Z=Yu}B4z6MlW^mY8Rsz@-SOWUr$Sd9=(Wq&{>Nwd#OAi1<*v5adSf z0|Rs1yt_(mhfC8JW>sCZZdTrWIS-e(-&oId>Hxx_w1^KP#hLpz561xkhre4r<(G68 zSAYGw)g1VlwYXC!?q}_C9xLtqTY{9I#Tf9?_uHDM@?(p?HpE2C7ugj3WIENggp7f& zdr&$Spy33xt5cp09Y{CN$2R)7To5-%*Gs20w z^A*hSxrO-&EFmnx2C=~cj_qc(@E1Y@v9lNpdS4fmTd-Ge=M-0Lo&P9-xuWxy58I@? z!f4TKyo04@Q7a?gheTdvtTU*v((Khw1F~d3)OV-uyP6elfO@jbAY9#V?#YE5wN1et z8`RsdFM_AVu29NVXZ&pQXF-w9ahb(CY$4^-Ct2d}Q6nkW9<|*l1;0Ex4NvHwISK4^ z^Kt*S@@LD0T2XXSE3VS)D}uKriwiz%b{;S~?7)$W_`=~~6@Q%!kZHZ{_7hiE#KYZn z=SsWJb@qH2cRhw!GF1n=;X}Qz_qHmaTwsT(*6*B0M0I|ZeC9#+%*T-TZpVzq6`27d zyCHx7&Y@i%dnjZcNoT6VmvMljiHP?k8n>YZoK?&mJ#DxN- z{OrSp5+Qez^AyGJqvEBSf@U$ynhGLxp&1^|tDK+rwHjQ2f*L)?3xefWtPWor&R zXme-#gKSm=y=ad%o3ldwvU_`nP<_TB?5;euf`MPsTK#kgvHXo3wwEOao+{lB2239s?6Ho zu2sD3i^N8T!>zybM4&v9x4O=c>2-D#h~4qJ+a!DJjac?)O_17+y46qOq(I;G;}Mb= ze*mr&%Ai{?GU?rD#=Nh*aBb3DPMIx5wg7531DSuqIkwYo@~6zcs2FMc>YtS&VoH)3 zO%5O(6e&f=p}?BW9~C>NcvDY0>;!hwB7x7aAan3sf9JC}W4W}X-Qd*My~Zg;`I1mpE!kd>dY{WIQ1Xdn0Fryml;9B&Cn#~z(T#N@#I{58wfcEsC#7POT`H`#Rgm0f&c$|uFhyW z3+JQYhszg)U!z$LC_V5RaEH8GadP9P_D2;#ZQ5+1eJlI$(eO zQ&KZbK1?eCq>Lj^e26;J-u4bqaopG+G<$x*%BNZKSHIQ+ozt|EVzN9fF@cVG21 z8+B$6_M}MOmO*$H@k2-P-vnP4Kj!Q=DYnND)s=ChN)NuJJ}<^H>eeRct>zi#X~coP zsx++7RG;@k_fsb52)cmGL3Ck%)!*MceGfg!@Bz70NK0!=`Nv>lWn6xhi)L83RAlTE z0+G|XsB@FSs)7_ZHEE1*T83kM6=|LsBVMIa7p7Gk-^Rg38KxL*P@qX6jMrWNX8rQP79-pmP>jaNosV~lR3uLKoy72j9&g2!UGTt!)=Stl*LQ-0zE546{RP0}$Z zbdF#{w74%U6q#6@6aGqW8{yeLdAI1`_AS4|?E#-P!Z}X#55xNx(2~gJr44M5dYkJq zA+z2h|8I?DL6RNT>5`~5?R&^3dHzwIgKeXqfyuT~R?o(8`rX;JyU__z zW8bg>o{TN1&P|+l-%xjdDN%|_?q_t5>B4514Mh;*oBz3JH^aVUH_{i;h8GK*Gx#SfglTHmJcr+=#QV18lM>F(SO5I7uL=C^Ab^ey*=sy zlWVC`&_rd`Jl7~nboixvwdb}%z4J!+DE7{#^NmE2c@MY7vks9}e4vf{l<#&& z>2a7i&IMwA&y$GjM&vDHUZzyZrU9ua73^tTMA6))1srG|3Lo7Kg}N*D!b}`FxH1** zKl1i_boL8A7*CN*Zkk@gXW299uq6lsSKj|E`a_(wLdQ6t_ zus?B|idzPc80pa2oeG53A{Erl{ znrjc)_YRi}yXqvIvwoAeV*2lC;`rL)QpecV0JF{%^XN`n)0U5|+xLj#8}*r@d)3CM zj`^1DNzpr7kTkqXh-~+?&K3()r+Y7`hysiWVYCBQ;pqweQXvb_r+eY z%n#BBjAnI7zfq43kM8hO;$>YVtUm|9AsM^YW7};6GXjjvgWNaj_e(8{f2Iz6yYcYz zXmM&!Vk6tbE%TXi@c13P?~&c>j5+Q6OH*b)ZWU&lDzm;l3)o&Bn{BQq%trdh=hbdJ z5vsORO7(N??h;GO!BI1xe0+7Ad3X1@m|LUe?~_-0g}0f{&kG^^pd2Xm-Z*&rD+V1Y z3T&G<6f;=8b#YMxgOeb_iU?Tzd9WuH!(n%RH3=(YGYHfZR~o5!6+w7{*pGN8$L9ai zBd%|qG2!P z^42Kz6AFBGNYQY$_Q3A3TH}y_E>`7?Q3J>W-*r%#4sr& zBY~*}n=ICv12sH#-}vQRsss?XxzGFA-8677$+i}(o8n)r6vu2V5?h&hMl{XrX+32P zLO#;<8>Z^UDuP^sL94AXc#^UBv<=&$6=C@Y9_cPX+$FQnfawgKsPr}&a8URWp*x@O z@8!i%w0PFe;8&YaIXqcbwT;}ZzPdR47(5c6sDHsw@$@CblrgV=?xYC`L3C8rhjPno zfc=C7lPQjaWVlG#P1XQ~dsaWdm<~=F4`i22nlDCBoUWn9O*Kw(KwArxL9wCG|L;cj?+KYx)_Crv$Ig_kAwjNWEcn!O%J3dGkZ3voo28Q@X?WW>d#B zy(^kPt@VZtE~FKfyLGF0YoF`7ANTkqlwh^aKA9I^ot_Uuv^MloymBNkmU4N$mBl}~ zqdaqyoYq$+i=8LFuJHtc9Hl;Ao3-_++^~^J-$5}OS<}eS&JIb=)D1jcW`Maojc7?2 zxBCfO{;p!azKtOC`g_#YwXszm9&s#>}ah*RsuhuTxAL5SH9x3~8 zw|SI`);4^i*Rm2ZD{=e-pVJ?WKHXg`NGh+5o@e1DFX=YD{51WNq*Hc~AKozT#kG)+ zJ?6y|V2~a`359-*=9i1jk;@i{mxtw*`95@(&I-^@9Osjr-mM2ZWpEjnAO#^v4BAmg z`IMf7zN3qVx%^Pe*JfNL{rLv_k33a$$2Q$*jrX+UvrRl3vGDO6;=xyr`fkmfp)B^` z3?~~)%kIV=sgiB;TvW1KKIi9;xuDcZ0Mp-BILijR$(-{6hU8>7)E{kOOtMxm<$RAX z?%aO<(rbMsW$;xHzZ}VmPFxVW`mYpJdIDPU6{Oi&QO;Pg%2hw1^uK7tI9o&+Bhm*pRuPr7)7iNNhHXVMI9B5#)=$~2WU|Kz#vn$o{X#?#p##$ zP;R1;`ITg1*LFcPN(((uw&SXn<1SnZR~LPtrJuqqOh0{#Y#Vzil8m8@UUiqY^HH84nv8mdg1YgmKP zh^6gcu8Re-ihMm^-|3-wl`Za+SCu_Lj?X}>hQkw4yWUm%oY?E+<8d3d!_z~UXWG#p z1&b*}u=r<}%t%1VFUP%11Ko(tm$HIN&mbP##5dnJS-N@hH{S{C*|I3-2GQ!o*AO(f zREZ@2QXtRq9=R_2$g>nIQCY|>XZ}pFGgS+%=+38KGbA@5H>ZdL2lc)bcp6%amR@i# ziLFaapLnWj?OoQC1hRf)I#y9b}e&WgOe0NSEP=pTntyRF|P#9^Z zG>c`*tBgQ?$48!qp=SAP7i;>mCE&^zc|La9Py^{X+tSuZY#zE$$Z`2rS$&Isypy`; zJP?TSh!x5fA=*&ICh&VLbY>Ovps_0VzAY*ULS%OM*4N%&w!F4{pQA=Iu+mqt2^sJs zCsj`k-8-Y!2s=UPBeA}_b`(T;dzbO~gPZFWN!M1TJdrewXq!&(rUNCojrr4inzl8+ zt_nE4hk(!i=TD7u*U6|cBZb@+@$t%l-KyPym4K9*yK2`i%_lLNO8&!R5`TXVWq z`rnHa_p2m@g8PW;HL_z!o<|&QM}o5I3TbLM!(->a#-R*&UZF<=m}L-;z`x}bQcEYz zCgnKO+ZpukX2)iH!>UY==p?M%0aHidAj{FmKB7CR{-0kyDwiki+ zc^g~Xk?*}6xE}G0o~D!olb_~=baMFvizeLW?4ml8N~p7h-#LChrBLsl(K|2LrCa!{ z9WY9vMv=-_J|NV#esmsB_-u7A)r{4*;yJj017(fh&WNX-S%zw)>N`kiygg+{4g~qO zVXK3SUd0kOrs4PlC1?{Jb;wZgwVu9y>7?ARsA6SgdMcODb+Nfg?>8Bv#)6Q}d5PiN zsdrN^om|WEb_i0*KwW9?7;}8lLllj=4FdnDy5EmtTKf~@JQOxw+$A4V_!Tr39iY?64_<`SQ#G% z$hjSGPIxO*Zmew7qsZ7=rK)V~oAYb|*PwinrSHfBzd|dusY`171`741+gPu`sOwFj zO?+B-8zX1@5Akz(d_7+cUsJmCY*+0HT=<&Zvs!?tXe(Q=Fmau{?GB3imuZH+0+Tq& z*U`oQPR69t(`-N5#v}><`?L=DXSk!|P2ut2$$CeR&pve6if@7+3urOOxn0W^%#C^Q zcoHu0#}DyveX*Q$)GEts`oH6;LzpYU^-uxdx838MQYX&Nn}Nxx7XekGE9dqvP8KOy$C|mR-LFl-HygZi77Ti$$z%A$ zZzu=J2dSky%S@5g%t?WpSzmv3h+s;ImK3Q3SwGaH!iR>Xje81j;7#Zs?V!(mc$*k< z#$-eEt4V! zy{%g1N(o*TAX}6RzjYgM)NU=Uvk8t~iEKev!e*p##Q%>4K_B{}0KP?bClJ zmY)$YQLG-U@>%Ptc^ewJ^C$O$p^2Ym`lGK3+$lWdK7eD@TWC1sUtMGG7w-9Kbz=p# zRQ&kx`~3{Z79b;UB@4qT#+!VR=ker;dVuUp6W>FOpSC8C@g5Hol+1s$cZA)UO~VA$ zGxT?3*+z$Yg<;H`sRdJ_T#sK$VIRTu`)q45&bN+Hyl+In;9 zoPAu{`(?vhL<7HTJ9x^PN=}3)=lJV|>ggv{I?D2ElAU*Sl+`|)9;PM7W(g(yCFtq9 z$Jhku*ds4Yeg}#?yf|QhfO$E>wmecQPE|@SL^omVr-OTvkY`Yxtp;MI0DU@W|5?Qi zfu4gGR|n*uNtjBJU%=2s0DhX;s-kS zJ`a~7ClI#KzpzuPy+Yc8Ii4bsFb7c(Q`3OEtHV_Z#JR-rKP{W@zY6JZ(LBf;BwS_9 z9iognb$#|7twp9MA5~9bO|>(I+5cPljPPV^>zVjlJOn%G2vGs~dwV6J=GO(nW>@Ra zt77?8nC9!5O^;<`nRm^7WvIN#@G0HMf7ID@=7N8#f6av;jT~MHtL~n05y?PF^5MOZ z*|-7G8=LYsLSmd|RZ$C~n}-XZCBE3SZFxM$=Vtf*ko{s$bOO;m;Xx>}2CjGxO0|W> zqaJ7<3%d_;qDnXx^t#wm*Hc{*B&u(D7?}2cz+;z)^u3`DwOO#Gh|!+sm%}qmaIpN9iPNDJPTA9qk zq*K~XD3I055XZ~$v(;v6CHj5-S<_Fb4Vd)Uq%@vBRJOB|Z8*j%H^g#6 zmk3kM3|@|q5464|f3K|;rmk!Lijso&?}ns0&lJ|EOZ)>$j`wLVsq+)snI}D2H1;rV z8dd`8;ON%0TSO90_`lqTVQs@bhYwm?E+&X&XujPot$@AX@neoil{)o+n39ibfx6#% z6IVD_V*wa7N@p8~{D({K=qYVVXwWjj8R9iU5A1X;19@gN=W8X8L2TFZU}-EzV$3_R z_Hdqq7|UYVq5l5`Lm1=wDO*ilneiq-FU|X6ce*Skg~T!5rt(hX;Xx)AC1hpYEM~on zf%8Tc2{LXfxu}67tW$oQ8X3Jk=lZ{^hN=^7ch-hR+}F!c&W38Jy#fq`OPZxfN{pCQ z-uZ|zoLnn4&B`4H#APZ4DFd;da`r^);x#=Qdde5#7vx54v@N+ z#>kTo*I&#&^%Oa$1y_B^M$(SCNu$iDP>Jy0RSgHelXZXs7g_5MYAl56NWBZ6_qyB+ zI8RQ_${Fz-wP2YBj0uf-Re+#%*=d&%_i;E9ZU7bt>eHsgIT42hGyi&jogd=ZIrNxp?W5vSz%%& zin_crb}f4sMbJq56&iedbdZfL=@PYYrw5R`G zYetlgaSAa{iIUhhQ8;A#^1-*v2^am3{+TB+_cJv=b6-#2bI#DpuJ-IZJhF&~7|R?V zVWrH3L6#dEO+j;MO8AJ!9D=0g)Tu+a0lf^o7p$EMtaLBq^t*NY)zRj$aUGP&96qO* zRTDCnqXz>j#^fzif+46zIvMpp-7di^Aty=q+C@Bb%mgw`hm=B&)jV}2nbVE@`oDb6 zwuY~egShK=&za}=4qM)N7N@Ii{}=jSFlk)-x!5=5f&oG*Dz^A45{O#(U1ym%q^$SV z6DZnzUJPX;amk;BvlY@2@AF`M_rv|K!t+@-EnGqWt6Gw~(3k)M5)uL0VMf<;@&#lM zdSOQ9WyjmO_TaZVCySFr@wT;umPf7AJ`E;)OlvoB1q@R9hA{$OVv2H(FEBw_dnR+< zZ_T_X!PJ#`cxw>|Ot$!GfpB8r6I?Fw85eMGmSE*nxJatUhnICh?XU5%csg7Xd=>Zb zVm&Fza}ZFCARF56yHzQb*#`hnv1!$Li*zcTJ4LvuHM}R!3hp;bMP~N9 zcySf_{Twt+t=~~{dbfMtTE5J;8}KW9HTP^V-R4%Lkn83WBIw6QBy*_#}yCv(~sU0LjHK3E%b$rOA>O{q!0GdOA$c1ks0_kx@*jrN!} z%2~!g`|FS`zX6@?dy%c&7O9CfHd_W3A!2n>cjB}LhV|mF#7V_6V z%X-JjgBCUb+Y|^!nez?6{O^9_SmP3gSUu2;2i41BnW6Ut;S2zOpVAxc(9sOqj-PFx zfg3pBZ9}Iyp^mxN%inQn^nNl|?hED~cHYCdll!IY_L2S>#ioHaeiR zey?_ywC?@_1U7g`&-vHV)p`n54ixt_a&v=2!}kL^wQgcB3PV;l4e|Fd&emJkuCo?x z!*hu|#rL?#MgxzL@F06){i}gKV{FQh-0pGbg+fGILHz*rX@EHZgh{kBhaWQ*rDm{a z5Puuviv>%tgQZU@L`xTT3z_1ok`pykI~uyoOBDX{e2OV1D#x-rdAjR2ZRz$QvrLEN zp|9D|W==tE!E1d1aK0=%dZH=4Afc50vT?h1f>wxnPwn%h%k8c)*O_wqkXuaSZu1`i zC>2?E`i)ZL0A{|84z?M*Pxex+=Yq|b?8eS~+Ee*wHk3UykFX{s79f zCzp3~jw`7FdI>a2&{Pjt@Z~6TU8i*WWL`3ib1;cl1cW(+orFy1go* zFktm33^6>_&7U;e|3Dq0$ztTEdbx(qpJ8GKHKpuDy_+zI@F!ysZX4{N8!f_BN~ILljq4}_A<7eW%7c8k zE5=o&wV&>oJhgr9IT7&W*ZmL1uCCAZg2A|Qud^5}6JrMPGTKDr0r(Ng(Y8>OoDe>T zS&yYUJWqI`%y|LN19aRcu>uwy6FnBhnklQI?BDAp9w$hHIc|9<{ILVvFcz;g31bjj z*l4Sq^7`=yuu^$1bwc_elG}CUP+ev>;HBspvHyE$HI$ z@D()p_QQ^ga3ftqv^PDd7>D45)0~)b^ZX1c(OCpFootU&#@yuUHfI0XL}G}12BJ4T zMwc6i-&{BmTu8_$))n+4m9fs5Bna*OE`_5X(s1z+7o7Es5%A+YQ$SuEY~{+JsaEU- zE0i^e?=_15C?9gst0RAz{CF=DPOG%G;CZDE54)+nLAq>zLcA>s3OKHCq7!t{=&*fr zuh@tA6NnA>``~_xL^j5*$yO0?C*@9mFWDZxtaF|eDR&%Yxo`Q6uR6LXUT0EF;7B&X za+xltpRRZU6$uNyVEy#NY!LGlEACXK_hQ77?$Y}I5%t~iRLA@Og@}wo_DJZE>~(PL zki9apg^+pdEg8q&k-b8NV`T4ngzS}htYcOj&M}U0ey8re-{1e|uk-l4-|yG!IdihZ z3$K>-nApX|Jco5(Zxas(mWjYlv8ETHhRu(D-WwG+%*@P`2wFqW%EOy#YStvv^Zvd; zf4SeWcLe*jw=y38u!-sWXn$=xgo|OsdBO%063Ac=V5D;^l}({v1S9M>1UlCYAG@Y* zK0(F`zE&WWu|-s!B2vH5{xn(3Q%XedQA|bBsAzwVgBG)86L+ncg0d%0qT1w zO)YN01NTq=V*Vq}&Z%AXlZ|OYg6U(8A+eSU#-6 zHN_GAXpcm*hkEed{CliIKA>Ep-a{3*>#;jxNFB;~HQ&om*m>zc{BK;U$MJu&h8Del z2hv7@VXLwpWgFd{4@19GiJ6~-g~vp0spk$P(>~|q&0;^l{-wCJ!Lg~MjDs%N)!xBV zL*v+Kt_iMzA(=;SZq8X^!5Iqah_>wm zL~F3$8@(im@5oq@oK2hRjrK?k3v!qYOj`=#)}Du}kCH~vjw9gNJTHAbm5f{P^3I3(9dgLw z7)jTt%{iq4jZa4t;!?t>3d;IkHZ)=BGvfZT&(7+bG*VDwbB<)}c1&5b=V9c8eYlxn zA}?_|${HO|^+#tmcw-o&3bMMNm?92?SC{|<2?NYu?mu8+`3;%9R#jrYwM)8DU1I#c z>lU#F220+ddd)Xp=Lc9BQw<4ED;!V~*!7%4_^&&@a@mRj;L-#{Mc>c zZGYBmO9<0EsSg{vbx%Q?B>mYKD))(34l~~0PK4FWwdJ`^mxH+Z)X~r04GzzL>iWfa zy1qyf;&<1Ec~P6R_k%~+m5l{zpIey4*wHkSmC&29K(!wNIzgcE5B3Rrvnc(3Kj^EbA{Nzhnz^h zek$;_WL@7{&s7PU2q>|jrJENaZZRkbW@x7%P;5e!d9m-syRvt1-n20PsZ9>y90!K8 zzyj_07!N9}wWwO9$@6xOKiMqr;pwkbhFgqapJB0%L6=57s~y3Yr;%PQYoPnpnRhmE zA^+-#J2WuG(^6`t2_NR8$qmkJeZCD~(*5S?wRO^pbyiORw#iL87)b~Q5;KJF4z_ch z-1QAIv(TzDgSYNC`g~w~==v&w%4c>qa}J2$g;?7`5WYwUj9{12h#z@Rt?#SjnJNw5 z&(#-k8{-eB0M`)A4{v6(^*P{a|6Wq_tCPmHU&P?%oO@J-gHE@rsXf$}Ek&wBOHfYh zYKU)J^Kt(}IFkv%4bO%0D1pyz6Vg+>ru8ZgImD5GCP}}n21a4eb)Rx44xHXzwWiGD zc3{mE<|j|8$S;|48G5%=^-lPx#P6H8RLzvV>P%s?OPRdG$Kt%P^SrxRDU`rI9R8V^ ze25>}pWDl;8Ir~1xt|!~sFvo~nYa4^v=tRBTnkmaqxjy9FT^)dO603!(F^$$PbK(K zrC&c+VuE>RVEXaWTOydd-x{g`beoX*=40ZX3LTJFg+9{>;oH+X%v3KQ`&0{LF`Y&@ zb>{4@Sa2a2YF;09xR*6sMMS|8q|?GZ`7yOhC8>-o9CiJQne{L^`QAAp-+SYv6eO|6|fL zpTqfFo4+a$SQ(Wd5wLPw71=C05~6??@t+cZz|0YP8RlQQ`&-Gn3(W^7_C!G^t5ad)$6g&;t-!#k_Em` zPqYG`S1jr)XusUPB$@t8$CD9%k~dT2B32{zQk4@wwu%{egJ<;AlXTRJddi{O%%K{r%9TSH500{Dm7qF zy+b2G4VdWuNUoAA`TDwcOfpF**zD7MzsmM;eVD!^MI_3&z4}E~?;E`NLt1~MNK>zM zu!@Lb>ARLfvR@T%Pn=3yR+6x+SoQQ5_4MNjhPXW(YYAg!@(9y%mOA32y>O>j=(A~$ zQ|{Hrvwww`S^8tkG<(_?Csi$VLo)|g9PwO8;b#4e^N!7HGL*}B&7qBP2s}W!N9vEH z6Mc&eq~vIk_6+EFhFDkcufS&3Pr}3OR(t86+?)Q4Y+ZxJd50}|q(p5-B+lC{Co-%? zvLZETjkiXDg76v!{<5AXrw<7iYe-zpwCG%Bh)}rqlUTjEypZkm1jZ@;^fL`G>1N0b z(+21Gnj=2R6?6Q0I;76)^5SHtf1US3$^W7KW1KZ5g7`L$uf5i|W0r4?fpEg-I#RAj5zqQc>Q0#u ziWW5hRh-n$oo9d{B}=qI^=k0fj>!dS!Xa}X1<+eVX*?znjgC<4O%zH%T%@cpCxl~_ z*il7r>n>vb;9cWJcrLDy@O67dCD@q4y5DHdIQ4g(pZSbB9&5ep1{!c2hqJ&1;aiNj zQ`GOSjd;_!TBy!n2#%lAYZ>C9u{L!xY1y3ba<2mu!8--EyBKB`qZRbovOy9;K?dY4 z;jL=dIT{qC83>~LR%O=W5jn!Ud!k-Y0SwkfZHEV!JVbnRi_l$>N?_$F?#pKgUMy_= zfZK@NLpUewx;;ZUQ+c(CNt53ZGCr&M8L?)o>Mv%%rc9DM#~q$9#Y@5xot75h;_v5_EbX2G;XRl{9}jO&Iff8^#k4RsIbX* zplVS>^&|DnBrkK9)=)Jye6pkkcZjda#!Ee>QtY)BfW~ib7nhSYf4RdV5F5ugr??zM z`Dd4!D`(j>mtc0f0+iEQr9@_Ae-c3!%%}{mZv#y~J+Isf?@5w_Q0tZ5Yadavh*y-z z6b;pq5^;^f?ZLdar4@fTZutkZ(p83393l!(<~Mp8vZ-BAk@BExW?;O_+n(=dO=|)f zG2r7ihv)68{Sc&3jHHQ(*&(=b*1LXR`{ypD!_ah>zQVC7FxW|`iUEE^^PA?!xhQkF zjSP~8%nF8USSu4%yURTNbz~M)e?;neHzB+k!#Q=;b2qGf#`1H{266ly|NNex_qAGj zR8GR}5a66YrUU*oHo7O}wAr#9GoaU|jJk&JzZ!!l8sJ2B|Jj1|@OBLF;K64re{iMp zz-U-@j%IzqmVf?XCWF2}Czlr3%LVzQP{=sXsKu^L|DRk{5ifsSiXhSte&a!61N3eU zu=8@YAbgPI{TTrrF0to$ru~Y?xy4XAg<^PSk0y^{TZlYQyVdbN0C@SD*82rr9%|mC z+?@_ddkj(>9-&=+8-X`1a?lX74y}0D=x!pA$&1CGH9t)!u$3NgVp3nxa)@!=%eXD~c z8S?0wbwq%3BKa1p{$EtCu$%z(vU?Rru+*;d(JV83HWWR#`W)7ShmY*;f!d3LUEt__7p3`#M*m38nA-btZ*GIMefJ4EG*(1drUf24 zTvtFae8%6>a#_aXhadAdA1gKOme3;PZ>24Vdp(`c3Lc@ z_=HgS?$T=N#%;w9F5IE9lNEl0kA9UNN1DWM4D*8Do8Qp^g0Ad!F3D{Y3p|*YhX=U> zFr2Q@rUsbQbR$q+EBYL{88@CUeP9~*LAXt?+lp>5N?aTZmSTwtcUE}BzmI1DW6X2d zS_o4Q`18h4*=xG>`c8}H>&Z>AShLpjZhN-dXGEOol-4wyb)6}f80C;sx1FYAikY** z=u)i1sV0^4my4`NLq(s?UA0SAi{cZ)l7lDc6b^JF;Db9)m!`M#Fm0XH85*N*&o+VQ ze);men_US88BD@vpWQk*1-g%VgkJzK3ZP!mfTlro|lmK;BO4tWf^HT%<;9bBgqnc zJ1(39dyaQ26CI~8M~^;W*Johe{uH{-nLsqGLUhugu;^h5_UZ^eef#p$bQTdi>Ba)^ zYopnxZuvKSja=jRo~DV;NW$EOK-L;<{Y7efpZvWev3(EMivvp&Wzctd|Fhul@`mB( zC96#oczB+i;3`{MUEozTyR?+&+8I`4HR8C*zw zfi{%!UlwabN%$8R0#)uZ1K43-*vp0nUyYH=DqLbq54U_omgsR)a_RfZuh+#${D zUfjvuVkYZK>s6CVZgbve=(Tj;_CIm4R+F=BqP7q!PX<((;5b#Oid%$+WL z*`(+fJaok{ln1A?TRs=flX0BhSMNI~w_z@sa#(NLg-Iq-Ry(%cFj&l6x8G$oe6n#G zlVec9Lv})2W(c|b>)J0 zdLPgn{1RUbx|H`s;7VviDr$*;8mZx`w%W5U8Z6vfJzjbK9ua!<6L+kD8UMpjl{4jX z<1$-X$>%I|WrOrRgUEqct?NJ4GZa`oTz3;-?rs3-KDi-?-teRioJs8traet zGcG2Z!==z^)LTCdMo3Nn?4jArZ&$PW?oL|RWP5;6h0MWMj3I_yNw%(;bqes!vK}g3 z#QEWs39hzoLP-WSz6&vf6#s)1xWYuD2SM3<|;t%5b99i<@S_ z3{zemF1X$mxrL*a`M2763^`y$rt?eMXTWjr6nda_T=7bM7jW5Voes9u!(OW1gs2qF z8a)YLlz3sW%{iw(C%m5t-0k~0W_?FtjjmDn(4Xh0=>Yt*c3@S@q?2@H>*>b8J*$bQ zsMU_mjb{9vR`Of)f4SFxLI*hr0iBA#*VQ*C8k<@zMY&+rO$sMdR9x~RtK6Ht2%fTY znG7>N?xzr^{NNpb^g8cIEWtvry#zjx93CF+iZ6~@D%5^u(`IaM`8a)D@1ECCWfL&I z-*cT&NN!ozc<~7{ij!I9X&nuzbTx%e##QGB&edAgcW~ny{zT1o)pKgj?!(2d-`v{^ z$HG%~C2f3?&gfV1WK}KVh@XH#w=ajq1?o0HVm5O%tB*L%zw5^cAz98NOG>L6>)Y?b z@Z9{rfqTmCC_gw8y_F*FP*nVjy=}8B)Rqt+*X{Dm=%qST?7emJP85NwPWS8lo45fI zK>FQ6K<-OX^Kj{8!^E;h4q^Joaz*F5#-u zMcYy_0#i3WOfXFA#&(r9z5DqXGN@}>@5f03|Ci94 zpSY_rwc%5ZyR!3~(>WU{X%QgPxLT9+l7lZ7Vpor5RIjVrd=KmB6MN8>&y&jC<{uVh z?9A~{YfNBptwBd;^E+j+XVitkw*x%cQT=uJ>f)wxH#J# z7}A%)O<+Q~E9TF;h9@wJN-4oH<5{xZIH5|+SDiD%ojo=CAs*=f|BHkf-c=0rU_crNfbL@)XJF-&aE{CsC)=fl-k*VozGZ-9G+ zEip+;zbB-qcDyO$bv}EVbsC_$v)pc_75d5n+5c+%vr=!t1Flw`wl~hIp>L|`etqpK zDo`-;lE3t$dvJn6G4DnEQ3XVV2@-ltwy^YisK&b!&N7a?0dczj;l!bXJ2!x2yxnBE zdAVYwL#93_9hZA*s%ApYan5@|zk!~raFmXFoN`2iUxoDpSwrJZiRyb@+BX8(B~yGT z4t=qfxS}62R0x_oL;kw{%TET1;|4xF^x#4qrF-T@Y$r{CckYQ~9H>JXl;M=jS7t6W%6k-Lt$YuW_4**%}+td#U_ZuLTRAT;#bbU>%0 za+5*f_h*Fe8yDio@ckVB?xy181nJJ9O%GlffH{szXl0r^(%lzLFwBzo=e^Rk3U_Ea zUWOSm^Ip+dSpIwzFy@5ZY&Vn+KkjDDfEP=+w#a)Av>P(Eo!?p|lATII^0lUHKMLBR zFF+M)25h!iOqJcP923u1++-XNR{vzZO!<{U@@Mj-amUlHM-!e2XzUXL@>^F1j@$P4 zvK8IAtPFzZQsc=DZG&n$Yie}zUp|B`AzJTdv77thglY9h<)|O984B5}?tmFww~^Fv z7NN+>lOw_p?6UtOwt{Xb3#;K5IHjf;?3Q#-Rgp^hME&W@?h}pO`CH)K^ajAek&{qB zHxPgDCs9Zu{fqz7ue%xVc9!$5OT7XzPZJ&q3?Kh~yIikafV*K`M{*M$Ggmip*vO5Z)|@IGT3SzWSQcD6=ey7o6a`d--d;l^n^*J1K))( zfK79$rbVk^Y$Cz###Dm&f{jJ|!9_<6b5@4~{Ne+ej#b`D2mI$9P?4zUqol;9%35l2 z4`{_b!0|GXJzWP4*}S0E0*y2dzZCuaOV^M2dDCp7F49y)hSqq+aHM6s3s!NWI#?Hc zbh%cKGwjw{97j!hcaBK>(r<(=)jtMJ#T~uqilnkm3{|kaPIi3#1J?5b)XjaGKBKat zf0c;gh>wp8gAPBJOq^E9Y-!)s>Fj^_&on~#0_V>qybJjD7vcP6UHJ|fMOe~soe<}} zeqo|l+2;SVO;<$T=0*4WbmOy+Ts0rLm(TF_=8#i3Nz(?0yRrK z*yN_B;LX%YYQqFXhqo_{Oj9G}dn$MSjA=|CahU!a=;L@3*7#t90v?JCSr9!8(^M zqEY(ADBl@K-QN3SozzLdc953B3*SE+0;T#L!a<&T{TTo~^mXC){*#U)%_$>|;;uqB z9Jzcx#d*|%9aBNT58^wqMo07zFhkUcH5ch>I}I+#7mu}n$mVzNPYYKrozQ_Q0{#zA zw#w#d8AilyXWBTrpjV><0|VZ;#`aT12r~F^vP2~_eNdkv(jM(k`+?6>B44`$ya~HQ zPoxj=7b(DvqZ9o}i>Hdug;M@2*DB~Bpu6X@y}jMI+7;UM#d|ju#_7s2xO-a>NPb<1 z69!M!crtpp$AG6Bak<1j@m;zH{<(PF@unvU_8-xs1_c8sxt*RYx4 zJMzrhu)d#k$=2P2BlIA2thK1*WXUpV`G$&zT?f02F@;MsfBXjBrg0!Ik2y>T2Sfsu z0qu3~S@If>NT{7E&3IJr;s($i4ZK<`W7A$KmN;@x{dMR@5C(ACTFd!UKlFJ)sA|#W zv;<<3b#fkdOoTWcIsE>af%)Y>zym^XUignfxaRDB)bOb%Mw2AJzUL=FAC=Y*XCCdI z9y;&)547UXs;d$lO*ToVykC_siK4?i5_} zN?V9jT(kT#YWoX+ClXdQju;O(FKs&HI+oR1sCU3u1dl#E3=+26GyrS0S>ICGsehET zP9y%Lw!29;cTeKwT+bWFh}%t!=p2F0y$3Xkz{t#*g5nohcHx;MV&dW#op7FEM@0oK zWUbs<#ACb7ho>oJby1R=zHB~-dH3@{V1jp`1e<>AKsao5Z27W$k3u7~?>MuqrBI~R;#hkl&vf2`oS z@w`O*HW(@Rd6kbPDK2xfFfd(=DUx+QkeVUn5Yzqn=(Sew_I;-`JGAr<^PkSv?Q}AZ_5yk5Z>A zkM~{%j^|=paTyHl4hbp$(Mtav$<^@COiR~0O3Xej?V-)pbh4kB0%S?+j&`L6y}k29 znNRK`-z|i@v6IaSkC=qkboM0218rdGbBwsUlow#HF}P!8b2$hl_^F!vnah2%p}LS* zR9M13Nzt`Jim#ktlE_76xR`+~W{VZMahP>QR8`cx`+i;x>h$9>^4K*NZu#{314z=) zf}NpEh0=uI=wz-!NBa}sqWMw2ZPJ}l&_(DDii1arJp0H#fAj!6YlDe^_IXP&gH4c~ zekB>wBrAsI55)L>gGUBhFJT9*FPd(|qh`I>b8jB@y~Y4gDiObY!E4A?O!;8!w;la_ zt%q!xhNS5^})dOo$RUSfrF zel?;z9rz^SVHCzFK0zYkMX0*vNSUCrL$26WGu5+hZi!j}1J@Y+>)hSkhXtN*??t^e z>X#j6XP`%bq79CY+7?MI=eNbNWe+ExGXDN9AENFpM}-gC>e=o$n2o6;UMN*3&Ltu~ zB3rY!73n3GBvlZM-82N|*8&nLX*kROF2wd~c&L+$K2UxrvBz(zZSsw^HEc=9C)l^g z9_pI{%7;9?)+LdOL?C~)TqLU^-W(5IFIbU@%?5*O?j^oavuTRLG*HBb4`L`6r?vAz zEtN~Fd{bRRCrp8Rn=kYIwdoH<2e}Br#REam8TMrtG-QGvA%3cgZy@u(K_i!ySm0D3 z@tHMgx!_KM0(l6S&QE2NMjJTl5QOC2C9>JNc%a)T@(&r*(7;0#A<6{<&hci**9Ap-O5-XG&kAX~n>W3MN;wswmGW^32+ zIEa&Cnd=}eTw(M1OW8}0c$dm9zZK%Vr{f(SLwMuwER%nXw5nauajZ_Xk}^-VFZN+K z>b*x_H#5LD)sw++^#M@PXUm zdi4FLae~GPl5)ydiae0u?7sKleJ14-;E5@|PkPuvqcbu6k?zkhS_CfkDn$%D@>j0$ z#!rl64I5m5O#-jCN6J2f^CtR5HS9_piYT0ijennK>qKh`_~)k$a($)C;vOSYJs{CF zdzVD{&R%8V8G`XC%$|hZoHI`9IlTM6a{gneql7HA#4g1>^7hzF`be&KuC=w#LNB*R zb8^(x)j>qVXB|a%dWw%$@46XXIE$2|%fIU3rf-s;O!KXmZzz7&Lzg%$<;+ksG^!8@ zF5)t!PTca+XTlb6ONTWUpL#OxnU*5C?2R9-^O1xoqFpLFO>sJ!wki~-bRG;l&$xjM z)hF50J_y}x$01_nytmKT@`A4ZMlPUE#$|2%Vtdg%!R*WN{+7tVV-#5s03=$xRv22* z6)BJQ3T8LAd;FV^$&Y@kb^p_kW)YjaOP1C#c3(`w`8srEwG%y8 zZ^p7H$UhYaKDiGji(~UjpgM5R1%WojizqhI(U7SKx^m&BjpW;&sT3rZ#HS`U0!@H+ z9eDlI>#aJg91uSMXd`(N&O7Sctm>m#LjlqU05?TX7?x4K@L=CPT;8A2Of?dx7}dc@ zVCt9N3)=U-a5dQsafD25CtOTLtySPC_ti;I?1ieAt0{Lm>B!?o=?#0(zmFZKhfE@9 z6qV_i`dR;3FoIDf=G%k8-&^rEEVScE&+AJ6Ew^ia90KU0^}Z3IsJ1WR-JSu=n^4T+ z<#E$2y!b#-J66}j{1Wgkm|%R*DQJps^P&?>3Rrnsy+6VbjwV;O9XUp1027FEO!};b zzy>!($6YjSaIVUwTQ2kZ5K-B+IVj8#sY>s_*fhf)@>5)ac7$v-ZX=CWC4=Kcv?@gm zS2Z`@Gh7@uhuKR!nkZe>rFU(T5{TAk2-sdhxAEB}{L(0K>oN9)3#klv=1oYbnYNwR zkUr6+5YadU`u%>}=h!{2Z>p`>Y3}WF4Q&nag;j^bKTR&(7b@R=AO708vXjXCL7)|A zJ)VUzPmI?59Hw)c+iZ~Nftb@8kZ@3C9Yj1x7k5$mrydCBz^%67pVIuf!}=(>!fCZH z9KYS>d=TZ1qtP9l-}oKf9>*{2>q}qc9#*2=dw!0Cb|o*@aB$w|i+cV>37DqT#{DxG zHKPiS+a+hOqAOoXbGYPi_&86hk|}pppqGu}zyi|B!~^ch^6EAvdGQj7X=j0`R#SIq zQg=uMKk4~448{Omt^4E>-H1QdWkaFWku$w9HFUm8x{X^U5zSA>9TlD+&+Z}&XUBzV zcYK=f^jLoP>>GCSqa}yAmj`=L-aL5Rq*Ekv5nIp1xEW8xm5?m$=h{`=!Bi)A|Cz_? zSMtS#_k^X>qCLZVYy-G563iJ#wQp}1M|iK&$}`1lRNAVoQ9aNdym^GGwY||KW-1`K zx~y~pqORKm(6Nm4{;L~_y>6(b(9d}1L>R-}%X5}JR<4~o^0xi^Z^7ml=I+zp{!`}7 zurGbO$b;j)sbGJRRiFzUtj~YE$(fg^Jn10R4FgS@r~w~%`9o5C;#Dw$EMQnnn*}5# z$~q!(@QN-8GynwhjkhKyP`k>@?R~!rKX1e^Q71W*g5!9#3+j4~)2=+%pE)qy==v=> zy)q$C$ww|9&?r$Xvo!I17qr;a@zTQLSffnTFG-?1ek{!4&5W_*Lp6#1l%8euF3TD` zTV8^8$fLnrM^*Gm|9*yRR!#s0#r-?(*xekDwVOAbfj0O5;2Rl^8t;R-s!YlAk+2Gi zW4c~xopT)F*6)Bs{_m*q&1a-;dLm-yrnr}UAHbMM^Hv8WM@}H78A0v_~(ik|J=6qj3hNjEus;%xq^bnnx8D8!u z-^@QgU5Jm`m}ZiwZ*X+uc^+IRG;HHouq!n99$oxvP%jm;q9c=yBEbCY(;nIp<2bVb zsqU9xq+B}_91{G*U)72BS)X;En(QHR0-+$icK^!)c*2ONuPVNGe5hJcAir*$zoHxc zn6g9y$M;f?@oaN5oW=0J?TZ}Ec>SV084P47=6+>n-nFj8@)bXlo6wI-6%48x&W-Un zUE7fOY~WfzB@-3YCKN^040OLYdhNxt8$SIsv*sVJnM`@Ez~TN^h06SOar2gd=G4c= z%G$&Io7P;gyLpaxd~hEuo&Wjch4_Cz7XTBdOSEH*y!>`WCU>Nh2Op6K!#FH^qE7;G z8kkG8UQ|Ow@+5guh9SAYKr!RGEJm0sdRBRwIP!5}no%{tEedpWm&} zm-gA5)T{`(v}h~RGp+Xa50FsTv(>pUwz(Jj0p^<<`}Kgr_4}ZMPbr_NG4_Rt*Y9hGf!}mdA#?uR!d| zxCn#WoD?m_J4Nxy(ZBJR4G2M-@7cvKCeeGPFN*MP|S2N$$g*E;gx zGK3fD&{9@Gf#ocjkdz*%=(D_`bFvLJL_wuzhH8kA9ppNNQ{10-k=UDRL&54l^3$c! z+(q)c8*Ajw3Fu@3QWaRM}i#k)zYEaDOW=6qa^ zmK1UP4AIR9u68Ig^m;xtZ;H%rex^xAw_y0UJND6+YYVW|?!(FJR|R2m=8&C3tu#o* zG|W?WrI-8885UPK<1xV#Ww!wl#bLX*WqEGQHg7q75=9QLuf(a16OZvKGih+Nf0{U; zn)YnATmf9+i6<^?cp1^}NIjQ`%g@2r*tLPHLa|?ft+uGTI1`>Kby<_eucv0|`ShF8 zr&$xx2>u2z~|-6{OD* zg!OdMb#M*$*3iMYUFqxsCh@?%P|=<&_lK%{oD-&amj&tz9K3Ldn$Xy{lz?3EKJ=R! z1>3rD4pt=s0J}udAg`0NKnZDf>f?MeYu6Ww3m&TXBFTZwp_bBD3N<$J=y=| zk(OZbyVs!B3SivRe1VVCX{o{ic<&?uyal?8$<5qhs%qVyVaHW_O(CW?`5}jvUs9`4 zE))Fjl39nvH_Cva!5xjbo5CdLZi$Lu71kTs9qgpzNeJIoMM$rcxU8w}oY%gjfY&As zFn)cN>qa3MXK_1mzAzmSpPhH7i?!zyLH%(R(w?mPkbAt6o0GGYA)mVgsA^c(x%dl_ zUJ*WLtvGX;HKNX)fxxk0?ziwv5bojmW=|Qlol)IHAntK^P2Y7f1kd3kU|J?3Ip)8Q z4^W)as{Lo0{PO8H`|;D&cK>fh$WQV7LM+|5(t&EaQQ~o%!IlSFV*lCQnGEo7@*vi7 z7TFL`Rp*CbGE`L4Y}2s@plJX(!{v@yQ9Z2S8=t zV=Ay;Ktq~0$%&xlr@QK7XJI;V?7SmcCp^kdrS?}h*PWFi_e)$YcT6>y97D4`2~z5K zY-z!%6MaLh0#6EoT(=96-};n`H|zn76r$_l9jfMD@xH6S@DG8@_?!2}`5~ed7p_qQ zK-_0!o^EY{=nERz7KVw63xL86naL+3jsdW*3HWiI?ad_n`I#7xy z9YtcpT?f~zBf0B#!F}w%xL4wrC-q@a>M;~1#JYeLUQ9K6K-Ih zWwJ=D`MT`BFIJsfxXU0~p6lWVnFBwZB0r+*@O*^?1omAxGxLss^fz)_tZ=H zSGho_0q>PyBxHTog{bR}F!Q_{Q(qFhmw6fUbjcj+NVWx!NPZuK{Y*dtym+2=ZllNR zpgp`ELpJvo0mDZ>T;78H{K1RI^>E1Mgg|K%{_yzazCKzoRJVnK!KmdG&dT*n8E-pH zFdMijX&ukwKS9)EI$AJIuKsG&(?`U<`)Eu=;z@g3P0hQyG)%mrF?Ac#JQxy1PC|i}@Wd+8ZF~;~S#|Ni3H)YpFABsQp9NmOP)F zaS~QVtTrl7VdIE1%H3^7_FD6L+!L+ocE?f&!~!hh=e?A;yk>w6ZSmj30@iN~5Cs*i zf!yO&W4posXb$PWJhk+l4-VX6kHYGVC#?G4*-$)NLB1$79#mgN86k#Vl3meF-Y0s) z{#?6XCWm+u8O`&hj3AcaoaLij$;)-qTD=nVXgVI%d0*4cVGV`E$&2WeoNe^4c%l2#6dvSt$JrM*N}zY}k;UROi`}?pSJqGiTz2s5 zNFJpW{~lf7S00-YT)%*romtb9Qu;VRx~}sYduA_%x2g}F?3k*SQc6j)Kd!>{1Ee1( zUuz^N(=k(v@z;!Bo^WGihX)=<=!Ols<--GSwmBob0DQMYd^bK6CagkCj4n`X~~a{ zPV!I;w_3_3D*P4i&CI2CxY`k@D?W`xjYIRT@BkZGK0LqT=AY*L-{K&|dEYyS1wiLX z*Hl(N=bT_^S;kRk@DEe6>ZO#^1|)T+;Ro-MP0o8r<&xEzm0Vhu1Lzf&P|WG?0lR5IMqbep(Y+uInr{IZ}=W-bF$@|v!^ zGrIF@yG~)qUFHvGO)CV$wTFmnkZX&XuEc4??q>66$d2J=`-+{g2JVzea&*5d_=mG9 z;xTv`lRCeBWCQMY!6$VF-F*WV0&{i4$m$N@(%wQBSe!Nh;`cX6>%(}W8}(xqx1plpYTR60>DZ}GL$ zQlO6ayuJ@yeP3exr1~VedUsOXJTs`JVc&_{V%V`@VPQek<>jT=WXjiB)vG*Fi6L9v ze0@3D7lgU}SCJrq2z{sk^>$QBd%zg#N2O9bb%cha9Z1Z>IeNSkF`M}OUAp&T2 zFG80F;!adPDBgqDx9;!1Z)3WCw?ov;#P1}6rUeQ1G)J#90z56bZb~+mW#SZ$!#A9- z+UJ3>b;!Iab#d2a<4k#m&CdtAUa!YI-ks)?<5}Hr;$^pTwX&)+jNkfR@z(1S*8pFE zkH7X?Iv6wK7inPt^H!=sh7I`j5BdF91(qvIEbzoHL^D?~Lhp+7NlFIn_c&&i)&?-8{M#m+;!Gm+eXXx`mVGnF&!;2GkN) zaeY)re&3v?i-}|VO%~sA57b0!1(RNLpW?Sai5S}}?e*PPG_tjg@A+egHi{>%8nN6B z_cwfKPD3PN`2`zLQEw^n&gZ{_FK)ajFQnw0VitPOViT>Zol1kwI+O8M$u(@@TWwv7%qI*W-57S{COeJQ0yC0AXV~bj>D;X* zdVOc%@AaW0IPDc8e#e8nZMT49xm~k(%(_0YWTkJva_ONzU4ye`#fPZvLRI@pIKniD zuKL4{hxe|K`4LW?Q*`*+g36iZEDBlWe$Q0!85w~_ng9%6O_&4@BP!C8N=j~*ED(V= zzdsIoE5ZC_NSY8#+we%>Ceg}lp^I<%cq{A3_aW_f1G!@0Ekc^!OUFT3Tq>OtgJ{{h zXvcBjecA867Hs0i!6oMg2@gh&X<4KL>MyS@JbmtKl$5P#IECjNTpKm$^!n8-XLI*2 z#bU)L?L7-ZYIB7QvQ6u^OAi-xg6XJSuovT@jq+xr-*hODdOJz|fPUPg@`Nj_L(2D$ zSqAufLrY5wPH2BaaorhO(z$MWeHvN;B&_eeod)OYnm=buL=xADCeNsb2-gM=npf`) zNbv{@A!aW-1uf znm6~Za7aW0E^R+f2I!X_`Qss768)JDQ{4-zKiwu|ip>T+I*(-ZG1Vkk^I#HXaD@WG53kvf6o+CYB!FP5HINy%@p98ZVfm6!j^S6(-I+gE)jlp|E7 zdG~SKX{L%J8s@P-0NQ`&^>4UQ;We(P9GLI* zwIC&$jP|QK*Bx%$C41ijHEjDEL}H3Y4S2rVuP0K*#%jGaxXGIW1!GJ?UbO-&p00U> zOQ1C)P~~*HdH|6LC-4IbLa-aP$44rgR^R=!p}w|+{{*=bsunu+3Vqht{_8uu49_NH zJNi*vQyYrwMTfX--^q0d_r(+2GHt?T=o??|2AYm!~5eILDSju$okC{QQI*N z&UZhi6aF7tZy6Qk*S>$#h?Mlu3erf!3@suc4bojAAUSj+(k%j#(jn44z|bk(IZ{I- z(l8A5AHR1zzqOwG&Ai~nti_&v?d#mXI9=ZHL$UtQS5*kfzVBH!)8t)r z{P{$fk7*LL0~pAACu88Q7>$qMP4erCv6Nqx+>;96aX$>7b%x43bBsB3gVife>wz&D z*`%EZS5sCK`NwBfMY}X7V&RwWt+2~BzblYxZ(ZpT#c9xHGtg}E)_(&X(N7eCy}P1kWR(N(*hdlDW7ryKKou{SMFvERuev9BE>rOdkEIM z01=Y*C%HHIak&fxrd^8JofNt+^HM zyWh`|y0(yURt7s)_{RnIT$%w$xni`GZh$oJ+uWdCoKX`P0VvPlXy@qv{Y<)cD(wd^vN(Nw4PgiMsy zMig_$orMBvZ7R`AdNmlERlhVKq|F&K+aJ--X1p?eFwhDr^n2RK`(|hKY*ge+agHS4 zgbwt)=dq6y#U17N%c{NpN!1H*E3aAm^M4F<6IvJ*ihASuQC~?xtE3YzH-qCe&UVJw zZY9We=$`aUd1FAMaf6TNv5QZv|(+u8>$5xPhu z@ux5CorNu|J{!~L!Zww$T4B$ z*BT|hM+bhs&zAtbC)#{Xe1?jAwkJocE-^0x=R;17tdX6!ZI@k=oMY7@Gf(fNB!qos?Gwy~9&~L{A`p9!f*nD<#DiWv#NzHlTl|k<*PjtX}g4==||TCeINfHI4YRhl3dayq#yV6L-yzqdhlK3$)hf? z-=HUbX!*51u~VdUtXiWr!A{Q%Ri$zBr*+!#qLsHs?QaJkHY(3mcb$2;&MlOuLj%h* zh2s5t@XbS|Lx!3IgqvloKfrWp0*#1TJiaMZl<5#x^Dr>ogJLz0-nneYdv2M^=wjN&c zb`j(G@-8&!nfgO?BL7{=g}HdNl}dzE%qfDP_-z(z`aM+3864_Hq@`=Y@qttvNa4L3=w@IZM?dmfj)^$tCM9)o* z{sXatQ)|+v*Kfl?A?>( zp*+i+R2KaSe74kT&@q(Nli2MAP0x_~mcmMl3qjREoZaqBy=A+ddsq$k*1o%5GtCMr zlAC2ireLgUx^lqfl`Y6|3yV);^@-1z9;)1Qw*)MkL%8@E)drqeK~6WnBj=1xY2WHP z>@5lqw1DPz%V&z7vWOovaRS1FfNXB==qdI`nF2*K9(>bY| zhiw`M`ZvZTFn4nL{Z5Ynal>Pc`K8-iiOl=X#m#}p&o&$Se80Xz+qL||Efo9FVEIwt z&hgV8f(=WPS15Qih#pVE=k%TY>Ik8vVvtV9desH(eOTal0=d)^g{;@x2Jy-_u#;c2 zt3@5@0m-C*?IQ~FSX2^Ff7QC$ya$aMsNA7f@`Jwy?TB&=BZ|e);4RQ@*I#epA?lLL zcwn0nb3MTqFKg~evh7Op{x9;6>I|pPq!NGNoQ|f-Srp#X4Yr-JwiG+Hg;=PGJDgah z4Sz<>L(f~N)|JJs3kQ}lxCo7;uxa2?-%#HGmH|d5fE;O^Ic1-0xw}kcyea`4Yjp;p zFQSmV@-8qB?4z@Oipro!vw9h{0OCkq8FS2!izjOt1&{9f?}+}=S**TQOg+d?J^ptq z5^>7XnHIte|2miFRI{#TllC7osFJx7Zh+|X81zN53dMWP^{UXz1_>NPI){b=vqM*p z?0G`rz+N|)MQ@SBicjB5wcDDGFrGRU_8FV$=^{A}?TXN?Gd4}1E;7!XnEk$hIa`(Gm z*H(SqViN{LDtPbyov-AA+3Qm}D*IEtwcpUoR?I7ZFt zdWn|Yg!b$b7VMp(4lf`t>O-3RN6wae9oZe5x?NDwvEFGY4El2g zaHGuLIpH&j>-^Z+M66tRV<_MM?>)r)H6B4`b?h6SNfeV!0fQ!XA#ze*JNwAWe8Uq1 zhnaPgAl7>Atu1aj!^>|}JyIZ&APuPVw-DQ`*DJXqURz*g@}y6-=5L|Lr9#hwlnT+L zbEHeU1U)=|BF++xU1?a>9&Ge%jZf7#fb&g66~54}+!!ejlNjvE&pah| z^}%;))$=#EZXwT0uK7Oi8Kr8l?E{FTCD!HO7$s~~c3nMMkFv0~8p~?GlVsK8-LIZo zhr70lrJIp!=Z~H_jch>mG!F*TTjGagiL6k>!Fi(%HHnN;-g&EuwfKo&a) zxnPhLaMFc)f*8+f)%LvkcE?Mu=9K^j<fe{pl>KX`ZwMV9X0ShB<=@u@HUnFYhMek-4gS z1w6It&k=-OAVh$Ac1hMEJWridekgi5JzOL5YkS@6*v}S!-35Qyen4aSs6A>rzCTnZW(-M3wiV!JS4<^?MzvJm>wIMGytMaSzlDkq5n^Wk6`*onw;#CvN-RG6*nk=;1otyDCVjWj zFlyO%rH&BJUKb8RC7>O-<5$HL54(p249h`v?+PXo>J7JWwg$9RI z--z*a^`q_o(6ptukW4k=R>dQ#0o{u2D6!Gv-MyZysDK7gCIHieT9vNN{;qyW$w4G^=J5>dZQ#NwqcQ?Okx72y; zYM4Fbq-9?i=FMXR$~$9nAU)AFNpvzf;=9%NL@}dmsOZn8s8Gp7*7P(H-~=PQxr;;I zK`X2=R>FQK*pty0Xj#c7NoG1UvXGq6p3(0|vk|BkPXR4Ddjx+Ly#!T9b?5z0wvM`t z1WKanNE=bKgvxO7!&e&WJbi5VD8P-afl4WOWa{D z^6}myt&^J!kF;CtKG9=8BNwNZ9&gM$?(o3mIA~^NXAVS{!TLsQ$nWsA=v)XL+P&hs zQJ6Y~REYDQ%y4$1d06|Biz1(U@z$dDI`|RoH9YTUi{R-ilSH!t=6DS$@EGu(?GZ&T z@yd6hGEOCNm4dOGtf_!^!apzl;{^oAd)`r;nG{$3Hujux?b*%z^AsutN`vD&G4O5Y2`J#PMW|+KOKw}mU7&|))uU0a_{4MIsrqK~LN2U@L*mNgT(z%kl`}$a zb|7!r_3mFcRisj9W^KR;882$d5ZV}h>}uv}Q_0J?LN6_HyMAnI{XRp_TTfz0%hQWp zPm_GpSSU*Pny$2^-HppV^z)y(luo-_CpHrsM&En2%m?;>VRr4x59l8!@nbNOdD*!u z*=Nu*sGTC$S<|p%hsjqaUww=_wcDDe@-lH-EqCtjoDw-fGr;aMPw=6X2kULw^f84? zcz*^6;ta`NdkU{)iy)e;$(!;CgZ9nqa;7t5C1Fn#z6pLI9RL2s?7?}z{-9L$c)!Iy zOQi&hl?9#hmg>UM?CVY;9kAEpc}y)JL@zl-K{AY+bWcqK zi9PjnAj1io$C!dsTG2gRzJ})+yMnxr2bz9x_~aA4A0AcQ2$Os^=cBygD03U6;j0*^ z3a+|~wunCUFh!91PAT_>^%OmZ3VmsbCcC@(Has+T>dd|4%664hs9p=5#Xg)&@FjLY zJ#fw|g&jrCuXx}8iI&MC{q3hYcl^)%H_2bwgZVKx>UH}SEy@0udGDc1R{pxu_WY?z z|6;X8V&`Ut^GJbq7Fr+VjK1Y@cjUa10t`?!+y_mHP8bfMdXWqye5ZvIBp)D3`-}m0 znfsvdbHSMopJ7NoJ%fiGW!KoC##!N;52M|i6*9CYh}j}28y1)3UiCIvuWreb{vgSt z&<6iX-(ajq%Z3i*C5o8*9b+RZ8d^Cl_S;CWP&4(}_%%`2o>l~yZm#~D(-!S^^~GHm z@wIom9qSDY!$bMRV9yvNc^w<5vwG#%1$1|tSuN_(*Y=gaR>y`%2~j@w+T_pY0?Kjz zhL0Ha#`()5av^(=7v*Zv7735@Y@2xs8k~C>{heHvzb$pfc{yLG&^~6}kA2A0r#coR z_E!_H+_(GrkW5gSpG)fKG~&aJINGYhk0*KNdLE^K5PT7VK@ZV2!A(aEBGVOMrE!@+ zQ6M)R>b5Z_Cnu??s}u3N?4yI5YlX0fLVp4)P0|te&8Gcj3*z?HhnzOxY9;*5lms^E z^EWQ&UYg`Ankhpg>AJHc+ScO_7ws3M7ibl3#W%6VEnGS&N>POntJS9KKsEn2A%aX! zFl>ChGdGO(^z=+xCRkN-W@g!l9g9)OYJj-{A<6uCi>(}j2h#45lslg)ZwBEJ?QO|0 z)uTWCzFrU;YY!Ocgv7gZR~-zB&$xInK;ASFj&JoQ_VYnVc&7vj2WrL+8`ed-XiDO; z526mPYY0(9k+r^o2qTH66Tgo_C1(7tewF96eI4xgI%i8G-=CS4>q2?>g-fm_Y`zBY}QxQR3=>3rJsx#r@1Ns4^{(IjVsp)?zkH2*Z zND+^ZYRljK3+Z^{Ul}vO0OR)SPFFR$vvfJ$7)OAX9TC!G`U?*3-Nz`n{WR!6U=DEb z1Y98vDjwV8k#OfxJ8w@6ys$yvaJ+e#r5SlBkuaUz#Wam&h}psY1iy^QNNx1o_axkr zBK!f&Iw4x`lbxi{=?sJ=Se~){L07x||whc2om_TRc^9o%FM}MWIDVM$A_Z(7a2}RjrG4Kp#JAM9n+C?Cp~Kih zV{e*t&kC81iHc~Xvg^x!j2AfhX z#8j6t8k`|9U;VV$mI}Kh;da@3Xd~WdAKEX9{N%bBqK}l{}N(qwV^9HB!9ry-_~8w4D|B6!DYstzj7_RohEzP`Mc zsdCQrd2A9LCe?0_x;tD~j8lMib^Ek}hxo$Hv=^c0RY0XWK2Q~5{EMRD2SXh2jeyu{ zW=_r(K*pc+*=keLXV=F6O!obEPa?dZYs}piw%YFf*{Gir1;GX~2JC$FZeF@>42TK# zQ|_ABZ@3wtY)r=s(q$er1aJsb%8thU(3ZPKGQtD>~}~zgPyD+kcBT4>$FXRlRF_(L0Njl4kB91 zW+idyw!qcRmm%yDyXNvk*_r8IhowRuyWx}I?7 zvJ>o*Zk0*~OlfW}BTADsC4Q0xywCN1awmf@xfoCsZxmM(hp)*qgeww%sJmw*`gFAH zN%c*!9xtG2ozP-uI9~<7pxzNQKvG{iaw{@RJ?|0EfjbTfhtuM2N4HxMY&bo!*R;}I zy&OXYh>!n4k(gFLWXVx`m-tqyz4e}ZN9PfEgpM_+kY_Cd%V zyrCmuJ?;pcpF?)bCNb}$a%bih&ZkaK1^CaF`@6e8waIb%fq2rW24+MdRq-4^ zV|v;WE~g%_4{hbaFi0O=bH{gp;?4ViLty@OCH$9jL@W8@MHIsCn+M(;j*Sz_funBk zq1Ql!(D!kQ>l8PDcF8OrEr5>u2MW?o>!$R zb$pHQ51gmp>d+lIq<_d2kU#`g;xflW?(_Hi%~$Av7^M>d0$Feoge3u+)NapL_g-sv zrHVQwRb$hz?73LppGGiiYGx)cDDR!KZ(tR!v&vPdeF2Dq9`E>*|D)}Yg}t|vr)=H5 z?)V7YK4G!6pWwxei?odu7VB0TF19Z_pE}83*Qysv+=zmN&F|5u zK)(r0OJgMq=Y4gBiycQtMtX($C~W?AVv&CXk&#NA>u)hqu!QXRMGq~>OQLM$lBV;A zj^Fo&6VWz-zhGtltmY|z5`i%)4x}3VwaiT38;Gi}Dq5jM*e|;NQ1BrKS;xrG@%5vY zXoe(XXl34go|+Y&+-Z>d(tkj49-pEn@JoQ*&Gyog?M4q9%XR-S9(BN~vG_hV6*LFj zw)BG%SnP4?tm-2%m`i|IE@|@(S#%`aAc4HWH6%in19S>>sV1HJs<&p-A$dac%;r$N z*oEYd{4oBWmbgm5!opa4Wty?xOI@zF(P;}d1iN4Q@d!TuUXuL{l zK?HpW$$Y17JD!PIOuH;B&Ew{vZ#jfe#h{0_J8_!M!1^}UzHD^-h;5E-{^GjN?{8y; z$%{Q~ELtfP6A~7_VMxjOfpGh04f;1PM&lJA0|ha%=Xf%^!NL@_-s4E=}35ZDAPLXGX=N{5hcfN>m zzBGjBo(E?~CH0Q;HOANHMazisG)dzqkl^Y8+JNcA0aYL=;N8pS&su0dikJS z@;5l1=MK39-|1L_aT5fOg}I$cvI8408hEH|@l-+Dk>6Y?Fv0`el;E>pk|K!I>r$f<{}LnRUI|ni}j8S^xjgU zlD>D0D^It9;?~?~7(Mw6X9%}hxE(DoI7o+KeA#$fu!@l2mrGp(CvOcclD;}mh?c(J zixz`k?4y1AFSb+}?ys6Flr8&9F2+(sm3Hs4{@o(}Z&iUZAkpKgNCw^_y8HY4W6v|h zr%Wo96PnpB-@so7d#D}Is2Y3C3U{@Z_s6uzYtdiqe&_?J`7Y6(H0IjqgulzNYoo9N z&G8>S#!&~CkD3zz3j}u4-#aMuDSWap23S}vUBt)f^?bfErEMvi{}ja^%hggcb@L_Q zr2hHh>O}Al+#fw@N7<+dJA9x7$KHGGGm9YGvY)nsw5uN#3Y4q7kV z2bH_hHs-KByQ!P&&wZ#kxH)x9w~yqQ7ZVh*VCy`@WtoH2y|CKbcqwBI=&G^lg|3~1 z1N<4Wtd0A7=;FOa7KpV*Kp<}CS3m!OPRba!V{!zOu;i*{SnB6SJ@P8b%C+e39_3&l z>5;qd~6wgS|7HSw6_wQ@3FPKKj&xrn-ze9iRe!U z1}2!4L&?5=?4Szb5@MVd7Qc70^r7+(&3u<3!tc3NI8r{v-ENNMb=Mz9dw}e}YLJPy z_mAy>yd~rn0DSa8fBlm*SCHVLC)QEeEQIM?gP1L3mx_&Bas1(Q znAh(wC-YKW`tG%KINrIJ629&rx?vUrCr>lQ(e7euK9=M?IkRQocETyDG)+qWxGLHH z4If2X%$&W7rRs|?e6og&bJn@{itd;TS!dTPI$gnVHfB+7xxZ(Zc78Ur3B8cKxyi$7 zS;5`E9R-;L3I@F?Zs=WoR%3_$8@gjgP|rVPsx{(23fu9a0c>+_i%GOw%-kD~<9As; zy^7h`z;p8S^t5nvbkuW`bX#0W;nMS5ZS%vG@;{3u&5zBe%axOsNDyaSj)u(q^Wyq@ z!}>ob=UWU-46T;YSIVhW%_JLn46#G)y2WdcGm>v^E z5M5@TIv3^CWP2;}+w%jyNWLBETFLZv!3b{e#f;OuD3J2rrq!S7e3^U@v^rt_2&2T={DchA?3c9Qlc(&$e>0<7tIlfx~k z)%ph;sJJ>f<$Mw4xC>1VPZ>8&Zwgl)@fs@M@OW2nl!cd~YH-2V$gaNwweHECkN(Pi zB%xo~InbZy#--O%*Hu?{rj$CY7|%TqD}lILf13&rvG2bQ79jd#aLabNmtYZ%!D?Vc z@`Hl;lt(-!KsEa<1{()@5U`$l+EHSL&tKWYfc8)IRUUpfcELTYr7x@&>`C45~ROK0^*m<;?+-^-o z?Bbe{)Z!fm=ZqiM*~Zpur~L$8**SGqLV+1Nj{;YH29CdeKA~%chPz$!feY~@8MdES zg3aUm;h9yETN$`&DC@Z{@U6z%VXpiX)FZVt zVGQ^qsf(KC{8u^nfA+^%9TudL>_}P);HQivWZ2Nhjm5psZwJ$yc6$@Z*2?XfMy#wC zrfLSt65FR9n^yW!5a6b?Nfo@COl@%=0wbxwimmjP4CjKC{?@!$JmrI;% zzPDdbuuSu*wp(v~zu|9Jz9s9`GKM5=ZK70Hw{G!KwknEoF4LXP?{ibsC4ztd8|J?k zV)-YA`Gr`YKUV(XlCHm=tcWUy@XtP%AK4}f$CFk6Dyu|^WV|6h(|m_TRLgcLo6Si4 z6_)|7wq}+~iTV<$06avi*k1M&Plr~eUF_ELtx7dSO=Q=A38lDpI8{cz{u}&>oo;!($S87XU70 z0VG7=7{CYzlsce(`clP@USG8anuXNjcrFI{pYBBGy_#v z2QI52>Oao4m+P=_m8Ev-2Wk2QX6X(arDntX6|%f9#1B2OMBG2>ogDxYk}iyG?}Ja4BG(t6Gf5IL zz8e1zF!=u*8vYxkFP%G|5*b8Ma#7> z>&WZk2Zaj&AJzzoi0^?!$l!P(?y9*R)>;1H5xt_?BVCCvT&yp2Tyfj})G-Dk*6YTl zAF@2G&f8;f1r+{xo6__WqX}z#V|)$go-2{^qkP~(O>?rNw+l8;E4M$nwx;)U zya-W;%bZ6K@n^lSjBLsb9tI6CP}$p+7g!K9aYI$9dk&4;e1!=&o~NM>3(e>4|g|zeq}9ceM|XOc+q0!rDRgt$s6(B`U4Xx_#>)m zlJI&v_b#*@-yW?w3IgXeRwzw>b$q7Fcg!lhrqU5qk_8Mp zAqScY(=b_Jc9v*@LvTN^Mebp^(+OF@lkyqu=JpnHTK?3ZZ99H(?HN3@Vflti!QV!iRvPkdEfd~4J-`Y2p~ zvD6-U8Q{wA4;4QqN)j(i7Z zNIv-1v{(8i@FQ2>h`$A2R|ka4_r{^}hZqTV7Pi90OBW7-4Zz3}nkK>(7srcw$23-{ zj3Fj}GLw1WYzp>W^!N4KWlI0)@6+LN&zT4=HZ#{g(49Krw*L;OACbiM*=7)74xFyb zJ?|*HWeb=;Q|g#8zET>WLn4u%EGe;+TMLDqDSTTi4hv(UB|0qWpdN`&oFIRS!Ms548Mv<&<^0kc9P>7Vn-ig!sv| z8nl9QMZ;in@oy2#;X|u1XRH`mgQr(Wde-Z~YE8VgB|@j=HP`dhrzJbExBf=h!7S4@ zZLa#H+L2f}i1aw=_fhpNYv+V2Di2OPaU+Lql3ObN;C zz@1-03TO?lmL>rg>HR;rqE7(PJ-ARXQUmfOB3PJ{D5ZV!tZc6KUJHKSjcU#?zyX-8 zOWGcPmnl~jrF%Q2-<%}|l?f+;ZFU^$OXqFodmD7XPeu$jCi(eu!suW8uyr90>cTrRBO!F&TtHN4S-7a<&)G*ZW zefK56y$*DhAt2eY=hy!+K-2A4{x*a{t?sdtY|W3$Vj&x_$7!~CTJKc@Saa#gACOy$ z2Zl%{2<#_=<7C__RUtQM&@g_nHIqU}g)ArmblNe5NyG5XHQHZTfe?A>+sZ%x7Cirv z^#A+9UemystC`^CQ66Z{Z_B6NBim)7JGHK;QUr=WclnIA4Z%QCh!NsufZoI~N9Yty z`b``h^SBs{Q|wvqs==nZ3<>Yp?S*6oJm~`Rh~*y0AI>%iW!r&MCw!4slF5?Ir6_1x zj3IN|b7oSc+x5$PxhvXQV!XctMOoQc@m2)s+RlI&oYRsTTu{I9k~JY6vk6g{Ae&2y zi2b@LF77tpce)!4f>fYzKmVT^o<0C>%_|M?-wk8_1}_$RE%r_v^<{`O77cZmvD73s z>3f7#I&7vZ1{KH-`@Hdysq4Mw^mY`ub#qdrRCs;P+GFK#M(Du5x9lL7>d10B=y1?qR(iDflHvyonSXF%Z#F)dXPjwWsRB-4gf7!aM3_BvBeG#qog7!3E?x$ z_p5=lJR3x-u7dJ~d!8B3R#WA@m5^(%efy>HB$_Cek2adOO9@xc!^424TE^2qQ2l#C z1qSQj(SryYttz`FA72gY%Uz1qB>5^{!aP-VF3(0MPD(ZWV+ThFy7LJ(f4Jg-5VyT z5BPNH%PI6*2C1LiCD^SUnA4@A9(iLeSg28I-{roTEeh%y$BLj~-OgOg9AZ*ibsya+ z+`Y7uZanm)zv=?26w0RC&1{7;3jfL95y|_7MRm}+1au;U4o3#NwWH)ARlyC79bdTk zI9<0TL%6eXSo98%VCtbb7MI7;_(@(W&)S*u0XPl&r@o_Tx$(&bl z`$%JO=J?oGMsL&D(8T0hN(3+vXgqg|tnhCB;Zwscwtv;jB59pPGM=^YYX;LStMga( zw{KfO?7Lf)vpT|!{4vXPv<;23jnmlw(aTiV!`Q_smmaf?J8g0QoH->7;YqoOJD3uT z)=Zz$jHv$eWEg9ThQJIH&{65tylxQ5ogJ-Rjbbr*QTEb`(c6auj!g8fB~t>51SEPF zV@Txb%Ew>DcpyMkL(?kHiP-=(E1 zidNR?yOWyl(|%UE-tstP{DkhEU4$lr8i%c0%u#fpy_M&yDE&c(3n3Lel5AKyyx!+% zc|Pg)bfI^&J8ZQv5a9VF>m(u!xbhTP2@HUfv{uG5t7t79t9m$E*W8KtJH1-_upba7 zt49GwWCrle^>jR0SBO3#ACOq*`j%(kv*nRe*Dmsag7(Y?-3|o7u2X}qQ(?+FS&D&bob0LP6djo*|STIW0ker179xh*P|5FV2WNZ?>7{wUaapwpwX*e ze;lNG;qBjrA4?HEy&uxLg964!9K2nOjhHu}v`LN#3QV%#o_VL@C>FUsuzgPR* z=CJ<~LsU2GzHH(uXu`|s;6`#!kX!X^fOrK1Vi<897A6||E6oPd9b7h)b8z!(lI~2N zKjPCdtfkb)PSZL&LS%C`g^=Kt5H~Zi^Y*yifF{xQKy`l+%sQ5LTHwh}hKq<)G_LLm zY7}~5rnwZiz<7IoyqC+A1o5I~%=vLjjb?8#MZJpN|2~y-H8IL9*3x5pK*muKJlz=) z^Vc+qYSkL$zw4aC)WXNYi9&0z`zd~#nIto8Hc-!*i6$G*ainY)$5>qCe=kri%-q1t zpzAf%gffY`S#yeUw7?pnaaut#_64b%xy09XtiSEwUO%8ZgoRk~N*|9hj^1nRVhTp~ z`~0}_j)GkZsio9J)o80XV=HczE1OJv_v`l^zKM>CYIE5n33Ms~VHDRqo1137+q`>^c2`9`-(0iHr13uNq^!+pske$|TL zVIEPuEZ0@tc^;fl&*a3-___?Qs&quCR5m?Wx}SeT#MH`%N;MH6o)+lf=8*pa3#O}l z5k(HXa3gP*?@HIk%|!BXEDfj*K#c-D0%4b`&cX1B{bW31Qy{SL@SDPSsM}eM^4iAV5tlm@sjN&O6yAICLee|zrhuV+ zc|2vnyf3D&2U>8?Dj!f1=lm=!-YRtf(jVo)??@A{&g`V;`{jIu`A~S$k@H}~F{@>8 z807u|2LB^VwhC_)B?{~nc8)JSGu{>05SX_eGylVpT`8PU$r-0sS1fc!#-^37cZ_vq zya)8nw(nUFV(+LB4ZlwHp$Uj=#vLydM^UGFv$u$rG~9(yF5N<7mgnjYsdDge7swKM zh;Zz>=(~DslZHCga*=D3myA4U%!n8X8U;wi1t}!DL?W-x3&Mj0hz4>P6dZu%sfAi zdXB5*9A}=oF`@b+w(}F7>}cH!C|Qt%w+>#Op9F}??+LX`x`oLbYTr(e-Crh|d zQYv-&TtML!nFQLO9+I^XSC-KFZwPVT^UPSizSKTz~D@z@ME)rwb1dNotLZ=}0l z(8!+gXgEHKNCl1BMKDCSxLBEFX;}FbCn$AFV=Rz!)k;SuyrLg9XzZ6X^pkS?`m@lN zxGnkUcuJ*NcsLdtKXwq&_6fIiF(ge(SW6%r&M8P9Yv<@%r#SwKi~$bX8!VQhg|X9# zplMw8Vm=r>1QB09ab}n7(`iJsva&?9n@nX(E0Ol&_VNn_=oP8pc-$Bwy6|D~lwl(7 zG_I-8-Hllrg;V}-tTdIwAQl&HQp8Ts{Z464ATlbcC2OLs)GG-ajX(#ol!lE4WvN}r zI4TKsQNy%)7hXWR<_A)1rn_D_cNEZEm}UGjr42rH4%6zn=!TM==K1IPe-SFc@$-%>3<$BZ9L)`CBRg zNe&mo@Sy&CqvZcfma}@qt2zD+OJWZZF^wzzM_3U(#0x8y50N-V1~iB*+YpFKm**~V z%0eR!*==44_+USND?EE;hYPI~8Hs>DLSYG(60GaHtjZEB-Cd6#Tu?R?^UrvP6xE=lA75CAY;ejaCx~P73sM?n%)@)XjxtWLQ-5$lp#hD!$*NfJPFmV;e z{iB|19-5hxWP9y~1);O+ot!GWlaL##6NV74dWwLnEP($r5Tyhlh?)z#@0QYr{V_j2jbQs#zQ640zVc3jnP3v6A@UW_TErHRm4hsRly%lS z>)UV|)dF4D0wEk&`ORSN>RNj|qkYyUL*bZmK<9gB4SJVEOc(6ac1|sNp1}AEC5G^f zgtVO|vGCd^xt!@6W9pN*UCXCqS)=keXOw4RddRg&bDax7=jeyCkdIWLSi8kda|;qH z5W%+OLuyhZC)JzDpQiY!QjU+`n;g1Ia+)6T(J9#YmDTGn1r~_9sk(8n`M{xg^cb}< z0X5vp*7yHk8pc2V!+&C~Be3cNy%c?W2=^#2!Cfi5(}B<<6-j@XOSP!q{fYiF=dl{WCc>YU(+Onw?!x|m(k;Z%UeAsoy%el z#a_6!VH{&IK9}#GKVgR^ZGn=Yv7A}nqkpx}*#_bOLKd-oS%j9BxmB|IyZCMv`q>=%%OMhEDX=6MZ2to={`yv9AQL@P=r-*Ns|eL56O#H4s5RFYGm&WC z;{hxk`~b!kgEsoks{=lYAi&IHLUgn^An9a6GNuYC?;3SssGUdG3}`IjlNGEH5>@Qu z(31zntHQr8pHt0eES_Wm_GDp;67pHq@^R(<9ECGns`x&cq6)N;Bqva*-C1<$Y&c^u zSyvB%M1nsJG>9<7Y=rW|mX?-ck1OBsWJUJ!<*sq^?uZ%r8RjlGdmXJ5S60018iaBf zd^&SH1n{7I2YjULN3*EV18eHMHR?b3&w{GFP9G-3ea((;885QG+Ji7A5k&p&Xrd}a zKX50GE}uQq%y93LP5yvm`I{ChzVY_*^${eQR)#$vEQsv%wHf;g{FQd-&Zy9x-WU5EIN<2TR7(jf)sb-$|2VS=hI*>!pZ^i# z*#C-gnuT9M9Kn=$Z}668x1W$1ok--SMG?cX2)5GJ;#FLSa<2IBeBMCC8r_dWWE9^$ zHW^a#|6C%0>aSU)ehhN=y1-0R^fxkbr1LV-V$`67kX9I%6??1Ep0QKd)A;eSw^g(u z319eELwerdJN9k02zCAD6M-_4#%EqIpSRu{^W&YR;m@Xgq7r7i7W*?b_N&$F z3e|OQEGZi{_-+5Vez++>X2rO~+9CX88GBT51Wu)=r)ML?TJ3YL;ppo7ki8)u?aaBo z$&KR-3vk;#(Y71%Iezz%4J6_K^6o{2j0%&d_9>*G2sge9#Y>&l38IuC*T7E(pPyZe zk4ABM{eh*w4cMFh{hPak?6TR@*lMnQKX0q=4a+~W+5fM_*rE7R49m2NAJTm$xiX82 z&ikPj%NQ+Hh$xhubS}L49Z7sHMMP$F)YAjJ(E7o9kT?~wojl+YE6I(-SVh@+G(UMv zXu5O-1JCu``3bJSCI^8l^N5%!p_{gp{hjZEKPqK0eVQhEpxb!gMafUNnI_)E|h%^AN^F{hP?_|Ma> zfJ2=>k(5y_4BE)%Xr+7Sb@8o5Q%>_CL!A40aHn0e)A*e}SX*1`(IUi8(@h7Xyq6lr3<|sRjE0 zC_9M#L!Z%~9jn-K`k9?sNZT(M5^Y^ow6h#v!%H?V0(^-0cyC71Iag=S)W*Y4m65EX z7128law%YzJ^K_Zf(Ue&mI%$ecWvKmg{j+X5-p`*4B+$#Tg2035$h-7FHp*|^`n9C zAyt!fe_3~%Al_0oNoixT`x{wQ1CZdX$%*m@-5S( zPuvGsiL){3P^6mB7t~FXR8sRlr1f(6qKy)3X!$bt^^zNIwrZJdx~%_}P5+g4{-b&} zU|o7lM1++7zRHEW$Z-#!qG{~TMqEVP8+f#Kh zQXt47pYTaK_DbJs%jHkj(Au{^_l9{Lwway@sS0s<%15+4)tR zQX4;wTA1#FgU*!*NDZWUOnWJScZ{|Jj+~2Jh=)lWn0ysp6=7qXr_pucZvCV)C*#a} zt)R?Zh{F@fo{Ojm$5vuh^ARgEB*_@Wscfv(e*x4;0%ntwo^o$-Is+|#$d`1uQ5Axv zf-R?6JTor1=05wQr7V++2r<+&_8np$kF^ut%v~6gc>vJ;5;A@1e$U+LoFwvnzklTN z9u+BKf*PmuT3P-0`+=R*Hq&;Yd_6);@3N-mT)t+zX5$2R9NT+0%Bfb;U{0cbvT9vw z)<4sD2^kZcxLCQFkRmA!;JasM`0|GFDF*ypMpK?6*ebOXbYwz@pRw|*xE8)YQMfG7 zwlI)!rH?DoVW2;=FoSbN*600oai(SZ%jv-qbl?ef0c5rQNw>GZ7935FygE(RIO5H! z$M*0wfEa%@T$y$vgEVJ^ko)B%u%`9l&2`zvT??|uzbnfUQGCgjLN@PI0F$)gC4y+N+qC$X!MTDZ&L1 zS$vl;MA4cwtZ5tl#IF9^Yop7kQetIud)BOirq|cchJXW-ppp~~8j(=*J9V&z)0&Jj zY%IHF8uAC&AWP;v^O86w*WgQl5+mjGSFgfLLNe#HNzCg@yANbRM$p;m!Z!KDwtRdb zlfCnGzDgGQjM!IY9nh%|B;rO#6!q(KL*}k_pK^?)m+32D`FF|*Qb^bR!$B>2Gsy$#y-|@ae5U!zK%qmy3~4 z@o85A6}7iiyNK#XBh`O;b}Y}?qWTBu=ndf|p*1}#Md(j~DI3f!A1(^xJ{xZuZ->(m zD@gPQ+pwK<1dJW0j$*Q_%uda>Liub`^rUdR=yvqC{k9^#c2<`IhBq5O(6L(dpn&RGwt!t>p?30z;xuN{Ux3HIc=N>F~R%8D>bl)t7P z63UEQ8n7B@lifvISB7Z1QOmT9B1Atp)$|N@41N|{pjmtBs9`#qSbaCTk`@~-+HU^v zTwXBb4uE~NEdS|q*?wc-AI|kyS>;Br`sFoFhxwP7B}#FOr}bKGsjSJUtse2sbUlIi z3J)6FBX_o!etGE)OPqycn}|Z*KD+wCsHG}&dn&1q+l>7~U0BcueZ#j43+u?kYb4=}8iJE$pO%lWwbEmp0%lVuP>c+vxQ= zkE9U*2;10KX8g0GwXh*Mc_1t`C8j*q02m`eI!7ZT#?kURCGN_e>N4x0L&b8ts6+{Y z-%TlC#*5p0PN#YZpCmH0cLyiFKw1f~Yq1o%DGu|r-p{1L^l>AAj6hkQ52;<9k8ZT4 z;}zz}o$h@u53*LDV@K0*9RF(`iEk_553EXb!N$-TZA*JK@!?zVoITxUEIm-tzR;zc z6tw*9QV^-d$v}7$da5(2A{b)j@CZ!IB0=0eU00>jSQuKoY?M z{!JlyKNiTu)!fNuW`JxCPKWR)=1|pN^UwfKdH|!atpJgX!h}yti??I7O_y`mecDYq z;Dgr&4A85aKYb_6KKWK~XltoQLP?1zqab_iX7-?S>F-L%F0W9IA@PV!{nkR4s8c=! z7Z%FEc6F%yH7Q4*P@FfZXE{*JOo_@HU!j^y2Uz|6TBVZL1Uk%Dtg76?DBo)iUEa59 z(iZ%PeKN`ti7u|nbWD0J6`XPumvsC-kcqTSiM$%;0XP|E_>#-L%ZiEJw4zqyKdPC# zCMABhPeijl?jUJ4R(u>1S#3FUDr!pkf;V!TZ|?q7q9a1w$-%3VKIe5)PX*zv>WF?< z>xaj0wXFDv*c!DnW#@-2e|@9Qn`RBjLnRM*Q2QhX_YpqxKNsL@i&_1pxF(!P%oHZilh3I}9Xyf@TEd^x#x_O{)7K8>{5| z|6LgW7hLz^zdQLyrxONl_BjnX$(kM2>rKev#)dVIstEW=h$^OHw%hwgtG^N}_7Y>I1*)mrDit~`MrYrfl+=TDHb?DJ5lbA?< z@yvA1%WU&Yun8XdZe6u2-2Rb5k|5z%I1>fHFP`a9M5JXd)5Epjb3D{;&vUWs%3v1m z;8CMDJMuAP>M(G58j3V(>i_c|YV8J57Bro>sN3&Td~>-`!x^mc0j7gM(2*@z*84xi|(?kHxiq$toF$%zo}bD^?RJ=jx{aPWyVYEV8Np~hMsC^ zc2y>A?VQaOyIpp32gdoC$(Rl2k42@AdFBljdxZ+~9`e>Yd?0OOp`VIem5kEF6(bQK zWx=E}HWgP5*D_CAgPqd(UbJy2!U*6c(KInX7^_J6rz18h)*3Tf1d}- z5Vrh``pFS^eB|Hh@;(i7&pmp0)NmJ6#XCs!3h6J3oPc_EDW*-1x%@eNZD(0(=Ym6l z@A416PN;@`(%4ylvBpt+#XYmG{=~r~W;MO!T`UCS=(rz5^4(6|s#+hzdHw|uyv0N( z2wUFq>y#t1JvKewK1%6^gI2oSqiooUybwBUa?GD%3ky^aD^SRuf;VT}QWWr+@K2EC zCxf|T;3HRKa-{9?{`5L>n-VDAp)8e~YM#=YWibbD8SFmWsm97G)`J8Rj57#?sIs3nchc#J8MPmb(Cz=h9(oV zbd6Fmy6tlhBoJYgP!3%30s2h!x9;i-2Rb2es_dJCR*b(v0b89%a9cd__8BV;F_}90 zN7oN>$eJM8-yxa!Y2ek(GDG9Z1!~n!D!ng!PVQH7@P%=L-0N$37o$&QZ;H2dzybV^ zdfV)C37>8;rlkRzE#!rjO?Bp!Ki`ywp^_4|!tCBiBEbZ5clCMSkd1&$uOyVEULEq1h zgMvA}1TdFf0BdYFx>Txk=Zi+pS}WWoGDLsplt3kH|NRVIFN1#Cio9 z)~DU@oYRcYJdE#|7>HRaLstm2ox6Y+3gD6LSI9l8(kRjymS{g@wT>^rc?n6T&(0Rn z)l;dRVoMl#=dmOlMnhs$& z{9=4;*#vJI6mM@RbxI8h{Ya^$_x%#^WmY-PbyWrttdtRS^ z1*>v#Zrqyms7!~oJO?3^<_zUN_yBx10&Aa`zEF{U;ukfBrvmN_mbDT<8_-mn>Q5f1 zmi$qjr7H*QRshY-B4tap5USR(PYHah!P;TBsua~chY$rp8a@3tsHo?X2-5h-FfcSd9=?fu(q zd~GLaiGe%a*Am)-n#(;r4&-Mphh(S1Xw7rBc8eDwx_2UFdGBS%J3mqBIm+-sh4~G* zrGf(YfG=1^qiuOtmZJ1h4!fSvt0*XLR%#jK~>9+mjMp_+*myo+P%E&uSg z1@>wl>$P}&U5eGcJq{!is&2@2iXQ7u`-W7cD##TKYd>Dj!kZLKaa39d9@kCbyRS*x z7$kTE^I)lEp&nkw$<3mH$#8bz@KdF zQ_pzXa?~ZAd*sE&3F3}=3{0i%ci>;f8Vo0!EeBtN%BwUlMuY0c!BJeml-YWz1Un2DkP=W)SX(TtNP_+<+BbA?5=KY{P-#wZ+c?`bem8tctH4;%sDTaH(Xf2IhJ z#-|UBMgh9tlzda-|Fa@ji+7#dVUfCm$2hWH`^X8EbzDTBKDDQOn)(b5!3O}T__~pzzCb6USat!A452Z*;vE0v zJ0x3@(e<${v(Qs5U?yl4;2kd^)~)JxN@1EUq4vBDPr{kgtGb=+;j@9DZ7F}Ui5r^f z+J|U8g!{xq1>_iU=#Y}w&g{SAKk1-!4IgySwWKtY1^Aa?ry?UY2P(8xy8<^I1Sd!gpJ9K#-@1L)-lZr z`LC4}EjWA3g>sBVRtSQ}=*1Q%%i$zP9s*7tmlfW}!vy6UJV(QwR=K}%fqgUPR^I8b z%kWc&YCGAU#?qxN<5gTPI9{t;(n-3@&DQ6QSnn?W(=)5p)K3e1U~%`$XLIofryIWxsbS~9n5<5%dSUnjYtG03uH@d8F*T= ze$B{Va22k9`%Hv7;g)vcq+(i}Kd0^~%n@?3H4+UyS&AfB{Rl!Pl(cop-7HWKMr{4D zHRYXx-Q&5jGjLmgL03~ZB>RRc(cI${mKboN%l}##!YJhBmUZ^6w^`hL4xv$k^mQ^7 z`{ZOle^?n}bgDcHT|Ug?J!>16BBpi*=s%p5#DN2>0dco7zYE)EOXZ6Q-OY z#~zJK9zElSV1b|+u_!vnv=*h5)x+1v;~a~1dkW5#n4l~3H(+N?0Y{tyeEQLoG7@`a zMM2K8ZRY8bWob!GsU6*FZ+(dr5{$Gv`zd&fRkn$hqoPGYlb3BaWITW6YXXl6iDyjG zb%fQ}*_<6&D+=uPu()Le6R1;g`B9KW-tR0_rx6ir;uIzSC7jq#yI!=+;@GjVh-B(J z`z5=?)OnO9%UQd%XjBTp6wXi(lncR3YN$n0iFyswlltYR4}732d6_G5mg6|Jrv%6r z!AFR_uBDpXtNBC%28AWTJ~r<3-xqL1RPI{Ng}(m6A@d;G)*WRDSh=s_qmvr6!?KsW zA4zk$9Z5MGzRm78R=)a|AJx)>=oxD|^8slXuTz+akry`|YAP`6HIXGvhxo<#l}~l4 zRfjpj(1giEkS^(i2T1n_(#4=(9D7}2;7vdiz|y;ug<h8GIp<6?AGCz-CVwx8S+!V=x|r^l5kH}^tCwvCwU?*vjseBpHH9X4iht9l6LLFesgGA3r=k z$>|Oi4$IhOIPVfRSp-~FMzvrNF6)E=mGdpv@OfS5dFA;{!+rO~>Fehg3QZFdq23T} z^i|8`b7IJ9Ue!>1_rv{QBzp0ca*8G{agV93po7wOS3<%gn9kF^4;k<6TGLDtTz-ps z2cVxF_Ll@uHB0*l$ewqkYu5?!FO#H7KDt1VJgVurM!&Hx@u9~1$trv4Fc>~%jlyr` z`O*4BvG!3@YO&w$k)!w9sg|hj&Aom zJ^#sc`Y+g2BEBvDLskw`|} ze$mIbgO>JXA=>3CNxH9&=4iBX2|`qf%&)%a-dA?+`zAJ+4^9A zLqoBS0bsn&^6Aanfj>O_qIQ+Smt{XHH1mQ~;cUF?(`j^U`2~0<=t`qc3eE_ z)!vxfl@WRLM^B4P^pFU{i0wJt5EM)Fmwau6y?UU{$c#x)_$`NYjU!i&4k_zuGSx+c6|*S?s|UB z6F>PBo2|ih4`Pe~i13zmf*ZwjLWDT#i&jm!_rrq%Y51+L3h)WwlZqsvgSj&>v5eeg z-w%sN{CjC{qmWloh=H@FZ^KXGN=Eez56lOmJ=Ds*$9+Ojq2cHqc9j_l{y!dBJc$s_ zuC2G$X6lv2>frXrir+JSka5fM1bXO9I?%99iAR`ec$&ob*S)>2<>B9$q-+rKcmwB0 zhI?_fa)Htwn-h0qf?A@0(ZA{lDlL|MzrOg2)y}Ga^884#*jp)dDfn>eLJvCA$+Pg( z2;IR<8k6)#uJSeVuHNK$@1x0xgmmux)%bTNh)9k)1_xUc9%MiFu~z|BfQwxWC@2m; zU$DMsi^6_ba-x_XTkCor<{^=4V2z`3d9f;y-wu_Nx4d$CHKg3@$3zp8uOaPNQnY!U z%t@F27V3N8%F#GlKl1K4hD2hnk565)!*|?3J%>3PpfI(^DH%K5#Y6G}E;F|KVM?HS z5l;n@Y3>vB{xo=ZEZ+h?67Hti#C*Q0ei;elUShzPS^5jNV#LjPZ+oMM;wOdVgizQ4s3qLuo1_gdxzH!?F zcY(ZI*3#L>54O;w8?F8Z3^?mf`LsC=;};MYYzWo6;scFY^A`vgny7rZf|tXd*a+RL zNoBi-WZi0Y;RS}1N#d*3?T!9AW>5TI02f_KOKj=#`NRifot`fe6Pfv@kO6ij*;CBMg%b3al0>vsU{Z)1M<$JFDvhBZx3F|(zBTEtA z`>q@X={A?^s!11z`V04A8)>am=U9FNW9&tyKh(6gIBfr_4H&9*(L9i^(STGIEU;KU z=IFu{fu?d+Dx;O!Wonw);f?S?;KJGZjYASobHeQ(EUrsq%~^*T)0S)J@zd_v8t@s% z1Ba?#wt!xa)>?m{mHOBqPa3qFr3RsVq4)c7;EVs_$o_uZe0gt+A}RN$NgSV>61<;f z-6n5#Zpsw#bX#&NAx7D7QU-oPgm?%Xtc)P-Bc|Cc#4v~Pn-6;ml*)&$=sfZP`s$Su zR*^v&^-p-aOvyZe+}svA#-e^^AVk-+kAO&|KbNVb;i&_pg)!#=6$U+iq9)++O=p~&E={ePE zS)8cEOwLo}_R6%9+k;SL@!;J`t%-l|Hno57HnyJJIEq5ntnjF)(jQ@ky$@9IPJ7eVmelDwoYUquk3VP-v2ildctBXJ)wriocroK z*-TdJctgKAZ2_*2hI~c}pQ}aMODPu?{hJM8E;VAL z^&2MmY-gZ%^t~oz{=|GS*59@M zoA3SmEU&6AJwZBesgF8s2#MqG>@NT^BOX^Fb3G;x;ti@y^an27H7+IB z)o85Vb}^y_ERj5OwHx2TWxrkOJj7fqW5iK z_*X#Wff!ql+@uUG@}mh&pXH21h?{K3*N+hJLZWy&J1B`ZKY!U3F>wkx(iAay=eHTI z8&P^^lutPvkZ|EnHFlU>tHfJ~qz-FfUhRa~PB?qCY-E>_iJGLxcvVIv!(391 zG!J9NBs><}KbRmSv6{Z6qE#O;e}wbZLF{N+sdteRT~MVy?KUV*_Y=tqAksyzxmYt` zZvUrRj37Ocq5X>Q-8_DNQTn&{`NR*R7pF*XiDV;RLXBz2t~xtNA-o2<5f~3H<&s`> z?n4OcxI=c>o*d+=y3~hj4M$(*DSO@ou6HWFATLBFqS({ zo!(lO?pzvTanggO*k{%|=hLTr;u%&uV4LaMDnllVCuMZ`Pnld&X0X0TaHr^81&a0k z$$FWSvF1t2m9@l}M+;$M6??scM8362H=h%te3@8#PJi=CK_E6`OvU+Rz6}^@+pi07 zvNA_L%E4qe*y*B%ddqt%>`lG3Qe9nd6E>Qx9VkkBX5X-YA8GBTjA)dUl>GdRc~)J% z`<;@3dR@T$X~}IJ_ra824JfRG-KM$A|Vnh?jo-BBIyb_6_4=xuckFy`BsQtY9W=5mHRc z!s-8(MC9V)tC_1W^uW|T;W3V^41dTXoOar!W#JSAQB6}gWfmSW79P}y?%IgTR4?v~ z)~?l3ZnY%43o5-BSSX6oE(@EVD-cV4f)#r~KK#%dV`iFy{`wjE^D)>He8pDh%d25y zl2qXAc;|NbZ|br7cje3 zpRQJG&9@_FWh^+4XD}6o;HXa7`o5Sy?e}rnV?tp}7c`gOtUu^bF)LRhs`yo+`Y!|kH zG%h3Hu)F7J{%&~Uq?L^KGs-!1iuNY|%}2TLbeM0Lt3f05-S(B3U({>-_oyXx$U7*IH!B|R@p|gBHS2Fek?!*_ zLoS2-BQ&%d-^FV?ySxOR@lsbe5zxJ3ew#I51&HxTOhx^|8S9L+5Yi$PQI}sF7L|!P zmANs!v$#EfQywA7Hc;2)l>TPuz3}Ik@lCb5mJk|0jj*L#5PSjqV7VY0`u&Q zq3m;%?R$-T8ShyF8_L4wCLHy^lu@cqquVaCKRy+QYrUEbx)xWN$cgy+(&si*IRii4N*cs36ZV(NwtbVue~q z$h~9k3^IW)2y>WyX<;c~mx~YS%#G1p#AGh3ZDU|ZY_#poR5wcIRLOSd)qx5DAf`tR zJ4;_T+4LC(4IGYRF*N&R5`xtUD#`yFo3&sQU~47<6XHlfX>U!*#9#R-VW*bUnb3$3 zQcbCtQ~D{%5DAaLoPyX4-7i{QZ#aBe+A8FpiAphqScx$T!{kFAh-xc7_PnD=!-4Ph ztQ+8{u-kaBX3^xuVc@TRwa!Mo@@i;?Upc&sSy#{wZmq3qoAQY|2ECOG&tH;NY6_zq z)4X8P`;K0b4S3NM(@}z!ez0E0l+Jx1(TXL ztH{b~gwBdvbZG4y7k4cBEu*4N#eh7*EiOd3p%&ur-o49Ot`YtZ`HVHLvHF*4e#^{F z_!~l$6%Osua5EEZGLQS9M+r<^eBtNkn<0>T^(R~un>a{0Sn!$}ZRhQNO72A^tMv}0 zh=WIVpv~!@_9?}H)-zNw6@^x~8_0R2IN<{2L>avvdRzex2eB1+G z{ZAsg@6~1hpqQ&Y&gle;yyu^stv~xFgrZ(}*-Zf9MKB+6A{Kjb{+Nybd z8fe?mR~0WGe}@RFcO)XpVnq!zxi&f2pt;&$)j-Z#temkaPm(!IgpW*6{7`^y%rqXW_)OHoDHc4L6sq-FZD>!q<82xj_d%%vrTD~^_fXwh>t^wOMKswd^i#a-2xFZjJeqco< zTUKBaTI>UTW#qSdj>7QG*e@+DFJ&K%FOx?{;ce)w*w*yam9px+95GwMQ*_%Hq2UfF zIP#3Z{ICIY7-dGb>dQEx-g2|Zc+F0LnhF{om_D5nnu_4q)E5;X#+iL?Z*t9^VwCvr zV?9lV(2&NBICPSL-qXbaWSK#`tv{6)I-hWhNa@}j9ottm>)6G{Aw2u&H>~8AELA6W zpFrZgU@43V)Ed~G5w@Go{?6=+hmJW^15Wi7@Z`DQ@QWZdp%xP+x=Hqfr6s0Isd+ce>d)*wo3 z`{SASbSU>~TBrz~?ElLG=uN^seltWAWpyBebl5=!j!sAG{F4g2`Zui-nP9$BfGZpS zDWLynWG6X2w0v6rD4d$N>pQ(%r=QugV2)`qKvG?M4TboM!d!@1Aj8pEl4F#d2CRtSBZzQZTyw=xHlc`La$)A z-oZZ*ODkTM&Ya*HjC6Bzi}V^9(Rb~8Bk|qfhN#^Ia%7d)zP|J7{U|%|)N#s%$v^lb zfY|985s~<1nXIIX=EhQ&WC#S{HRlZ^U&M<7H@<p0ChY4Pt|0EkywtSUD@hNLgs#hIm$CA&L*dIT&lUWm8X zCPYO{J$L$sy>`jC?Y^z6p~fepy?6T1%=P&`bt6c{C@U{)7^d;UA!JsN-U|e%d%9(@ zzXBhz&O=q4sjuEhV`+u!Qg33i0w=R(pI}*wRq?|c>FUGwiNcP}2j5Guw21w*Nn9)) ze#zPUL*EH2`cUy8Uv3-HPUq+Y>Kua&rj2Ju>ifcG`yaF*`4>@#^&hXNa2D#NP7@eG z6V2rPaN^@c{UJYVD>*g|iO~bB_NvF5`zcZPf#3q>>5UX;*!KOgM6sq>*A^04Y}oR@ zK%y9fd)NEt@C=Vn)2Zx`HfIm;NVxm2%?MJo^TYGR6K;^*qCv{dm)!_KKTZMyGP-b) z7vi;Yj#8sB)#}D8Q9>7dXe|P7EeQ)w66hF1?Hc}I!F<2n?Xd#DSE~8*zdO3e60HpNe4sy3BGO#P=YQ=lGiD+BmieHiit#P&N z43-n%<5u1Ww3D~$L-l1d>>~17R<2zh|BdcU%fh|lrqx_zw_dmq@AEt3JrjUgLKQjj z-$odm&hvkuA9k*&V~P2&`=;rQK@+E8(;}ARpK7W6O~#nbA8?S}huLNZnZ*26!hdoEesw6^=+VA1PNk!O25cDV>kIf8eb ztLgv{4L?`Z<2j;rRA&fHZBp-Q;9i*+HZLw`rdSMD!W=O@biH(k$)9iQ!FQg|HkDC& zM}X#es)11TRR^jeXL>pd#HWT}9(oCRie@ReS+I7yc}3{$Ju|>23S_`Y_7NKxpUMEF zS*L2JDe!8Yw4CCE3-GAomYM7eUeU2_ z2Tf$1=62~;lJV%%x|*}M%~ea=Z8VS+8NyZ_SDS>u|hvemt9{N}A z?V`(C#r+Q=S9Q1H{3ljAfbrM4f%Z16PQ)s`A=z&S$sUTKZc7O+R~blyiLAq!0J`4# zwW7p`VZQ8Gl*AWy!cGQc=fl7m?=EPb-0=L%~Bl#c4*5eluwFWK8X7RVsrb+~>_ZtR>G9t@7y2wPj?dRYgc2*V^fi2Ht z6dd~?I;R#{{X|+=F%)T_a4f}risWzP8_;1(NbwK480bKrNuA`liDL-F( z==U4T@aB`}H`E$3((wxoq3$OF6c02$cN;#kssnNdlmb}l`A?f=U-fh8A9ckAj`lMh z{@D8JIoE-Dip8#q5wk#immw-lshC8=)hja7z2r>n(EYY>;2jnx$ojN&(6Pb`Xv_Z6@5Mh4>={AGFB;E9uDT)swJFU-KfUz zP-q*6q$eN zDL?FPVo)diVZq(XIF@=BJ{co<5zK-!X)Ebm^Mq_|YdBPapp{RJrb}@#$*1LEKhvuo z)7dmjQc9Ye(}x!IxRCNod+uFDk5Sh@V;h_Tl>r`$D%n#61&IS{HM600YHh=r`8wx~ zgzSBT`M5K;1j5U=dsv%bspYL#Zm87c%>w5JdydWLRe?W= z#4Cmxc6Kx~4j#q5e_wa^zo;QRH_n4AaD=U*oX}o7wcE>oDHOz~jZ*)jFv+(5{W|3{ zM?W0Khb@!vo9%oL>c%z@HMw9ji^2uSW88t|niAlO;csCDU->zL?FAGc%dt8u^pQa$ zBP6>-3owKcG^rl;TOPqFHi(ZXMR2FE)?z)f>=?2QeK0kifu4OeRlu++xgX>l}7>F&@F2@85LFLs$PWIp@((yko(R%n1-YKeul)9{U=_;LiJD-|{hITcYmzs-gASG16I~#kKh^U)C82aKvgKCQi zEpm##eIsa~U%?qJ&fQuUD}UqIEj8+J>fxR4lp}nfZ-oR0h}t>eoa{O&JYk7~xtqym z=^{w`Qc>s?+Cf3kS22d}c#IMvP>B5y~Xcicpoi3u}te|8dBhN!fOXzL@$Rj31sAG61PZRMq2=FVOGi1 z`%1*4BK%9ucUYXLXObyfU(Y)X1etIRvXi#PqSo#|1+`gx4b?RK zrtjjI0peT7>!OqD+42OxbhT+|nzS)9;GBSIyC5IUsR$N-h20vzKJ_apMqn)BOO}f= zpC^kns~yIR{10_ek6POmuHY`^q|)5y-E_|v-Xk=BV@JVWSa-!=MtO2|e~XzSbYC!} zv7A6A^5{n-mzd11#9+yXHJveuwY^W4<92E6)TyB%&PteXw;NX}?71ce1wG>JQ|m~l z&mLfCx)|uXia!X}bMe+*)Te76;+CGK%q&^lpM`etY0nM!>H*hR1 zeHIJ{^e0*ESW0!&=7k13<+#0E-Y*6nCcx}yJol(bXRqs%? zSJ_Hw%k9g0sO2%iba(ItRt#|{PIy6pSX38Ez`kWKp5GIKPfyrVvkO9(7Hp3YoY73D z!ansag^mRo{p>eEwxcH>ZndRjfq+7x?TS_aF;v~}MI^UbCTL~)@rp{E`jN}10Ico)f zFH5`(YsOHv9<+)A?!5WdraVVo(cZPgq1*`IF!yUaEi&6N(#1$9H27ex9qHKkH?K-n z{q%N_W-HssP1hx%g@SGgEGFy|{?zvlx)O5 z<%QxxD7(GsTDU&vSNBoZf^-VZz;6nGFaIlxzy2opgz zi4`J?5E)1zq%3J44D|~e)Z(IDi_6%ppZ?FNoQp*S9lwpfc*7Ogs%EY&H!fb2-8E4Z zFp*nZNW#Ld3M#C){4#~lK5(TXe}fb5bFXqNZ)r)Jx*)E{v>vi993_5;Jn0gvSJH=TU~Nc$-0thF459W+PEUs?Ue^F^4xDRZN(nna{4IgW*?KJh!K+0VU#Cf#%I4MUwa1B$ebKj0srItj&J))QE^M-LAJ}x{^&G1 z`PSaw-~SC-GAR$68*>;2)e!#h(51ErAR=+f+h7dT+H6B45H z_symz>T@=%fWywx9^RUZ&K};zvZK3^c4;k#9<$h~3_T3|G8?Kq&*wenVGkH{`*Rew zTBRV6kFCE!dNv;;kfJh&sqe+wCmd?plQVYHnF`9_dnt*tLMHZcQd7RXuFX>?(9P*n zWTZ>cnBkhxK2gPnjt*RFS&k#OS@N_N#Uoj~e!}xlNTRyMbH6OrQ1Z)M{W%x>%mUV0?Zy40a&I@3;D z=wv;puG~USeMam7G0yi|JY0S3E0#t?D6o%}^9%pB5rhs9LKA6AjJ7(Mqj<_uq~}^g z#+FY{a+pdB(}F}&g`yEZ>00$}QsbTeRKc{+NE)K zu`pzO6<12~c2tUV)sQO1k=tU8ce+;qqV`1>&&KH*ZwDQMk{%)mfYe?wsT7QEtQlMO zxP5@^KeucnoFS{jdjE+y{g=t>5Tz;)pNxl6Bh9B8O@fdxZnj$A~W<3u*6`mX~=N_2un(;A`oARNz`zYaL zQU1ZWPVvwC{T`>YRX?)0-I(Xtef2!{I_KL!jMhE$-%<_~_sLRwP@R;1XN_vwTZ`jJ zlJzQud{e=miC(qYP6I>~OMI*n@udyDkBtMK)@Wz2fTg7P0Vv}Zm5DuQRWpb$EK_xk}f`JBMV0jj!u*! zmAnYJS7)*PQUzwM{(E}Qmz1s&b#o8IOqA(eeu=m1WGttt${UDOEnP&l&~6L`j5dWE z6w4L=iCt(m=02X2Bn%%vFar);n4Wdn=7{q71Ls#cJzLR7_VrlynSme^Fj84)ldE?Qoq zok`@s+Z9RE^-0SXdDz??!(?Xq<_$bwNs#&q)pntC;nv~(<0Ak4wOK?%OK3wRkKUt4 z2Tp*g<}vXI)O^*9H*B%qL_Ej_&bAE6m!e*M<-VN42$Mrv73aro_x%_O*Ke_d<+Km) z4_|0{0j!RJ-xo&!2n)RKZGC7@-2~||#gyzJFjYzB>I-PauM8Vf|F7s_Y%cg83VF2^ z1?^)>;8XQ+h4j7xY?6uC)8<0@`|+giW{*k(L0<>mG^9v(BmOX)5auu9+NBFmdb9)i zI=;e~#)4ILhK;0i87KG@;gd;%smD zVLkF|l}D|VbBgWPx)O_=Lyt8vOmy2N3)$h?t0EJ$<=S&0PFIlkP@*v;j=R--JxJ+I zkk?0J#FEGeJwX8d9J?vJ_x&#G?C#2X_3m|R`DKOQ%#PiK!lkVHT)r)B0iP#?0XXOa z)@BUl=_)j^q7?sDwr%w4_vaO0inQZ+lkg^NC&!dam#NJ8$+Ot2ug%1s- zdCqXhcOQ>CG+sj-{^?T)`S$m)WrN{r5uRZCHuVHwd_{GIP!)kS{Q<@T4aR)lxQkWwj*0tU0Ex&J{XFYdDri@x4*;|p~7MA+TDNV|GL<)sR*8Wh)q4P&ZpXP|%;gd8fP7vZ0mr0@5SVe*l5;K#D?nuoFwhrRKI$duu#u z+E~)hc>KrIXX*>1!z1Yd3C!=Y0`1>n4ZK77fJTcu=ki_lZ6J1jx=fy!yW)$?%698i z#iRW$fUe4H`9`O=TOposSDE^q!}mJGGa@#h`X&m~>TM7<$`XKY!ep-B96bAK>DBzNZkFC9lKG`S72Q_)39N4d6&y>HV&3c zCo|~$wxFPEf!kU`-L)o@>^J+%@k55@%m4X#7|tw7qO}L3j3nqj-v~Erdeq}G7WyaM zQuMB3eo|S*54~py+V^-)Oi7QP`_*HAzbtL4`@!|HQ5Kx(gLQb5xt(|&ZSk<0yFZX2&qk3&As_a@k{PBe-2#J<#N$Pqq~TliT~ zpE9KCmNmpyL1aeO#?C227fVwWM)i+XeFZcFPdoqL=!uKM0oQi~RiEj3@Q z$*20NuBaK_8bg4cv=2S$0_uiffBp|!UmX<%`)-Sb^nfsw3?L#fgmeroAR*l$Eg~Y4 zLk-g1D6Mpk)DY6$F*FD$-8CZJF?YV-Irpx0?)m}T)&sOaBmIHW)_ z5M2t!W`3gkdaFA{Z8u(XmGgDTdxL3qvc9zxIb5TYYo~myj=>Bj8;-yD90Y#`1;+9w z(>65IFF0+@JLVn_6C$05i5m)Xa>!fs_a8tF4CA=^ZQn&q#h1|$)PiM_up*{Py1z|1 z+WQ*&ULLOYMbq#aLCG0cvE14z&2;{1GurUTj5^{K2d*C*ynD&>9PhS;?#aPm zb>ErHmFdB6bUp+PM>G3dR6M~}4oSFoYG^|<0WuG?rW2rzQ|jFmnu*>B=$uID9G?cV zTp|$s*a6!ywP|+0W&r-@kwVv&3B* zEtqVU*gJ`O9pCT`zf)SpeyR&|Xu%tg)81h;;%IV`_fRkQB%S`3fiwtsBm&?a}gM@y4 zgW~e^PE^alEZeB|M2h8-t`SUnTyBg8!<5FvhK9WVY%Je@AAZRkYn>KWgOPUNf(+L|t|il;j2?(lc)4BMU@w0DY3$HV zO6ukj1&@B&)!@-|fa$M4eiw^Eg_&#)bc{j5f$i@@Ms70t7sq^jM(t^~Aje));$o&| z^ZSQ&TsWSQQ-?NwOYtQQsK((lhLp`P=r6#iO;|bcVpw;RHxKU-RyN|(jAV!!Kw*h> zM1ANO6k~HoH!DqwuTjP0Z3qS74}B^8!MHj>tUO!zA&w<(EOXw&XtuvaqbC@1y8wVI z-OQ$#8)n>s=#bf8on8~%nd{uyM>n_3ouU8S@SVW}^A$r9 zsMhrq2-LE~3gDlsr4K%$7wIZh4?LCLFkCpb3MNEv8TxBp5jyU2QQ>}NVB_1$dPY<;T!xSA)@;%Nh#@#YB0*}?>wU`w6XFhvgSG4G7l$vL~ zcl0YK{pvYCKX3F=ejvF`xR6hzfJ4e-&|o1pLSqIZuv%^0!E?Ewbv;OKH^?CIY;S|Dllw z`HNyq`Y4vPn}ZIM!}aiyVYh+QVp4`#PUm&}6IsP$+E$S4sh8v@vxYKd%W}{QPu242rT|IO2q>(9GDbF;5U!8p`qGltermc4 z9yy#w-^+#TX(;03n?84_Zc?|z5@kx$zXK!NXg|F(Vpx7;(O7Q#km>8&uTjh7@sXRZ zmn%xgWWtIYbOT>`GR?scxBfE7 zAMRoaggvT>@qP5K%_X>5g6)fA{h zV!(H)Y&G?{dBHPzEQ}Q%%h#_?$MnQwcU>_u!@!YcOwcC;^S3)zz@O3hCs%Cfc(%ag zd(`f0$lWp}<vDW< z>ejD6A4b3&-gCN(w1rk+HM#2P#>4xj^(5OGc~NY3=V+-a2}|b@ln(dn zH`ACy;RNv{l^xv|ZMaF`KTp~8|7`Kof4lrPDrvH=fZTTV{`K! zwxrV5Mz-WqAVk(%6=sCJ>8*$R9$a=ba{byaX>|#Fr(>6Nxb(ezHtK-0N3J90mYc|v zGu<#F7DuBXkG!910Nmnj&F+u_CbJPmm?}hsyE0*m_hrnetlE%#G|JJ^5W|Rd7bd(6 zgl#`Ea&YZFfVzmZ80wrvqs3q9k#tul2(Ra2}$SFTs3hpW_y_m*L0#E5Jz z$C1#5K3eriJ3DeLkV!s_z)xZhDz$ya((j=h*T}R0V`nb38<3JSX&IXuqMs z>=R6?yPi0ftCpEDA=u=w)<`GZzqdm9VKT`pFd#n4if}_mmuU4X?BPJ(=U@>`8~|75 zjjl26*MI);g?Rznbw6$oN}Vg)EZ^EFoJACV!yteEK2Bl3(${dVD9(4 zWV*IqiaxQU5v4XXHD89rtIVN2aOMHJ6^AwU-8L|j&4#KE{D6JD+r~B1Y@*>NX$YU) zP;IeM*tJsc?`I*60)TMj^?-It{mr8emxp{}S#0im&IAT+9^2oI&-3N9eXIeyCw zc!uM=nYQrk>U@;tS$rd-?6?#Rc-N-0OxF8R{XI9ByCc9j@_~3-<8iYC2!Q9h_A+4= zq{I04Sl7}ELtDRox48Z6_D(I-azx}Meqf|_Nn&Xj@k1Q zQ;~u3JNlRDHOcW;We(d7-qUFDjE(KPk#)F3bC2;_u4MS&dWX1rT60Mo9W|tTwzF}e zGK^(;c`{@pF}28O2B6?!B$E{0E4uX>0anQU#zldtT8)!K;!u>1+owYNrux(N>nEys zD|Ff*tNWOH+aIs}|ANrvnG7_V$*P0l@HREP0OHAN%06 zO_2j29qOHusEt3gNL#$G*S~G+q6_`=9Lv`8>FRJ8^S-Fd7JRPO##D?9 zb<{|@?jlYWn?Bxfd|U!?pqn{Ug&do0k&AIDG8=3(KBn@cjNX$O%GavqB4Z--Gttyk zi3;j>&Au4ZTlnR^XKVe^7FURLG-6B6&^BhgdC-V-DBxQMM!{fKe|JFL2J%ew6o)$* zx6kg%)+sD6nqMKl@?2dWw@^rj3yw-w#B85MLJ5Fk3&bOu=wk9lkbrnuJF~9s$fc>> zxx+80B7VR;>*v%$`e>k|N>*4|ER6Rb+`xxL6e72P6#-Jm#mfnxZb^~LNcd=E6&Zn- zs;jtbZDCab@@jTj?AmS^)1i^P>L=XQxP08rB&bRRAUkz=pnD_B^w^1tQ>+E9YoR(9 zvmqa%E-iA=FgkO&8@>)WY5S52PcCy)x8&sV!~R;N`g>Z_Zukx)U+?xFe;H9$;4ixC zc=Qb;g+mo-W?I_K-(l4uct>shY)+W$AsE`b8Y}%gBTMq9WJj2c3aQtysUS_|YP>TE zs4st~*o+{gjk)dk#rgg9zDblfwr5nchCV&aoN&9^WB)PR zfjol`099u?W`pSfDu-t+o)G?dUTu3Z2(M9;Vx?WDfybs^ zA^Bk7^>&kFSNWIF&`?xUR2o->ws>nH8aPWXqxU=J*sm0#Voxx9iOxNg%##Fa8JGSd zxAc9jJFwMB7KN7kL}an+-^^~Lkt0yAS?nMJfJ95=9$ks^1855K(zZvu%KiJ})TsQg&bUwx`K z%3CJoGNPJ1Y|<59%r|naD$}#^+V@V&qy~q3WwBL6LNlqCqEy0Mj2;|or&tko#{QwY zzbbFK)A89+m69prwt}o_9S>_?zLS!8TMuS&eGwx+`YNutCLtM7mqT$4p7OQFnbg<* z9d5pUP$KAy%hUf#H>NiI$ODJ?zC>iO9z~svawkH~In0^sHk9~f6z-RJ#8#A)mE0A< zY&$)_HT|^WW{khFGqq_Onh)*!+D#iTpUQk8*GXedJd9Zk#-lP?S4O^RcK-fzCng2Y z20}uYL*HRed5tx2+He#owac)t9xj(b@Q4S@M}WcMm``#bEf$_-Uk%?I>Te41Q+#RK zt;L^Xc@P@vNJ5+)6@5zXKlksybE5T5#@oUX<22DA-Mq83wU6AK$_CPW(WCgvIw9K9 zDlQ*im>Yb1|K8UhcW5A} zV8fei4(f`#XCk1l(h}zNH#`6`8$#lWV-Aw1v?5fF+A_mjwc!N;%Z0kF5v&4*ow}jX z7s*puV9k7BSY?#GPNH1Knol<`N+vKFQr20{xcyuutvw&+rDQ*J^ZU2)OuRiZ{b$Co zJMVf_{=hIgN_Z$pfEI63`MpsuCpVz!4XZgsV<`JgN`G3{?U(8Gpwp1Yo{~U|o?qEWe z;f0dIJTmNAZ`E3cQo0(GbfgsC z`6E|Jcw}%+$=%cn5|vSCeF{&%Uc|`GDA%cUn8&c)b;ybk#Z5Q=lSm9oCN#!0Q zENO6Y;)hp<3&`P>qnYpF0Pry{D_#>U9A7

    ehDd>`1cjF}gfaGsG4-cWe#?-VD+w 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 &_f3EJ99c}<&779 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 BLVr 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

    ukucov{q;B{LR>e@vY8EF zdTc)$6NIA$0y%LRA?7lI)&3noBV%*uLeM&W9r4(TVqG_CgCe8`ugvp7nk_Au2b?S79-7?9jW>*c9ovuM0o=c=-`$OxC5i;hu_S zl7-@X5}?qZlaVULN>`q0?M~@PfjfwY(Hf+L?NIBmx=G7PMMrQx-<;#qR>EgCVaMYB z7vo7W`D7o|=MN5k_ipbN(>u8QeKA{1ETr^5kLefb4~|*1ytQ+tZ@!eP3xL|g#XM8i zpicbJKLfSR3no?@dZhrI5xGMOa9Nb&(j8_pG@a{8(@>h7VC$r1RA^3-2Dd8c|iCyB*RRsK4%_AG5`XSUgG>fB^PN zt5aR7&AQ|OHin(EBEz0=dqf2N@w^9HymMc5fBCfQg&06|!NxvVNS-UGm)(sK0N)fM zCJG$*OXywn80iEFviyo^aozkYR2PC{eHJSYo;&}VDEwa%p zFu2DGb~FFa5Q+*VRc>+YGtIzk8-L5O^;z7k`|?uDuzgh@)$;e_?7_sjsl~vSGtYeW zHd0eZyGAn588_MlQ3>~hnDm{hU90!f*W_8E_BejZf||Lse|fq8Jfqnpikiqr2{S+S zhl%5>MOc^yYUeuoSh2uAb38jYP`9rnef-2o*yMAk-Bhh?_I3ukPsjtrmUoGXi)4Lx zhmGs=(d#pq{`6XCL}XPaiha6~AXCl$aiXlYut@Wkc}(}Aa+gic$yddz`Z_chj;WB= zWI>KXVSM!X5bss7Q#w#NWea9Rl_0>4f^@%t5-Dhphd8aF9!!qA;y%MsS$dVTd0*fc z-fwoYuhUBmU$x@8PrbSarxw^4^?T_D$$TG;uA7fowUjLfDbx`88QIG& z&vGX$=t3Ni!;|84unSAx+eSn8!H|488cQ8v(&$Qg%7a7Ptm?kw+^u-yVf&)UZCsoD)$vq z3tYdPnQxV>@V#r)()Am3=RIPu9Agv*C7;R}tG}XWEcZapa|Qk2YH}GdzKVHH-td6On==q@k!l65y*x4nQ=>2kkzos0Omt%rch z!y+>ld`5VsqW^Z-xRkS+kGEj050WhltC`}+CY-s}w+B{qjt+MG)~ve_u9U>3#-!y3`1(?n*Kidcg(PZ( zffVh-=>t?li$qcP3~fawac%jJ=_z&)op>^oPHKqQj)wT15(~Yog4@KE@LE&s; zmY2?N{uyomFUC^x4Vfeu39qcv(9q!O4lV(&^NsG_m9H;~Dnd?4NbE%J*=&}hXVK>$ zbMyj~kD}3``tn9yq41kyQc}1hflI#1cS#!iR4%4wEBELz? ze=P1Kd);y^%Oh|TGhLV^tpW6LJ>gF;m+c`~!yY16?E*k|Llz`@F{}H^zoIcQIV#Or z=Cu(g0-NdBF8E2j1N6fkF|{r6KmaopYWbViI7NF}Xi2-DF zV`K_R#j}0>vOkX=5B`o4GqLUbSQ{qshW3F6LgwwroNkV8bSRE8R-`@M0~^YSF{WWT zR7yxyt>gz?J(!-_bM&TZHFtt?u^r{B+O4_jPgc1sVtgGxFILJK?A15`p+hIlH`mnwx1B>2Z?0cPp5w_oU226KiAg6=O4 ze%#BH-5s>9^D=uAvm1Y~(fZkrwokdwzPUR%!9QS-9}oVvU2-0yTtXVqxXkkhn{~*| zTfOL_y#kT>n1*6mPf@9BWJ63@2Qt+HPCGa7;Bxeu&r>3XbmvXU$Q0Bt#(HeNZbx5M zb#jIvJBt0S8wVX}v0_QoJx!v_^&v>*ZOS|YJd`^{dvc%j4(V%EYYwvigxrd;aZ)=o zNceNUo`T@wrJ{Z<`CvQKg^5--{oV$+m}tkwb8#e}gZx0N&gO`LUWARd`c=-!ib=RU zOJq|m4lAs$w%tkOocAO$jtqc{lDZ(4Jf6^lW(?Ix@QX} z9YN_4oo@uo#CpjNxnBK|`G&%Du8!A{4(=N+dUesU-$t%o2OAS{rdaxg!GWAqF4Jco9453uMldsIWAgMuUu#olOOnN#}z;x-|l=HUM6Q$#LD9IAX0^R znd`8~Rfq&55Rr+VL^60#&n(4hh6u(XMhnZ~pC2;nI?A>M3ldO`X1`35(YU3b^t6N6 z@8h>QlN{J7b_9Kr2Cw-~iF?cq=m(MN!ycv6kvcXQ{zqotYdWF8*3PQRU%+g2_5{{_ z9**oYu!O4&Uy3D(g_zG@_*~|n5Ur>POu2^(CEzVkNI-hj1p2c*avUwnaQl!1?pLk_ zmpjVif?^3)l435J5|g09S#0C&Fyn1KWAe6N;YXb%NrmpVU)z4je-d30rEB!o6$Z7*R>J9s3c+7()Fz zM9(34XkdPUJylM3`TqNb;bv&1W#t2BkX(Hi}JQw0{5-)4FRg4q1iry zxeJ>Yc#q|Hr|p^#LVw8jN8Kykw9ov0qilrhG@jKTyLyl+vQpD-HU1E@&wMfJ|L;jT z?Ky;82*DD3b+FXpNJUNEOm^C^<$@3my$&4Rl%LiYWr4)YWBwYI68$C;$?ZHgpJ4d zalV%UT`X}&!WRfvB-?CwBlrcQ_UZIP$(Kr7)uuOB8z*B9-5f_m5;8C`e?x389Zg6k z%F&!Dk&sb8fxGx=LY#mo@86{DTV4LHn0nGIkF3>qS=Tvk>yxg|JoJw{wBB2Co-nw7 zq*uO`DX`52C<6Om714}VQfXjf9rV)paST5gW=SH?tPG0V-0FI=N}o%&K$|SrEQAgZ z2eP)~72S-lt?ruVPhNuw=N=`TTq((K<)U=+!bvc(@If zp(v1Sx+(N!^FCB77hf>Dk{l*XS%Piz8*s}E5nHQ$5!*)=RI^+pOd62#a}>N<$LF0y zHnU{R5!gG-JgWwAU>;n@=KKpqL;h4>b^rXy#S$_TC58Ag3bf*-{{Dz}l&hSpkD=d} zl(i^A4nX!h=^kTbk=iTsq?i}1&~%cyB_5hTk@M%sJ9-U&m70JI^w;(<*h|)Z0{h|q zXX@tW1_?BVrnEbgt9EfFN@p!*q$G{2t;K+T)U^5-oGu#pYcOuUNr{K?00`?R!QD$H z-$wN0uN!`LAC_Wrfe|A^WD*DUZG7aw9~YARKJxlz33CLwCw3cXxp z7-f^%8K4{Ri8Ogyg<#C6s$FjV0p6}S%q6_XP>6gJk0Gv)RB#af16sJLF;lMlD*bpR!d@*wX7l+eE)C;*mszNGo5i%U zqky%zjM$( zFU-a_!f_njDTURpUxA6#^_aN{-p3xxF3kUhHO_MT%QUjB(+>!`+V+08g-r=!G`60{ zj!k+|GvUbDMBjYPne)+=0W8WtkR$ePr(#UO!X`$txIW-AsEj?NNT=R=6*|4mO zB%ibHO7Q+y#t6ph+tuu$L6Fy&gm%qcsXMdLyvZAf^-;r;6QMN1YRx98qmgx_MDJq- zPfW%gxml~_=aMGJTBFB+SUITDoBdduTwf;X3UA2Q6v%GKC;h)mt*)cd!pEi_b?D zDkB9Z280(4BTZ(uSM8d+UV3hUw7kW)Gu^{n!`WP^Z6Vu&XjCiB88E3@Xt{h0Pr?Oq z){;mg(Z6!Vn95DQfz0DY4)0 zpyM5w-~5*C<%4nA43$wrC?w2bVOHAix+Rzx!UEPhcmWy!;KYe{IBs{g&ftZBK zP@K~QI<82&_7w+To>G@o5aLU7$+ir7UbG&TgZvcZ>hsbH)~T9N>Tj?l2EmkadzG<| z2|*vfu?-8`#44fnx2s7q0GkM8rQM`sVn(km#V{x`s!qa=IY*TD*trD*-T;;Zd^pPS+r$DN~Aw)bY7OtqQK`O&`mX-yn6 z9W_pI=!FukfQeS_B=l3x9G%z$s<0@v@opS{$1p_1f{xWH)^vmhEz~%3S7x#E_a%yJ zH6>lS7tj96dgG|LiGA;$8mh!N>>+U)Vr6ufvTO)#*;bf#xWiG1KVIaBj?|gl z=+M^=iRIWxC_^WuN)(+W{Yds)10H?yS`4)8sw=E*xKEEg>zy69(cu|Y|6lUJe@@|t zpP$PyNtZO!8TGk4@t;R_-~ae5mW)f#JVa5xK62k#?wLtgd)L7%Taj`9%;AGG!~FUo zmAC0?reE%C&{^w^a%I8u>`NY_;VS3$UoWn`f5i2e871nTB*XS#VYD-uvkxf&|9=($ zPQk*=%brawhwwkm^7CQ@##?LI5m^`R>oVP$d0FXdjr{bYOGX3v?^$oOo#^~HT}6qb z4{_SWv!c9d7W4-eoMt?Vvu(2XoQ6P!+p??KP7<561GeUtmL6JcQLZPf@f%MYDv6`^ zDYFuLtg2f~;TmtZM%TD5cMRPPF6kKHrG2lVs}#3*P+ST|8?N#uNhhIrrJlb&cuCizO7_|8Iw^A6JC_!(A(2E> z>@jt=cY4`>910YjM}8mQ=;~U$rYj-FdG}{_{JCk)Vpz&6&aot_iLhXWq_m7Wv1~G$ zvp}JW2OEBG%iV%|b~Iyu0wXm`^62X6B4Mqb`%t*Wyf5lP+w=+Np15M9n~l(- zj$rP@zf{ur@kk75x8pk47Q_0yvj6PE_asbWZ=3Jye=_Kp*rW&e)i^=wxVI)PP2Vm7 zR0|mjcAht1;R%C1(f|=vx{`(xAZZtyKMv0cq#z@A62Xj( z1-8$lLcTPh24o7~{p-dHWWhig3xwQ`4BTPCUpq%eMqs>2t+O_dhuyghPjC3s{atb`voD1-oe@-UN70Nm;7 zMK|$-jUksG{3{SgChg=nzUsI^IG=x|J;r_$Xwc5p!tJhZWDoyoi`nRExqzN76(W-M zJz2_egt7MRCi&)6sVTFA`w{0kt14S6%A8Y+sHT+~+Y3SH=6ZFhLlg8;%%bDHK^t`1 zmRwT-);6T7Rb^~>JM_+KaVx~1Kj}iIORQ}PZ_QJ8c|_GEZ)3u1(L-ykL3)<6V6i6x z##_ikLJU>i%*F}P>(^NqKwsbknfUa|EZqAkefV1o-0Ae zqb)1(ih;J zE3(|lfVCOqr~LOm^_%e42BipZHT9cOW0$RJ*4&id<(#-bMgrY*XNr>sqyg}!!%-17 z76L&7O<((@l3vE=J>iLFGr0&OO*y4m@g)0tLC(D;XBcF(Mt*cn7E*#|%qzhYN+X5O z_n$I9j1=nmqY;$+a+7Cxxc&&GfYX7mHHgld=eGIA6%60ki&8SJ1W3Q8YyDXMxtST4 zz>!k^^{=0v0w(tGE0>3>rF_8E70C2##iwENefyf`!lgD!)hQQ- zo}zS;ttz(#3p0GrR2w1JG0=Y%c4XEWtfbKFDjPeKkAV? zLk5TdPyp0XH)v<|@{T%EGI#^OAlgoBB@n)be^mCnz6s7(27wn%P|$?u2- zY--OK`Xmp{TS(T(WZoS8Eo<5T1^@@7&!pZ{hJ~rJGgJQ1SAO&{^9v}u^dAR_ick#)+jK8P6~@gP zm^IY!fsPgPAJBD@SWpF_a5^SLm$7%qPVO2n$?w7x%fBsFb-U9)zIb&Ej5I+y#2Z1I z^k|1XR+Swco*zFQ&RSqLr^|tHa7)2kfyCn8 zlm*E({`2nMEV`gNqX%$!vbVPv0oUOFWgXd$&cA)m^3UemBTXWDl$)-fv=Qr8fqL>K z?vh@rEwmugyXnjPMFKc{D&c)VU(3`!0iqllZepY`9R6#=cJn*pdia`Rm=r{Ro`p)8 z^B_AvC%kM!NaXzVt-|{1r@s>FMzay9P=J!h{S_yCvUP4fr~`2h(XZB_t;ZTq5JmN# z|CkS}$tWZ$3mK1Hz3#O#%Kiti#E7n0+yqK;d`hs-tR5j@_cxUlaRsYq>J0Zfc56A( zcer~Ow5urw4zc!Tx1iJ_Kx6U6SDUnmV+(`>->^C@!qL_+;*(%@6BkGI(eUmA9BIuD zpaGkrJQ=6(;*gs&9`|>s=ljXB!^{S$g1_FZt$oa00-H*~^7}rK^H@)dm>Nk6jK4i) z&n;IRnO(4BTJcdx`ZfK$HAY2%diRlp`h44-oSTE*SRlLo-ut#d!)?7_=&vK@p$XYb zDT%=jCe0un){tUnx|*BhrgqCcZGvx<>#Uj;11A}u?e_^HS*YIER4dbMGIIQ^I{jUfr-{vfIu2b~~P3w!)p_(j$HqXt;jy_+mz-$nYi2KtCkDB~K)}8*?#2G12Tt_&kD-tKSzz%D)xv~HB186A*vquWys=dhJm%ff zm8<{l3{L61)3EuAapzS~COLin(bZm^;l^H>c2WX}E%Rk~*hrrH4N1wWYU5G6+RU7Kw;S8xL;80n4_CQJBN z6=Dp}uzwHa8eEtKFFe{ejCo{3E&b?U|0&=xezD@Bo`39I)CO-DY&sDO>yP5Vol)#V zBupi-rJ1Hvkmaob#bcnjy-?8@r6m`w<~za8S2f#Nhly>NMwF$+#YGs$l88R5i5{cT znqX2Q>ymk-3wAj5xi{v>eQy4HIL;^nY|mT2~B_G%WIbtz}!yR$0Hht@eA z;RAQxcr@-fyvc?B>exZ-Cc2=z;C` zf}o#^-cw90crG~7g0K5LZBPyo1BA^|txGn#vYqa_TUwPV^j(OSy{>TCkQRN@;nlM* zT7gVB2}phD$jFws(eJZ!Q;ISBNbbn22$FDnga7n+Zp@z2u3Tbvs3XFP<@DP8!o!4R z>SclDpWEuw0{5@Lp}Kjk`61Vl%Y$MGZ5))^J2@{u-8QVd7zJ@d#wqNG&#EGNy2;?H z{^`MO#P|4n5&}QJ(p_%pOs@aJO04GU{?u^!GAtL11amm&4LR~k#wkl$&RwZ&$U*UK z3h;suvoEdxTi=SA&PktjLMkeDk)LO|M^~UAtINo(uO_b7`p3Tn4CPDwYvxOXOnAH% z`!qfhNu@ASVV|2w`a?B?D=&AuF-&$QVeVAG@m!<(iXtJ>yYY3D*liW1Dt?v4;15ZX zfG@rfiGE2BEetiy>)!2`i`*k{Z!Mjux0~bI$+9XI`vKGBobnAWBC^ye-j!z1hhuNI z;!*F`_a&${d)iykThX^Vzm(n1g!bTxsI`_NC?((^I!jMt$5v=PtA$q2E@n6qVG3WR zgEy6K-h|jjNF<0u@aS#l59e2}*TmPP1mK&kYU4+E+pSiI7|$mgzvtB_uY_;yyA>d> z@|Sw?2EPKNuT#o4Yh+^!MT0eW9XpdT1zB@_%}^`BD0Wc`W7(c?5MW)hEKCpa^X^43 zM`M78InIy=O_*ugPeWkuL#Evq{}#Y|VE>Es92UGy#vnb5&F7#)n07$$XT^mqit=jy z{!W}e9*!25y^rHQ7ABmT`ch?Gl0N-|!UQXz+O_~p@i}>2T^*2TAVNC3d{snpUFPGX zN7Y;35zMS#*b--JZd6Y{w-7pD>zs{;%w`3zLEF0v^VqCQPRTJ~Ns z(-Zhn)_(dxwn%)59BTP?{^jnv;wtdUg9_rLVGx+IG(E`ytV<>TtlmMXm9kCSVvB$9 zX%EbEuO3v;+310ZvvP0^s%Q(j%@T^*)E_oi{(r5gr0kuopMS##|pP1HT0wG8JnO|EY}YK>#*MWPc}90 zLNr*8O;i3oFk_kmU^^is6H1u3dD6%BVS-G{^jAvx`m?-cL+3^5xlcuahjNcDqBHS8; zWnRKsvnTc+AtidD(IK+|-9-7~h{|-z!;}J0--l$)&my*FA7c8Bmq8n?%BLihj`F&I{K_}C{r&Eg)Ty&y@#1YL{y`R%-@V?NR33W?D`)QFGo$eZO}Y5yb>&z_#en60a1&x%!N+0*DiWsOi-Bmfx-Ue5Xyn zTBoT7DEY>mquVMifi?Pq1KPp2lwfMbAbKx*HGOC{Gw?H?dLrX6BMv(`D-bg|u^F;v3Kp6j4 z(BFsocoIe6HSbZqJWwTAGTR|eX>1z zjK`RK!cUhztw0L{xmynq#v3c<{xno~F^kH1nmM9jI%Td;ItM|~um-=tEP#CLViq|# zP-K85IsZkC_7tWmJx>d^D zoi-2dU%VYhh|+Y<)0A~g-1(J_Gt);t;Apf^j&@{C05-jhh%5Obf$r0X*wj$?sXO!j z<+_N;qtqMc6dnotAyxBAm(X?FZyn>3m@5sUBr zh99`PYgooPq!IO%z_DFoZP|-V-^x&$ITZ*E%FMBQABwGlX2hXVJ$1wV$`+ScSjlGp zR!#AmWu@)g^hy+sFW4#w%ig+{9X@)aXn$-TO;#-*CyeEXes*b3&{d}0ovi;-x@dj+ zD#YsbRqkpP@K1^eyxC;t6jS5nHtUDSR^)vU(D~ zAAcl1Kk+U+?(}8QhOWS+iFHYm!{6TTuP8=yfk72F>1LXku3vYfkQcakMkSr{+~ZM? z;COSzHplC*)f)9*yTQEZ!uUaxI3emA@ZxMQ5G+=;^`+)xEMbx|i?)xD_A2(DiuLLB z@N#`7%$soksg{=YZW-fLII?*i6`p8G&cr_~_`elm|FC7g#*a9EriB_sXG%7WNgpYX z?&^L3!q;B=)Q~g|cEfKHE(>fjwkeScv2|}PC>UNk>Rmqq);?+famkF^9&4~HRheT! ze!v%bo^qLaDEWNcR)AzQu$`b4`D6QA%6=&*iyHMd*wV?I%F?E#^RFuXdC?eu?Sr>7 z=q0`^%Y}`r^Q#UKyil!bbEJ+|Wb`u>bH{cdpJMR*Fr%H+MY+4Yx@QGb;q(4>_g(KD ztdzG)5LCxkx%!4;1z?P$Vm9h8Zy;9wU9riga5_^=>3}p zxmlL&D&t1BBPQsOkFgP(i>vFs>rn(SC>Vbu+lEPrXX&{qaVL(>dz#Kl$tWm{KmV0o zGR%{$M{6_~qK8*$9!tLx``E$TsG5hz4OmFwd7Ut|-;vVHN7AVDUZZ(TvYHk{)M<}| z8km|}{UHp3qBhjUpxPVH7zv_vO7I4l-xC2nd8`eVBi11YGTh^zNOA@04`p?RKTLQk zHv&A0yh;`Dv^I!(u$sbW#55U-x@jA7-0XWXxbS&-GWwT&ym^#c+;kCv7Gmw&&Ot=t z!itU?v9h0Vn8Xc2yV^oasbjVZw0l92?6aXNSP>o_sZWIwCZ{%$|!N$nCmNb zWsQ4f>t0rVL?N`+hF4j#5}CW6eHA%nO^_}OyFcS_t)JcZ_mm(NbTZDxl zzl6aU8rIw?jenRNN=$aXvRi?(I+@ZL>N zuG`mH?KhG!vhOm*kA(5sHt@`ctF>@KO2u05MKI-3m!(2~kA*|%_ig>(70#w1%J0M> zdfPoc)o6M#fuhp$S1l)6sx6fjb-=_fayW^p1TR?qc+@c=r>AxMk5KVcu?E>D`~+a> zhj|2LRMG99wrivF)nij7Pdx=@l4^5@A3CC2lji$XxBdwjR@Ho@#Z~Sj8jaPk730UuBoksA`*h+_;uyx%9*|SDxgZF7}r!hIOXrDumt{8UIey zxD$BhI6_mj8dE|o@PP~FT9osC9}}X`@2;*S(ol~7whY|Tb*>G5*R#T1C3a`^tI)eGq=b_xw<|qH8w5Q8?bcj z^|K;2FJns_jyI3y=X`HE;@v)sXAeP_Uj0IC%Zi6FitZ?3!1yD``3Ql#K+3%)IBqE0 z(5Xa{Dt>vd&3tn3HYqtd8F6|L3_T}tIO|APWjSc?7T7e^TyNvW;*6Bsd-D`$`+ON= zChpL?N*6zF$HI~gvC2(`#3Ln-@O0wG8F_;EmhUQLhpdMlJs|L24Y@gJK~cCga~TMa z_E0@n`7gQ`vvH%I!%mO!pCZQvuo9!!ZL0^Rs{{3@gvB`wQD{ac)RJM}3?e#{WZa#e0KH0xmZTQA?G5#seJiy#FR16! zr4XZMlG#mDee$-7`7V}8(x1=!8sIaU=AW^rK4;NV9%HV+6Vg8QZ|huB+|8rGUu!Dg zS4VUNM}$vRuI+Z1ARL1Iw4*cf%H^!6F??NDu7+Y6c4EXoS~WGPdU48R-mFp+!lrP5?*@>#Zlt>(8HdGSFXvwvu$Xr|Dcqc)BakUp=;10#Q; zuQW~;-;k!? z+1G)4C!uf2;`GI-)^<8{r&PY<^)XX?%;*J5i9_Y%lR=!=_DFXN?vG-URDJ^A;*s*Y z>RvfVw+H7dyT<&reU$AvJ5RHs88Npx*N}klf+5b+vP9L(CrP_>4ctqF?fl`^%OzrM zY+R=NJ8~?EA8E_B@$@fYs*={lW`UW zlG>vD2Y^IycJ0tSKGj$zCqGxh=^^cZF}(!V(ku(`LykWX6l}o@+w-)9CrflzEW}P;!I}sW&6nGQHC8^=&HZ*hLDqZ zlFPx%3dhD;iNjZ-rqkR@uTts9*76Vg7hdg1^W|lw4I^*#N?T?oAD1SSH8eb2c`4B? zk=i)xt&3*6|565Z6|x{_NLPj>s$N)mL@{y1`^;Qu`M?i_T>YcP+8W*$+h(Zscq-Z) zY3lBuI0MOzIG{lrJAP?~CcLiPe_Bji+tVQyJry!5I?$q*1sO=aDsK7j%2w-K91rc= z?QS1|f(8Z~MOvpLN-2-C)-lP$*dnp593j5?jtL7dnc6XiF@KWlpTv?qSt`ArrX!$_ zahqC_DKbn!S0i3tx-6WVy9PCQsyFwufqkdK9Xq#Ru6q@5Yuu{fL6<&oqwHFJTIW7z z$|S0&qrLnj#ipq?9jKpb_y!w#X*Ahy__*YAZ~yhUe+4t%IM~IdB2K=HUXLVF;o{Qt z^rqqj*vItaZ;iOLQR;chQTO^fs|U)+$Y}ju-E;wR$s*F<_|Sp%|1pGXJsNpvx*}PQ zr3E-^DU{+uU?kQz-j~<0Ma(OD_p zO2%0i;1A@Y5e?bx#f~wfnrqzIk5H4W1s*50lON=VIWr4U3r3EZ#3B0M?xVtP=9Vg= z7UuJpmOWWk#;t7;b(+4(#)viFW`4{*o8<9YwpUzyG9LUiO?=>eMET~^H9J#!ZTePE zOYL6;-V}X1z_b|&8@=~>V8{C0Uv!*l>$+b{6>QvVD@uSaURpPp*3DVxY0viQD8GP= ziC|V7WkDPRICz%-%wSr0QIJdvlG6F~%RkBPUvM)=)$receokxSB-oSxz~Pa&XR|a& z8;g-Qqq?hHNKuc~W>uu5YvM6?k1b2&;7OKtBBevQMmoPO%cfX$Vb>>-p%q0X4AW#_ z4Cs8)SZfT}nelie^E%PD?<_tGyd$#u^3p>+HXed!G4<1h$f)K}qI8T*V|oNU>we=E)iAWD7>>~Pnmwo8 z)El$okJWEK$=%A9(VKq5NTiMaV#2r>NJ`p_(c@~M*3JwUBjYAveqii- zg8vS1#z?%vzjn zUUqhNM!4mfI<;=H(9Js$lY9dR7-(E=1qYnBdNgrVA#&FQj|0E_f11t2cb|5mr=NtxuW*3vc?a#iYRh_32m z;bCLpMJ(KN_eOaer?d+5n${)Z!v-JR$Yd_$7h9cLL?Rpk2kK6(m5T7 z8(r&)mMuS%5Y|yxrIrs(JE04C`?2Q0E=Pb^ylqQ_)(LF&G+aohMS0~EB_510hz>M$ zH#QYNdcB=#)Nw`w?XNn5;3VQV4wRbE^$`FPh0PD`gyUGnjcQGPmE0G0ybww(*E40_ zTJY1mr6L`oqe2RU_6!H4=;J+mjQ`z?kn`jxQ_1H< z$|VpTxzJmfK&bhl@n$Hn2}pn`{Nx*#`DEB6Nur3eS89%o#X z9Z;iJfbvyB4~$lg`f#%WnB9N?lFoJfX&h0DJ#fDfu690i^GR)Z*Oldc|i&6^9poTj69;`F5HHR3nenj*P(mUdMIV% zbZ3zcHk_nlNS7+ENRJZ@=t`({Df97lH6QghXw$0CTGbrJh==AkT?^J0hO*JwPTATR zL^R>WTDDWXumIY1*;lcHDZ#|LBY?H?#UX5pfn95FkuRjBfwTMco%tV;^(UxE;~r_( z0IjAm5lsVzD4{k?dYk8UR}p)^G+V!3HRP;54#NhC9 zIj34AnW|Sp%QL00R&9y3&(v$Y#?dv9R_VMmPZ>H;3y5G2=#Y?()hjTAXq(hB2hb$? zPyCyG3LwY#pFYYEmB`M-2oBU9xj^|rA9{QsE*09`me6U8VSed%XO6z)_a`MEm5FHt zlLOVQ2FaOxez;iDLqS81N>t@Eg}4g5bRTL=yKZv;Yo35>CXYHUB#T+7y#{SU*>D z>}mYuo`3ubXv+J>wmAg_AcS#E7T}FYB!T2J>g)V9R(!R=C$HL}!u*PaZ&oawH`=`? zM>=0@Rc3Cmc%6oLuuE;QQYkm_!H+S7R8xyhW@62nd_yt`&E-d-BZc>vBd(+W%KhA5W;umQ0Dr3i` zHbxb=#gjwVRc*d50)^g5E?gS*J689zT z0Zb7tq0Rj#-@2D`jc6-#xI47+3E{d)boMlzJd)GF?fc=z>HneYE5n+8-?s%+5S5UU z76V3ybSfz^QhI=ZfJn!Hks<=pO6TbAX4Ghe5z^8*YV@d)&;0)W&x`-_`#vwmj=ka7 z?&JPk_j#Y!d7UR}O5ad2`$A7@`NOh6;DFUMeg*>(9iN(=^Uz{)uON=aLT2=r#dMi& zS3a+`S4$3q1vJTvC65*3Pt@e}wKl#SL{CbHxY}D(I%j||PgPlUbBojtXmYEFzS(#Q zZ8m=DH4HS|)k^=Byp4b2<-~dVhW};K-=cb|imPKV-9%HJhb2`$NMXs{JwpoyRe@kC~wal=no- z@>g@(6(8rkn~FK|tZ=4d0o6VtvCf_)F`@S6+iZU6r+XyvV%qHJrm%yI&q*r3SqN)V zulBP={Nby7$o){4(14A9tQv(Ep8P3wD1}>PXGP)CEsBkClG(Rf^_wpzIMDXn?~}9X z4>ZRNKj%_X;#i0$v%Qea`UCX!2?gro_e3b!+yBlu=CE4rbyPPXJ$u$|F7|2P%b2c( z9euInJMDf`Rf3K^{iKAU!VV?Cr0*kzE>^jZp`=y* zZ4=E@6jCh1UfZ78;pVB%`43AD!aFSkqmdan-q=PT6$YE|(>TfadMOIc;(SzXW;{*%i5FIy&n8He$^Xt4}Xmp|?!=c)?^KY4$CbS?_KfH(rM zcns-H0`DSltS8a><$lb=riJO`lB9cDgBB*gxQ&`U4tKHLvn0kyY*4+I5(=Zs55AJ# zD$eq!5GCI)2$1-ibtki8up4GetFq3>_29t%d|nik%2KbOkBcd#z8;ffvemf8LuCw) z!>@|=Z(X`YJcf)4^@7cf#zIE`y>Ydek!n7Y?h9Iq#fbA=+(;jLB2t%v#FRm3v4qPu zx+3dyx8r}pB6@*;?IP!(9(898N^N*}_wVhSz>K(fXb@` zQv(wB>pEx;^W5Z~E`4dQB3=B<@%uwoqSn{fo(y{5A;tb|VT`Gc9$EJutKuw>(jABw z(;i)e$QZ93tGwM`sl)NbO6|ypJ;?dpW+DS3{hodtk5YhpT`#$TF|m$zAQd* zY!BOxHIT9itv==#>k)3$Ph@e-^gRnRRO4ZxV%@t-&ggioJQ4G|3COAsrYP2 z%amzof=-Gv%nlUOZy<_aRz|SL-VL7w9W<`c=~&U{w6VhnL=+LFtb=w;1N88OjXM)( z9pi`MiL4Q=_#e@BOY{=K9>mDsWUtn@((*YyIFeWFVE zUL_P}|IkK^kzYL{d>>Z_JYgj&SH_Ck(}kDSkH=I2u{# z#h4y`8}rxez_I#q@db;M|2RB|rE-TS{kk{<;@(I;IpX@g|2sXSZIGe>$@b1?AAl8# zudzpJf?&_JdDaA2J0GmIHC&$yGS1${FNFL}v~-9>HH=C=AbIxI_Ab>Aaz({h*=c*k z^~J8^Kv&ll@3P;z*U8yof@7C!SJ(0E-lm&jm0{M)=&W~UFHY0$tYeH;SXs!<78-$6mD&;f5QJy@D}--rIOJ;2Y*JH2_ozDAp{Mm)qt5N12p<-rThj9-ctVTgn_ zMR?BN9n!9>CcVGn%*}k}4s_6`YpEz;U zoBF4Q`GT5Psu<&!^vpet6#o!9?c6heknh2)P2SxAX6-ywq4VBJd!%@X6DT~@j^vuG z8SgZfyd2ue^kD2c0c=U=#@#Sz$u`R0xf(8FzpPg?8|&vY0_3Iq9g`K?lFt)EJo814 z5wyUt0x@Vm$GI`z$t+a6RQu!2dN&X^>)@^ebC!3$6L7oDON9)!EE5B#TQ3KseX-BVG4-LQf9?pK(ckkgKZyXC0!xSptM&(|+dM-rP z*p_#uO-``->3jWLZjDEt@s*Z98ztNJ`M}=x*%10+Yc^sRTRO^teur%bBwW^y#OH-5 zOQ4WFiJ4OzFteqz^E-k@3;uovXh$Rweb7soeJA*pH2JVd>YKM|hXTC6=LAAJYZVG!H zkck#3@b1P>Cc{T*j-iwOjA7}u8wI0bKBnDa%G#mTy@$Mv!$t;yfw3_^7lkG8@C0=w1nB-yUccefm6B zZQ|*Jt@*v*jF)yL6>V)enC42AE1eoPv+tG_`ypm}E#O##p4HS98>}31_9&BNigQJS zi{$(c2|-{3@zM)WK-_OLo24ha{5!GJNM-d%g@tmdL83?6 z+v)S?&mSQWOeu8D47ZlEdJm!bYv%V$Jc|ZY@<-6f%C-5S%j}m24`NsfT4s?ARgKQ^ zF_iL_ampCfc~O5tZayF4C{3p)ArIn$hh3xwmUQ)Y&jX!`DpOugc*()q`T2PfIeCKX zmti3YtDhWM%Y%_u$ZTex*2E&%WCn)Sb5dG@VW{Ze$PMj&C-Fc}qvl^XwO2kE>;r(rk9{`U;w5Kj_`pS>?}Rsv(aZsn+W?5&dX@6(tdv5E3-b<&&a8yo3(g6 z7p%)yn1fN#G6f?wTdN$6DKSsIm!G?uVpK0-54U?uxG0B*2L>uw27GP)E@eX-!8hr- zdpGAJCvV=w;1YdU+&)NP>6%;-jwz?G%E~=A8BD=;`NY|NPOLIQ#Saj05_WY#q>xVHG;)HMcHH zxzH~8iOS!Rf4qsK72_}y@Ogo3?aEmd_-`i22NZbPzRSjqmR zJ}$57V3}1H^o}Ige%&NYz1s?@F>|TvtK(8kl?7-**GRbV30Cxj{O$DRbFk;-f0yi3 z>buQcAC0_$UNCb|&!{K`!p^Q zKUtcl(Oo=*_l2JZ2zwnbaN4#w18+?xt{H)siVd6jfXm{P&zJX&m+ek$+|A5ZO37C^ z_Jz++2?KtRVGpDHZ*Qc0$5jj2HSDnX$2If|WfxtKnHjxYgT4kdSH_?4HB8Ll8F85N zoq?PJ4|k*b`|%IhBQ}KHEporf%qa7VtI|LuKeBo*uLk>Yj|EpbTPI&yZ=ZrDgc|c5T%M&Sr4lLO5RvsF#B=i$cW9BB z6~Ep}Fh^oq>DHrIBl+mym$uD%PH)>s>wZ8RYwT3Hm0cDfnIf(BXV%BNIom3i-lJeQ zEfXP&D|(>VRyD*+qa5YHQf$cZdj&ho~(BsIY{K!0{R%k9Ad~yAMCS9=7E_m(F+P2nsHO}pszPN zhtwnR!U4Z9UGDZlY)9x`s@eQ`A4@uD3<)mTT%_QRAC`)@^0|Cx4f5QuAf4PObP;PA zdR5NB$r%$oRt15s#&3BTGe@PAhbA+^c0cO&ZSqT$_af&hdx0rOTCJf|Rmr0uRqffL zwIr#y)e3Y`fATP9_k7Umv+tT-{Mdk&-0Y!lU!hWYQGWW??!{8$;KsS)DHFE#dTRM1 z6vyV$jnxqfI`HjHIkEY=s_Ric%)0w+hR5h(IBn{6)_KsAlf^X%Z@?75ceH!yRRkm6 z41O9`+#n9Hl+vV$mxYwgUe<>)IQ`o1LS99t7{p($cqq+Fjn1h7xE**-os0)<3{s8I zpC^k>-`7LMA<|G(VGMVjBeo_SFufolbYeW3ifFxudqTj&YW5^U;Or)zS!|Bv%~pis zlYYmE^Q7rE&3F`}Zo#j_ozixNa%r=(H?HErop!Rq zx<~j@elEb9z0D8)nf->WL>zy@SH67Ru+yP1)|jQV&KKWJNwAvhnb~U;EZ7VtmLz{f z^}p{=|M}#oO8Oy9IOk+jyHr6#IC0#-Rnw*&bp+~qURp7iS22~=O`~fg%avLw*tH@; zHM;1rTTsiDP|$pu7l{+QT;mhP!Q~GuWPo<0XzH)*FwL$&D($rm8g8Edo_Vq9AiyMn z-TG`KOSemM&KF5iZPIjB&9gIJveuq*PD8f3xv_)3FSsF(Y(O7&sDs%aXEQ&YIOsON zH(X*)oZPZ$R7;O4w4p&&JgLuh+POoD^MAbnoPu36b9sA=Y8?D5rS$kYNQ8lRrJ45l zN1__>{I%rY4BPCLl$V=lel!LyyWJtfFM%0NtobkEbA(gGYx4hm`hMmKe!UWHgV))f zO;U>X!Ms1W8aUL-81v~5P~Dh}6l&VS!~kV9Z{O_}NA5JH{ctrLI)T0f&L*pNjJnRm z^t3RUZi_?HEn>dy2@2tq@#GQYtPD6p|lxEScf>sT(U!Kzm@mBsq zfKUFd;=EL#0@}H7z|A5mCVk3_PQQgK#mq5zR|TayJC3@6DnP7AiT%p+>`<}r9Wi}* z{RN2PYva8zYwgS8BSoup%Fb8lqs32jOSWhD5f95r^A5i}M5JExafy=*)4!^ANZFh2 z*cMfp@4+5RM$^<4=$SYH6EXw9Wr&laogZ7jO9eN15Em-9dcIq(&Un#_HO%85`1pk& z2Vab;;&KG}X36Zuv+hD4;FpS>9vnV0e4^q?rLWItwMS^PIHF-p6|Y(!bU!F(PgOPM zva`2uo$z-tO?sryh7NK*nvL#scudCJ@3E5ep@EC!j!Y~;hPYi=2h(CuA3LEVA`x#= zXl3a-qLml_@~o>9DBWtY#7)xiKah%!7N;jhnn`sPVHhD6e%3@2vu2Gp( zE>7MsT~Obx$#)2S0r)dXzpULt{zRnhy=3T3xW8UNN}N?THaMgIlgGN`3(+qPtWYt+ z*YdtEC81OszrVmp@JUO-(W9ZNfXBM;Pq{qSOwdXAY?b#U0oxRom#-oRsn-<&#Lhn| zi%x&*A^Kp zC5*VV>^=bpV+vhXy3OrUSyuGSSMfE1Vmj!l3M!8~FKDO7os?}Bo#L!oY)~77lVuKl z#8b3)n-zZ3S~I=E)+Rut?t}2^Q!X34q`XPxSNe$Mpj}F>t+E}2gMp*V>ERQkaE}(pYL(kVUYe`z;&Lw3G<`3(wK-}DRSvh*BAAk$6dO7h z`Zsu&p-WI9Py1WcRfW44^fPOQzEoqMeYb4#%TB^=_LWa5@qTEPWNVgynay=E4+^Dw zl-PhVSus>USLi!ey*v*yz-!evGO~Cqa=tl|U2LF5gxEf(&y7;NNiaa0oou{D`eoH_ zDiE6E%%dF38G&)y+cU_GK!e@k*W~30<>^5Mnq^mFF=X*W_gVXonpXKp)Qq%oTyt|d zs|k%gi_~EKfE#i!As)+o_oT-IJGGsQKE6N9=SvBi?Q^D0K7tveo0`XfY5N{ZMtPAe z$o+fis2zEGgFH6Sg#46^LAUO!dLz#y@hOYYN9d$HXRX#)A*40UkOjT2u~Cb)5mA$0 zp08z!GAx`v6*=@t#iOjc;}vT=r*q`xQac`WkYVkCgT|?K>5pBP&MLPC)v?&#lYDEi z=|{cDLW{&kaVIpn_2<{I61qb?+w|#fka2cI}h3Do>D34Dy_!Tm;(Bpr+RvNxKOYOSH6zSJ*a)w z?)Eb`y%-LtUQ4MW!9z5Aw1(TWlz1w`1|rg@BxQ44cNaB$;JnMgtLTG`XQ{J{S3~B9 zQ2~(A^S$nH4f2Gb#oR797I`{8A@E>IxJ?%iX-t_Msfhqyet-Z`Qsv(HBg3kwomi<` z%Glo5b*~eatnCGvc)Fvqrs6vQU+q|Z<vKGh+dQb_3!@qrNLn^6_xmdqgOnWQ#mFetC z)aCyAjAoFu+7mT4w33A{Wm-(LfRW?k4{17ae7*Ee8>z(Fvy)EIAA_C=VJ0zb2($+a zm_hH@=!Bt{X|)D)L9d$ic+ZC05vA+ZGBv`DVPTpQPM0+*Tg@8Zx`FabJoZ*=j2fTH zN#AMe=!HImwis~nxX3r;@P4EQ11qAb3@YPxzFmEPqiy2OUX761VmJxD2b*0Ca{dkPV5N zFPb0KXYW@RhU}Id^hy(xwNquO+~tjv$`kI707$s4&P5hgK}xyXLzo26W57$3e>VWNBPUk;QQbs8t)-x;WXKI`q->1f$)$%F_Ftr;8@$Pq z`<0P7Tfh2N!Btu!U~g*%izCrdkE8){PNbT}RA6!c597%^QGMXioaLJC#Juc~6PA|4 zmgz-%8)`qJWCScK{7_ssRK#~3S1*!wG}Tnr+Jk(^V?8A$xJ2qHyb%oe!CT%|UD!!? zSI&3T>OISFbhIkH5I<$4Di8?#wCAjijxh=4n}U_ssjxHJG|YYbC@xzW>6`1Lbu6*b zeD*~7dCg;&Yt#|<1amAJTC8e+HvHLqeemi^9G`Y+14G(CstS+Esh$|OWJ6k4nx*812y`?xp_zZsVyp(+OsPO7rhBmP8MPLLqdBE= zwJkKEd8UZ0)<#j(n!Y@}S~9+0Q)AIl@%C3ZTU6s%^Lsa%pz{7)WU)ulDC=w))D5Fu zg&3Wm1m%s5@rkGarGYIFN82AMz}xlEus+lgJ0V=>xzc#K;@F?+%tIXN z0GiijpPE1Tkr!tcN`nj>3>depK_h1%gCS}Q>mgK7%}2)0qiFZ9whqaDe?iMYVx%Nk)i zN|=&5v|FscU+4J#Wh}FXn8QM|Kb1%~j<6}P#4RVWHdpb%f?818>D{gq87~Rym|t~7 z;WHD;vvaB*i1V~zq6aC|<_D}-4^0P|@k8(EZKT9eq$Y^E_I|q=UcsnApg~P}SFDhd zRo7yY{H)qCMH8EQu8GqfIi1e!zNe&1w{PapUX}0MD%MNb=rTHcX`93}j`|*Fl|yD{ zYuhmpSdCH3qm9Mn$IIfS2`5a&>2Tei@)W_d#zmO;O7C^quY>BsrSB|{<@m+TA20rJ z3Z>njQ-xS@lcP+|#vB0Tx0PQWCId{GLZ zLR;~!S8G4L56!>5aWvO&wHjPW!ccG0J_;ABuPn2ZgMQpE@FgFI6rC7$!zr&d%+W3p z2yAQhQ7;bu&|=TA(dTMEe11RLiL2c@A}RGB`HTU{!FIns(I!}74OTgqSo}QogcIyV~35!@h|lPWgbMbEE)G< zgFbCWa=W|bCSyv%g5kF}*vWO~+WS}UG3t|T_3szCQW3u)}v|12tZ|yDX`NCB3dA;1N zmPcpGzV#kwRSxmmf#vApPcaS((_@=9Mrre>^@RBO`QSV_cu4B;45D>Z3Y4pIJ%oOO zf0@;+&Rc%&hme|RIMj62->9W+@(xLLPU^!{eihksLa95&Y1Pg^nTv>c5T@$+{dk%brya_S|zR7jNY;P;9ri86J= z9sn~0tov266fX z?<0k=xuSAe57i{q0JS`YB~iOx0Ngu&5vLa%%RL_s5=ZZxiV9T$4z7hug(ef?Bf`zzZr1= zfq57KL?ZmB#060axg5F&0IBYp6wz#ze`ON9?l#wT@y&fNfoS}5nIk|}IZv`Pl#MkHw#^Tpsb+HNZCAemb;Mq}=J(EOi24S9TIn%~S# z&Ks|Kk4oI98CzNV4M^EtF(OO)#xFbvi_6HlqQtIcvTtTZ3VksScV_OIqsLmAuUICc z3N~z?JJR^Q$k(uj;tF!HjD~-y4pz_IL(dhCX6lG_{d`}vq~VZ za{t&fD3XNxH5Ylge@N8Bx^U8+s7aWP(JK`&29*|5bTLd$EKaXt6RP)7Z@ z0#?p4C!PBG_g}V?grGV2jU=fr_v`0>5hyRoZx;jn+pFPQ?~D{1FHu=J{m?+6VQ*85 zz`px2&*j2c1Ys>bxG5=i4z){?zwPQzu+#Ce^Pzn~%6)5)5GCv_JpJt->dwij;PHgLLI}! zx*PzHkoTWY&Mf)CE&QT#slBDv$pKN7g#jJ2S^a$RrN3NOf8zPCgt%#}Q`&AnDyEOg znsbw7iiAAemEnytjM6Jqj_U>ygO|k>oD8qr*UrVt;ETc^J98TzJ%fp>9T*(v0+bx} zDpRI<$ad#`;?B0lE^}a0zBIOL-J8M&+2|`kBh5B?DWI--d%^ajy1L>QM|l4%?*A^E zcN-PH2t2jnJGFu}xGMKMmiTJ~HL*lx&BRWAj>#&CYpFB$(WBdAkHGWg@;Ox5PMxfE zAw=75H=eqOJ={3xCst}-E;>cR=my!jnhC#V&C|!hbG^4elqb67C=r!F%u4|z9pLag zenM$`7Oo&ga)P@T-`eEPXD#TK#p7SkTWDZ+POU>jNu`Iskb^G;=kvEW!A zEv`rPr{tH%kCQ`7FLgdUn^NqR0wxdQiCMX^Zr)tJ#mUdNcJPBQ9FdS;|ecaP0J^^k7L1}LcK>O#`whF%}^kx1{) zF(SM^N<#UGL0A&Uh_wh0EQ1C8*dWLBZ2~aiEa{V4?BcRt5+3rO`UHWM=M9sF!7Y< zvDJKOLT0gZe_)*8djm12xskWxYcRF>x(OtThgZ#5!6+&9O!%+m%zKXdBIp?1-h_BC^_XgZo->^)Qn-|{rVJ`x z&PoZKNkR;*0zbCNzz{StdTKnByzv>fJ@Qg19CIEl5imSjw0b`PwNHs88j}qbKO3_% zdxSj|XML-al}l_?j|>szQ^I}#86NOa-i`w^OfA95B#EaE# zke*g`DyWKu{E@t8T0~1FQjp=}0kxagXl@8B6yCjbuic0fOonbMrob7Fj7C9`BH1A4!XCCBXCVzY+QmWi560B|WlJ*EEd?;8R%3?ba`8L-`)7Lmy@Bee) z44BKL zyu&NC3JeyAGi1pg6Q9zb99FexH(~At$MzNf6<#n8+KH+f^|H1G6TF&pY_$zYH zOm8hJX$DpYIV#u<{R%MZ1tJ2y7(t*4O@tl{p1 zEiD}%AIA=X9c+dVUPsWHe0~JUF*Va{1~`}tXAi-KL>Z1|PBM)!qSQM=*#y0MA}@N< z*Gw4Mu1%kPL-d!KwEs{2{42Uz;r`p0Ga&fnG}IN+cXzT=ho96Sc7rDo&yMJWMs(-6 zs5n5I7e{~mTR@=ig_rX)eJ`cO(ZK+bxK+&1Jz&Ms@&O&Y3-p6P+PlJcYM`+TPZ6iA zA?Bmey4>YD`YCrFKhp;aiHje#Wcv&W9jvpOp3RxAKG24C8~xnKBd8LQ?WI}_{`Q|Q zl==ksO6TH?!vPnvJ}KVPh>7b%xV_Y>;b z2GPt?`&HSWdKv`sAJf|3nELG2_6WzW3G(-7OvR2SW@k7KKUOFi0kXmiOfcaNfS;ER z%n~Gkl0tgRTs!rj@ycTlUT0(#1ZUkwZtKS`zBe>3ir|htQ$lCxDy58p2oR2C!?^QA zy~P0U4+9atJzH<>EDzUE7W()NMWR6#5ocA~vLeJ5!kcABLIQjH5fKs83KWn3wa@h1 z>MoZ}M2{q*WArnY5bV&WD3LhJ93 zW`<;W4gzl*iz`ZDydpGXFALQ}wVsmgG!Nf^!mb9(TQ5Ez{N)NYtMXaiyUQymRPvvt zhejzADS?%v14Rt`o!)UecjZ2`;ZshEjP=Zaxm;yU9Sl?st&0XNJcyi%6Np0Oj3bwv zo+kG!yEB+JiAQ)OuX_U1q&QpIJ80R30n8r?@r#|X+KYEviFwl_-_8q1MSj7#`{fB! z_=G!lQ)ibOwS4Pe09}MP>ghJ7Mw)GhWpaMOWd2d= z{XvBGVXj4TP*Yr7ecy>b6b(#s_$)cbCW#ixEPT`vpO#RnG>kd&V1sK>ud7+C9gTTV zq$3ljydjO~;?X|$X|@G73>UU%JY}uaiXJeOUv{S^586&eCN0*KsU&Y4SsSE<$HH0D zEp!jXB;tV7`Ay!cgXu>ioEvsD^&CBkE7NunFZ9?}3pE89D%iX-V7P>z0hyWM_tO!q zdJR~Z%*=~F@QR@P^W4gVGf3YhF+@<*GFC7f)}OI5-sipIzX|N#FC4%_y6`v#UUgnr z=CzcPnEf%aM3%fNC%_=sncLzoaT*ZCU>~SjR0{ z(#gr*{QTlQ)c`imG>$jwy@e4Z}!lXnHSa zFB}bMaoTIl^pP$JF_W{SKse55y(DgZyGyk|Ih@~r8F=Lo*E7w%DsOrqYaMS>RMInK zCj@Ti(?3WYuCe!HWH_~f@n1`u)2oHv%3WjBatB#=AA4o3@G_K%{b#-J;nETPM<<-| zW(i9X<720$+gBdws3yK~{3Vvx*In1a(Hu;nAQBlUz`Q8LKmAl=#-f?XFKNz$ue$uf zgL={m**fgIS_~H1O0(DpQoPt z3ZnX$oll&#_hn)Vxov@?*N^>gRbNX_S)X!|G&mBFKP=YTJh2}4q5+>ioT-un!?(9< z=g4SjJ?9T(AT^6A6yF5yQmAD{_mD08ej6bJFc8A1(%~+hJBIL6Lg7f z<%;5yRI7{neB*y_mbY8vQyVU)(1AvDwl90f#3Z+I)J7m*>I$2I@U6+uU+$`Qvs&Ms zV%&JjO*xR0lEb+}g}~P|HVL_p6hwFHozuV4!*I1&+cSNHzVoGCX-`B23X_wx=-)H0 zvDQ5?Z>K7*7?_^Rk7Rqi{;!;HB*_8pQ59EswPjPDz-+^0pwO#(a(Jh|?fiQwS3p4$ z&XeJK7nZwCc}IZP6_cQZiG46D+zIQb*gJNwfC)otBz?BPZS&#uOXVX4`kmdX`)8gc z+ZA7p#1K5Y2I`CtX~raVMrt>!!wsj>M1${f_q#U$uEm4>zUBfYht5XT{3`wWC7<=1 zHIH{gUzv^)=GsgZIjt9sQnNo5dMYJ+*_{R8_DV%A{??%yS2;D98n-0>l~9Y{nCH9u z>ot@CUwMj@AA9IazWJ*cz`H6K$$hi*lwfD;j{Aca*1k8>yNw;<3a7lLK)#BjAS<)> z_SeG>Rd;%oR76eLi2N+s; zbB?_P=`MilVzgMY%WU;wdDdWO#1Th=q{t%^8ZLGP18O1&OdN{%oIvbHp{9>@`L6Pa zYvx;Uv$m%FF{|nZ-EXkg_SxNLVvI_CAKy8oj5N%Hj5b$QU_eArtUfbga8(43$nz#j zKA9R{yCr0>q_;X^#QDM zf8LRE$*106Uh4-hyfjNTjU&z?U5_87h_di9%fFP$IP}=oZ`q36B_rb(+z8*ZL zf)2q+Yau$kqN@L+{=r<@pH`D$IKwIBOSdrm1tAfgIOHhj!*3}S+XDx%sh!sPJoi@6 zT#$!G)oR-*=an!O*3cICmhiXIwWl3KK zPp^9tNq0$=UMR7_Z>}3_pn4O)3mTf5505~9LqR^-cwc6lJWvtEz!#$yr-}rRv&*sx z_|-&q;px8P`wk8UK|v_H!<^NK4!u}&JS*TT>2R?NL0ivY)(WD(bCe_h{(w{&Yves) z=tV12Xf$1lFdcu!(k|_x5?d;YdBw4qeqS&0>RJ?D@stHBF(GrAh~W5s!*Oe{n@A-` zy_?&k59NFn1$?^L;p(Hb{b%Gp#{tn6EY&n(S#QlE{Ot9q%49`PQ?VP5LV%_Npac8} zjAaP^OCOOTb~opaP(yWfKsP;COm^z&&kpyO5fb3ZvJ#DHsf`YDoe_Q1vOc$2x0R8N zV(dyo*8q~8%eYjLi>jK?;(jTeE$2mzMgf_%Wle}Et6xz3)J6jFhi>mo_3%~{%-`~*HfCKcyi>!`f)u=6_oi42#F%h|0mMZ~vPX`;p+;(T;$yYopi4AAZ ze?7wfI&{PvKv&xSK2<64UC)R+YI%FV8vAg9%bv96DBcVEToSSKDcV$-MMbvaRA&zG z`|jN^4g_{66lLOl*nN|JbId}CQc)$cw6t`yUuX`wCjvFGlVHtjCXHL>NeQ7M|Id%Owb(xC-$d1z0 zpHV!?Hk$8gq+e956)I=3OPEbYr*?Z_g?Xn~pzZVOk%=nj6eKc5=TJ;4-(K0keQ1o| zo;rTI22}68XCs6htFqWtMI+W?98Bo$kW6`WzP%F*q=`jZQTUeTh;*li*njd~(bp`g zIuze#QL<8XR(2wyPLxssgk#5BJ;-}k=Z4%X;k{}0O0Dp>Bl3OzSTz9)0DsHt*dc3-*RYoSa7JW29f zt9}LQNUFCPQ?WggWm9#8l#vZnaYKkgG;!GYlLP@R2KNgmYxr8D(J^ch+)!4nGE94a zqqODbG=F4otYGZAG|OI#1upV;o}j#_K4lT7ex6UvT7kYC*|F+q5ZpOb&0!q56!M;H z-?{QUzmxal+q2Iw&;XR#BKTvUtKK1L#4GWwLH%WlL#lE!y+6EwU1wU-m>^VF2bN*N z<{?kWU%V4la%>9CJ`R2*erl!bp$TgJ(dD_m092}p z{n^>>?rc3icrz52)^h$K!an(vBj6Di07Rj)!tYNrWp|3G+F~v0N%txO? zsq`&QTwhG>mK8@i1Ym7-!}#bd>^H?S-+VbqwF*Vk>mp59!_DR%Vw97~JENRm(6VB_ z{Q=7$E&>QZO;_%qmg^}yRO$Fo4(u`bk1KN}G{qBSC9yHxFTv_Pq*H!5l}t=JoaZ-% zxy9*6TC*N$L&}DcV|?1nZ2H<)5Kn`A^p9zW4bP^+e52{As~WX6DxFFGA@cfD{>ci{ zw}~kSfR^i$%5B(@344T9%M?X#)=t^x;|LA-dz$(kDaz~jv5+o-z{=!F&qgEDSM|P( z*QIlHouFP|kp90F*=Ho5zP+hD zD{67%qA(e|!PF=n%5IyNPPe{4e+@BSd8(U=7CPUpIO>@x({m4{q#TXwyV)VuEc42| zl4Ip8VV5jWUe|p;tlii8BI@gWelYl81>eS;d`(ZRD#~U9%zfwz+!n~gh-Pxx%qUK~ zHQPH#ebk-sp#kgEz8b}H(;2q}2bU|iXL;AP>XxmBgKZb zEbUJ1c`|hKXE(tU&o4m}0^$@YUAEHl?WH%CYIQ#yXLwIs>*muFuQGyA7Qmp_Bgp(zjM&+P{-hd^%B|oCXh_x;A$_?YV(-Xa)M`T?0Z6Y#u`E)!|f)#nv z__$?9?HA#HAL2{RFWNd{Uf23hOki7CF-P?^sxqv5k&_WS#i}8cmkWgE^kuc{ zdOPLSf(x-GT2F#6c81G-vCR?MNNjbscWRaB)~?ewIU@`E0bj@6XW39amun@L3YXp@&vD+}`5+uDdT!PQG9lXi1@ zNO~UiaQ5UIvvw)IH=o+7w`%T+{_GS~$fL8o{+{+4G{OFWC=ad62>^v6R*hx-}5d`hV#uAqj#L1nzdo=ie z=z8n0rvLx#+rlCgDQOky?gkYB>FyF?BGNHnqyQkigzT)&pS!$<$a0NhkfoX$+0-qZ z{Ufj7oQGOW*z&!4m+D*`hv7riqtD5f=3<>1yc9ILa@He8lG6p3`8I(I1F~pUZ zmp?m{Ki@;i*4sS`)OL~{Maj&jnY9{RM4xQ~CI}G_r(&i~Tu%lY3xOgLI9h^?P5 zM$wBa)%D31)GsMR3p|bXawpyyho0&?^tIsi9`s~!;fyytG7(a*=R-vC;NXb*LPX7) z`FLSXlQ|$D(F`cfk)CMPt@5p4>9GHM^Y;Zh*-*KGtoruaQT}hcv$cxg~PCO zMTZZ#pV%)IVbbt|4T6^2@6Ht5GFn&cRMTUFa?eL;=NXmm2$=sf0gU>4Gpi&(r1!}6 zF}cL3?PrClWmjVg4z`CJ&0Fusu0E2f8tC~FEN6OR{6%5F$+&THvDY{Jp50+0{D%#F z+V|JI(Y>-{5w*;1hIW*vzz3ymEB$UJsM3qLkst1k{jUKX zb$Zze6YgYqWKSbSgyyaX!p2>OH{3unfoNuc8X4APxf1v!Dq0oj9dh_@XY}lhxdnQd zi|w4L)Ja#M_M2s+yW>MpLXau{qNGHE{X*adsv}w95kcwQ)+66LJPVrh6e1 z(VN95n-#_^T&+_MG@N`9VQ<#oYI+(v3?Fy59%@vGqu;lBn@|T-stng{EH;n#Ew^xA z+$spGm3wOusW$m-NB5$QkJl_ajs5Sa(VXW7%!RU@*lwrgbhaR2M}NPf+OgB}(aIef zzhrQjx6Wy)8dRjk*QeP_onN&&R4Nyyl|!ez9k%cQM54k^$32r+_TI{pARUnL7tA8N@y$T<~CfleFr19z!mi9Vw zc|;P#ZfrU*;TVVo^+L+KK0Gpy8tc;Yxt3n0|DDF7$nlHVX!bUN*@(Pfd1oPrO^&F~ z?mnr{>Jc1{lb&xdwV6r6L3$epDPp|dY5sNl;ccBxI?h4Ld^v- z&L;j(p*&1%nJI&v@8?XkBc-)`h--nB70Zp~9VofFata=O%0eRhs=qy|uf!{l;J$UF z^`yO017r*gqd=&JVo>;=w}M}8xdF$dgL-H9rW(lIVYjbavfCqAN6svEY`TcDo>qESlWU9WcdIEH%=qcPpl`VEEYERq7E2 z!hF}2`F%TnXC<%*ErMNVb8a>O;Wo;+aC^|&VPXD#>55Wb@OnvxRGTJXZHpXPX_mpJ zL(PYkWrl=<5Ll6&asl{`y`y!0(L*~C_@I5;AAL_fLPTX=w)M0Q2fna zKe6+6?F*-$(#u!~c#XwEa^R1|+VyaY0b8cpLKszjEb$c?%*p3vmvJ~Yk64$^>K8?! zgPNL}AGE}3PYdB{Pp_*!wgVqyBE^C^0BMGuWKYl=Cn?3Hb2OonM(EndxaHWuSf-pi(Z-$^)SZM zv`zgjN@Ox14lL$m)_yc+bl9pQy9S^y=SAB# zmhGrhi%T~Qc1y{Ue`bN0)*cN_G@5AFccu&R*0Q;RZ7|DwC~U26Jwo-Frr^gt>FmhG8#HO)ckvb=Qe&GycREdS@h;i__H7sjpl))v`S z$}8}_dA>WBW_LZ(zs$0v&@D_JcIcu*&Y*bhuk;U?4X@I2b2unoBl-(z`5Pk`C_bVd zt~`t&_^SLUR)fgd8<1HdiYmV=*xX5{KFv$di{x}PWLijy*I?T*I5lM z+~I{18_&(QOP4oCYPDv!pvH>84?y$aqvi$L>c)o-mO$lUbaG&s+m#jSj1|G6a(kJX zaS6PkP2|WMS`Y1T`iY0#y~}Qi&vVn{4q3C<7RF7;JFIi(Vahq)RJlm1bmkAYm^<0C``@HoG`I>)7< zQigKXhYM^8Xvo&S>d4*y>DRcEr75dPUy7g$gE0H2Y(wdA( zlO>U;W$*U%hS@V`7nD0^5MMXs`N+*{>xcIE0FSIXe|A~-W^+rvZovMGkogw4UU$uM zzR0NJ%R;__@Qx(Fq%P_lEt)hfQ_m96)_RkAMtoRc8^VC9?p!0Gzlh|XTRv5>=BZjr z7P$xXsp+DAGn?&s8kahSG4>vx%?{diOw^AqO_%r;r<<(Fx)?r2UCza>oy@Og#Kl~b zyL%2OKt2jz8f(+tdcdIMpMT^K6&i$!>ZYo<4|H~prayD6s}oD4tn_dWh0KvHL$V;B zZvOl9|7WKP+)4QOMn^0*)&*uJjLl$8g*7=M6$vp3(VrM_1_#;%QD&T00(FysSpHe| z%OJxu7gLu&7Fw65E;?0p=7w}hi*VLc?%*JHU*%nXOqE_X;JfL&Glx^3#5R?bzLz9? z(@t`MCydxj1|j0HI`CrS)9#ULieF_TG$tR*$``)Csgz9&ZCI zHYfsp(vk)+U{gEGEFXT`gaKYP4|xkaS}l2$c~BLO1EM;n%!+W`ua{cTgs)y8rIZtyqeUV2gqjd>t6-@8pqIU%YV$= zh;Qf(G_Fp+YJRLrhrWw+Kv^Zv(63%UVYa2kvM7#kaFJyC8dY&nVH z%*sgDex8;2c_vL#2yGVgK45^?#!|)lp1wvgHlB@~4fFF_GCBI?iQP(f|yY1m_xXc}?f}qd!ZJ z|8ff!#G{yquC>1SprY({yZrc;p>Ca0P|NoLiqJluqtveg1GO(0?z*PTW0E>Ws4YGH zoK47XZ%j~>~{lO#qN`N;+%qPY(BI1zZHpHTBBEW<#=adFrxsWtQjL}V}D(m z=L(U@u#UbhONfv^efi;dz2HtvcqV=FArj5K1B~2nomY5B4$Et7w2g*{Wb_ea z8YQg0u;ZBpQ921kt9~?&{SF0(+gxmR=n2j)05YLXqz* zW+T;Fq>!sc_DOn1MhGp5iuh{KDrM?Hf(PT8!t)txthA-0;XBx~u!~?J9f8`xw=w^h z1>jc#n4n*BT$);EJyn#9VxJIgZ903lE+gupjMxjlmVvLn+b7Zc5F~sN-jIQFVAa2| z_~VoOU004ax0XMtW77gpF6g-03m{}p=8Ck=_V!^AO+Aq7#?|6F3;2-!bg&vEgZi&z z;D3d}9QoS`6`hDN#Cv8KP{C1IY-WvF9yEu@Z(pRw5%)l`fg26g`ubJsX&5>_; z`xm6DTw&zrWxuoQ4|=(dW5W5v@CXEHu*>?Vsmn@#zEIhuOMQ18%MKw%nsh>dJ8R>{ zJ)@saR(yQ(`jcv2J4?l=G9k)*(bD6Q9);vBZMIsCW z4ig$9*xs`wlwH9#rtnr{~-q!uhOnQt?Tb-XF&()`QV+-G((eqCUv>E=kFi;-Id5~G}ZTI2M;*hgnC|tU!{O^L|VHZBxf~K;}g~{rHfR3 zM>;3RJ7>3B>XFJfL-Ymmx{z-+ACCa|#ok$iAO%{@oG*WG?1ulQ_F=(@2f)tb#fLla zEV5w9`wN+AX`szhozcr3DL)P>Z2w~Eze2={QjQjL%w zbqc<&F)HSn?`&vqRJYh(u0r~D$z;`rEDO!Xrp$9dP%&aUv>nn{jBfJG!-P$fv#}bB zjV}qcm5MZWiX<;J5n|&*%2p4!GNIaXH;kP5-PLX=zRc3>6}kKbs5QS;mx`!AXr~I` zkcZ!l!f$TOsArwpUwGANW+BCv1YIah0g8&O7R!P?v%MZ)v5K@`uik`ZajGuOQmvO1 zFQ&pF{a7!nwie{ireGpsrt4^Su{i! z;nV)4GMiEt@t0_U(y}E#QuPj+{js0>5Sktyc`S3i8$Ngse_5yz!7RG%;xLHyI{OY! zi=kpld_b3ee%O1ey`Iex32L&3h&lXe21zsmzU^}Q0oQ%(xe2suJah0q_j$BFdL*yM zs?<`RSD*@lh$fSs@>%zcXLT|PkC_(%^{F+_&_MmCu#o{xy8|l*~ zaWKu*LRf2(-E?L{S-89t^AeXFfNDrXc(tBa3Ol)&vahq7c+W(8Em0O{Oa{C{;g0m= zLXox-RaSKt^n^2!%B7VLt*Y=CJ39U;) zwkD#NM2seZ!j@9?%YO+54jPSm+e`Mh zxp&+2{Vg3vMGtydlSTPYtGw&@ln!KrUBWd72z89Lk}YbJ=x|_xrAhj+=#&AN{Z_D$ zavfY^ZEOi%ZjO}6O!;D;_%xpYmZ?z>D_xXhiF0s(%%*N>ew&ZiQu9h-4> zXU>ylXc*@k0PV~p;BoL>ko-*<%8xSr{oFgh;GR*$keYayEMGC9h@~y;L=sAj=~~=< za)wZ8>K!4y^0{_>frhDIM!qU;r^99~#H^N{ZbO8{MSYNkG*6xnxGr$J#Bq zV7(-=^svQFBM@kq(Lk9he_1!oIiC|Y%*{PHDPkR9U`&`7*ok3f=D8f=a?)hN$*Ic- zmJE7796ijfsFQX2ae57G+warJYx zGA=zV+^xCMPefJiIGTSfU0&MDb-;Vu!vm{!0b}F~VQy}2$FaG%#3_|RH1&>rzgGWc zzE2I8G_RJ_t?Rv=pStcEHpIfbqIaVtk=}V63zz9#4tZz?z8^Ua74L;XCgHC19Gyb| zfG_Ne&4P!yonx+N&+ZB$3ja@^{-23@{_$eHo9Rhw{mfrE0u42_Qk@s$WY&RA1$|H< z`02#bMe#(fo~c?MWnbYR&!|ZA3AjuBf^7hdV?n-*C&|D1?qU3I;))3D%Ui(K9b&bY zdsdZrScsUX+M&toUmF}gU3TVoI2OYCqlB_FQNEmI@lcDZ_Ry8g{@)3QPdC0h=*6F; z{~7OnZY=wf2Xb-P}=fUpoE|$?I>Rql)=j^4e=gf zcf19tv!F09cfZV?hKE%v{f*_CpaQU22r7rn%$a<0ssqC9mlT|r0*?@<%dRE~waMTd zb`h0}!j*$fj~hj9p1-)D*czbbf2IQeItGzN)G`WyeW^sP7L*9m@-f);Vfh!o#4Ib8 zGw{t_#zyBZkSzL3lk=(3CK57(edbu2JOBKo4}qPY@Pp@nH_(jNjPEPx+$H9xfAba} zTu&u-M_%B*l;`9(S`|duKWq$C=uHnUzEcX64RB zy^zz&fAc2W?AYNw&2C|AEcu!sPImzvc=Ttf4Ui}0-e&*#Zxi>Q)!;D8H7Jj0!K9{A zfulf?=+nFJ@2&2TPn?jKNz3FSnoXfz2XvG;+1X{A?9)UaV|oP>W{>_$!;ym8?M!{S zk*Wm)xrwDF26!3wY7LX-WKTGCv{Xi53gy#(>(0gNFCH-(9kuc=)3Hbd%_pI?Q;b>~ zL_?~vVah7yuDWz9iX4&V>ReZew$tfss_%!AQzR@6pFPZD8`Bz&fNa^Q*zD5pC(04% zOmdG7D;sxR{t3oIe+#oUVtY7g{j^|)wNh!HCdu8_Y{9+q#qkKIl2S7?G!#mQBX)3&+bzMf_4p~n0I}+V zkJB;~Ig{Kl>9479r}AC)>aNI8+;6oZi?(FPEaw1V?cr6ETPrCpZsf=SC{?laTuH^t z${9GBxLDSddnRP*Z_CL^|1&)O{lEZvS=-45H*l0arpQToXZxM3WCeIN`7RKja84E6 zI~;=`*8?S!St^`#g`f$&M-4qr)@4=4-!FHs{r!1MxtcXUtApk7X)TGj!n!%xsriNY z^63jEoJVlir!LC~->nqg&>@xsmP)>z+dm%g#KWMqoY|Q1-SlGm8BOPfB(Jmiy4=~n z_D<;=cxXjqdB$uUR`R@H=J~k+Sh96itl4}4Bdi3N4Ei9Hr`QzTy~21a=jd=!Y!uVgxM%o?dEO z!x=0ixGX>Enz9cY7l1MjEaw5ArYV0`6Xp1EB{P#kt33}*EWAqeVA*JLVxj>=%8zcB z<>Ju&rwQYD-Vv(FY7+a8M5p8Q_Pgbp!Z3=oV`DNu-jPm;cmSTtGk3>|f>B>e)rsMy zO~5ALricBN!jpTyvCPc7MK_857rd+dD78-K=CPx|A9@3sbT(7WSeU`|(?NSqtHkoa zLM#|nBvWApHX6Xt$BOf9HqSTZAAM=NI&pqPojwm3Zu5kHLEGbSlZOG=+p;UnaiWP8q0!*X~N_B|4vAa}Snlp`*M;x{-Zw8;H>Jyof9V;@1aym=vblIPME94&Imb5Tn z3jXI`(e&*0pY*JYwG;1!I-+3s%>#*uNq)*TDl&L7QIsf0zZ1s@zYit8?oz6>COEle zJM54GBOljy!eK*V7r@j#c9J+(|AS%187tD4u4|ifrHN0T{ZcjH*u;iFT!_-*?k)rh z7~sqmm?C$QFW&n9*6$kkpOsYjc&SsAUgurR7Fv(%tDU;8!)9RY-T8*0otL97YW?+D z2%EieR5~o+^q{i5+V$1Y)8Y7f*@2k}+o)L&g;4sNGA;0)wIbM1udoSA#q1p|(@Fs2 zSGp4>y>)`pyuFbpsc;f9c{?J`OA+m;jm}RI;C2pfs^eJ_GFOpS3mBaBr(P-kIBh=; zp{{BF>a=`mcM^2?oZCLz4TxtUVB<5TM zWp#b*4nNbYUorb>hnFwqTchQ`*L>97Q>#NX%Yyd(E?!L6UMlnHB^eo572NvYj|8CL zkX$=9joL?#PE1fc{1V*Klb22Ch_1RhA~cd|HWR0$8LSu7-T zwbiMA(PH{|CY|X|oCp6K1-Wl0oNG#xn)*bM)+O6DP2*mYZ%hBoUd`Tkg3o|c?znNS zXHwh?|CNt_*!FreO)7F$Dg$SKl71r_$zi;n_D7$(sA>aS$uUw`I|5TQUg0<$&R}0j zYdB`~KBNEVllTOvidkR36adod2KhI!KsVgtOua)(nyd9Mkbjg9%uoXxmSQQgz35pp|Gfu)D%zw`~6)lx9{ti+$#9%0pIl&mZZX>DD0VP~&sxl<)*{{o0`4;hs! zK~3jJ+iF)X*J=@`&^6Paz0LFD$hD@&X zPYC*`(+aNa``_8*@rpT)0dP8JV~25N)Aj|!BO_C@i+jgii0FxG4w`DCjrv?rHJ@!& z8hDrZxIG->FaUWX8DYvif>1qfn}9RhYe-erjbMUUAk1MgU_pnswm+~4=qw&Nkv=R; zb?WD!QQYDb-ED-O*)_4`V&O-9Vdu319A>V&SXwc8H_Nn^X4QHkUlE|OMg~P(^ZQ`E zcBKA5rK*dmT?;-*PbodgY4VnBI(tPQUIPX5vPL=>P539-1?m-x=Ni8=eI9k))j0`0epp9_CCY`_AO_@mcdvc3mQ!9XFu_*vn@o&F@}#@*SEL`l{f>eXFc zyhL?}1ImwwRSk@zRz~T$T}OEtUv>ZBM7z&Cnu>o#RvMZhKXT(0nS+oXUOmth#`;m@ z$G}sv3pRgN14b29oLn4a_`waZHBt2JLyj(!tDjs*EqjpFEF%&L81B;-EfHS^LPsZ2 zzq^5en0u+0^$dGl#J-g_v5t1+XhTTG>`pcAKHQ-ZRdVIt4Hjc>Iv<8#O38$~aNVh|d&U7_4`bJsDo>ttg8R+8H!T~(F(1IJBMyIFa-A+kReY{fl(7l@G&b0iV2kqF?A<+He}3%zLA_TloVbAKZvZRTq)zQ z8~C?_kr4X}wQ;#7M4c{*4SenIx8j)$$gAQ+mxDhw668kfY#fw+o87$7z z!#k3YL`6oDYZo`FDXKk}fET{fPnA5hn+(A4dMplPcpo(6NT>m#y{z z_ESyiMUc!d=K<2|YV5Ggy29{Al2fh)%R;?kob39=LFv7VhSs>rm(e&84P-%38E4yC zE(w#J>O;$fxrgo3{>P?(pqCIscL+enreN?bUXxGrItw{n$y9AZl9I>4%M4upPlC)a z(|hb^HNTbd;)zMl{j1>c`iY->VyY?1lx%y7c9hDT(RRAPWcI~e}GaC=%+4^ z#A8$3YCG4Nqn(|d;VC*9pdYf;D-}h@BzhakWIJRYr!I5MSTjbez3JDQ>;a~ZrJlkG z71Ei&!4Sw(H5UESiy})C=iG;`bJ|*6J%)>Du?LQwdotr@^e2Wj$9P(-0&sQr&YiW` zr#!oH2i|%IPZ1ePr)d|Y3H23LLCLK>Qd`Vh8mG^vj=^AR)i-aZCZ;-Z<}i4taEWoa zS=_$Pu$`U>N5}5W#McJ9n){)L3l5FGkDR?1ZiPATmu&kr$((sfw(~AplWwQNUuH1} zRn~YIo*Rz^@|^#RvhJuM|9uepXNoHH!{6#589+czr>CY)H+%0ejTE_E8RnHJuW>~= zsm9kn*I_d=4xpvDybj4y3#e@B?@Y?l2&hnad;P;;V_JCy&ZO32-r1)_K>P}ILZA^y zV)0-#?2ewCeQicUn!E)$0l* zs3il%$WQSi3xJxIjk%{nV5R1$y*ds1Ci~+Re0|vuv$^P5zT_Rzg(SbEcP7l4Ugl@B z0cccL=ehL2iA6Cdn3)D0?-*p6-0n1!ol!jLHhBl!S_B4nx&*%?2=3`7nL*~<`yR{% zahFt+6-R~H;nj2{xGCYbMASsJxKMijY|cSA(hiT}3R2t4l4)E_N(e~ z=~C&rim;cCtKk8J!_4|4r5iz9Cl$ZT@!6`EOrW-|^WB)BFHewJJ{va+a^&j(+H5&# zvd+M2v%Z+^K|(a1FS8LfCJG z-DJ1K2pwIuPCq}8RY23?$0$CUM zt{1x%pT+Y7GqacCb=BCAt~fSx?zHbD1HvWNUA&w}+UK4~g`MEt}$F7AE_UlLR zhf+u<9LA_9`*=r%9}`;M&hk1Vw_$rjAe~PpD11yho!rexqIp;UD`Uu+b3VL*^}vc|yQ6I7;Oq+w^EtO_>@jW5D-ba&531aqDW~%CA_RC^efI6pYJsv%Sj| zo^h)B<2QSNbxiWbE(4F2-=O^t#N^!4sJ$tN;a@?U4a+x8SPU=E4d6fD(X99=`)eJp z|0A1Ki|Kl40fvoI8V=ag5zRltmD*a%b=m)Nn%U5^n zdujGwsaV{$%uH&-uk{3PD5t#_C$l|d&L0HIv@?a<0G=1YT~>x{7)i~h@?rf2mGR8R z+-z`B087S1Vj~OI>46qTbZLi3s}byFRv9lwkFuQnrJ02Tn-L_|w``lrk9BFuq(@-q zMU^A_Epo-uS$c%V6(mwL$}A9puB?Qqv!8MDyPI0tIFY}FB`PnGc$_&l`SZ60ky}ip zT)N~D&wQJTM^6&gZDw*(#@UeIs9kRiGdE*z@+y&>Z zQ~J}qMs;d}%rZIO8%uqY#*-9(9jil#?_L57XoJ2;=j9)euBZTnanY%BY59c2bGpD3 z(x(Hkyw4;&Jr+s2^Q=QAH^;rja=(QpN;Il;>SCqTgjodtGXej7sEa-1uZP6{@|dkH zzR*oB5ELrxIVcjxH2dto#8l^9Tz=mS zQk|gRiuW+_SN5Bi2|XdNO*oVeHleu8pQzzjunvw^voU|vr*o^;;-0<4*scW1yJjN@ zIG_FO7+R(_fo<}K4r_En>zo6iYm=$f;vIW)69-9)Q1bX zpPICL$i-XH7^dD>f&x4UW(NQ}LXfnEhlPf1m!8l0g><=fZsF9LAU1AnD!KRl%%`)o zE@QP*6&r-ZPlG5kX=utO4UcvQ)6a*VitFBW$&#!WZ!&(Scv)D-h-U5$oeLJ0pPI52 zM~MM3WjnS#e ztGjJ%9DZqE-G0NK#OyzmpJBkoI=bKGl}UhFUG?wMp%iP*aO*qKSYTG;rv`E^Jp)51mj~!| z9tJl(29EtH%jf)`@_P?zJv`Oua7#>8J1u)s#@3QR>`a#TsPPF=!#?_a+k1|u zAPVGhlkS_}8kgY)KVDzUn&|M`gCfSv;Y9tX|K5=NM{ypPW#*ar)%xvq~yV1-2>t2OY@&c zolLy^9&T9D!4jBhBYd|$m0od|Pa#{Yj zmgC9&S|-`nPq@}J6!%{K()VomA&k;At2GRNaF|IcIkLkqCvy9|u_ZRa=l<0<(%36L z+pRZTU9Y%G-dQ2LmE2rNx#A2LMjGxVlp*95$Dik!L6kRWZdFBKt$%H6?BAOwTx@PS z@+TK~j_y7BJ6K14cs6(6n^q3<+vd?I*;TCqQyqRjK6i_)rJ;23=2#-N0OvsKrI9;C znk_Y*!#9tB`v$tIS{02^IItExy6i51v(r)j8g9Ve9EwnOO1V)x=MV*#h z9obe&3aTB03ANS25{gkxv(9b$fpp#w`7Wqb?2a$vLH@85t-T*&L!F?WzV^6<3%w7W zTThUWYLOwu`RGAqvIrPV<)pP`RxxiC^PUq(A3)SLGc^9hK;E6OK>_io1uOEn@`t99 z>03Gc3_h(mtgQqV4-nM}o=;|FGQU6q)`oDbQFfaz*E;~z`TdyAX}v<7&C7x#mR=g$ zqXWArWQ$Z{W8RtU{Hj!mUMK~kh4r%VT@%%Tp3^n|vZF}6MATPu8AP%mrV#$NPMEo| zY=&bjCdEPEBLDV@4)`_6p+4bjUmAVR{blzjN3UFQ7p{%ehX zsE4UTE7~FR@EHz)es6KaU2)h%wQW-<7~cJ87^fG?@NGHgKrMLAoS?dN$(v}Xy+R` ztfheDa-i`9!%8y5+$Mj8h!wj@BWxx3FCBTiF_7Q*(owLk^McS!0$)_IKlltJREFp2 z+m~?612$r8?IpwdMYDif@WBXf7-Lj8gcWd77>-W@KWNOTm6D2$A2WTMmJBZe_&CkZ zp`#BPAB*{#9+(EjVNJHPZ5a+|q8`U2So#9~_S*n;#!cH~o!o-w6O)%=W5R{0ztz`m z`d$A@i4gQ=FVs?zIJpSrW715(S4Z*}bE=`V4rhga^DAK(MlBPqp0l^q)YN3|q3YIn z;~63UM4<5}uRq6`=5hQbGdz2w@L@o?MzB0;)ye5uP(j#aDgKXoLrM>2h;z6NW#1*8 zOk?*_)mIl|t$2t~eqLiV1=-BEwS#8a0Uoj6iX-4XqAFV*asM^&k>RtmE%9rhqXVI1 z5tr0C=UL~}dHgN(X+%fppJ`NR;04nHT8rR>lusDh%L^h?pfl^F%a=$vodv$1CyDXf zBb0Kw{lWrjdC!+(YKd0rVhjxpL)h8bn~%X8M^YE*h&EO_$_u?2$`oDLLqcLUU3cdK zyyRrrp@Z2u5+qks24k%c)%aSR#(h@)O|s7e>je~?lLa!43!-dzTpQ2Z%2tqEC8&M8%h68+5Y*7{(sfO4$ZaT z=NS``E2e-+H{GAM3IFW(Lx&|3aYmR3(eg16l$Mtw#+aDkIp0-tX@cu9SZ^@l&u`%) z3t~}QPgf<#Y&Zq?(wQ93O(`&nHQ5ZMO)6TpB^el2C@3NH)coPWpa7W_wmtp%(}jyH zsY@myY#*YJ;{DuWFRy2g3#FCbS$&rgo?mp0N39s}xkWOL zN%TCob!Kj5^Cjc((7DqX_l5*3sQlC0d=@<@9T|Yo7LIVHRKmWOPA4n)eA3}qn3C`tPMP&;{%4fn-0H!LcxvZhNQtY;<6?B> zWAn!pHS~y>G@GS;6{>yy}+` zQ9(K*$#_X3_Vl@|8*!l?X#&|Ih4v^abW(00K{(|bXxf_NGkiQd{ARrkhLg@@jqYdY21&#gL6OZ)D)bQ8voJa7Mi6BTL;Lt7u75;Ee_$6-*KQh$a&QuiUg=?wMrM3l@w}$_ z^D*U>c!b?2FN0l4P8Khb+*wqJaIL`CZgRWpSt{g8;5kDN3&`9;m*_zT-3NHQkYab{ z)oWRGSZ4M7=l&A48cB!ITwQTo7I;Vfs z*Vhx##z$GS2cC!Ebr#Uyp1jqx5e{*C*t1JAXaRoqp!(aYxz-EsD(ry8o8 z3D*Ixeu|DBdyu^tSX#}UWp7w6l40Wx-Jr({)aEnS-D>8ni2Lul8a{z*F!e5C)_j0H z>|x5h@XL3nVdCTA_*x6T+@@J4G`&mj`gLfJ={Hef2fc{`t@>#HCs6i0Y!VX*MFY6Q z&oZ>EiP2dJ_sSX5`RHoQnPefB3fnQ2GWM`Lu_7$-+_E`d^vv(qMyKcjOb&I#06kS7 zx!y?l{zKZcw0T&8--`)s$Rdyux7?EJc1@Ob<-YGIZ|}4XW>m;#C>)+48ob%~A{+WR zN;ZG&7e4$}$Runo*g0u-3I3G3aA?J8cdPGkl9cnsNg3SrKJ7d(t>(V_Q^lo>IkNRQ z1u!l9C%Nv0JbT!)A7bSStYbTN-&lrU6-!M`ae9yM`a&AqS&dM%s%3S4<@p5rkGS}oj_$xPN^s${$dGHzVi%qlI>M63vJk)R13gV{EAyjz*j zY;+W%gIBpjV(r{LP!k__4 zwdwJ8^E(LNYlEBnvoqsU@jsd14*fOsKet>~xUf&3vg4;eEGo%l1!E2xNqg`0wiNPh zJ6v`(b_5jEcDZW8I4r{(I7Jrv`EkhvU8#5f_gL?LX5kFkYrS+Djonf9L*i8%g2pXX z`-_vna~kzcX2(==$`+3L*_2;xeY-XwMY3cpTot};S9r-a!iym`<#+yFA0IQ=neow%D>cibd{<$QR0R$R^) zP`Uh);an1VqRAx}`t@{X$nISvbV)X}GRq+mzQIH9#sofS3Hp5G{80^HO27j5LQhIJ z%HwuMDtDa5B&?_BRDE+qR>)4YEf-8tKJ|IK?=1q&_^kmr+NX^J{Zql(wRK_=^yo)T zuAbtRVHHM!?2kyCN7{Xo%(p?_!EIdrx!;B>))$4v;f!Y+M(tAL4sVJKbpDM+zRDf( z7YnSxUx0aT)A;RoU0rVpMG4o9_u9u-aV2cFjvQ9WSa^y(hCDD&gq?Bf3i@Y(vlimU zZy8Q5vE1UKB1>EXBO+8VjNHM^;QV^9<2Qwf<-8%=aSFazD`WAmVss;=nvI$IP$y1V z3TN}QLosY}`WF78$T)jbJ6q6fZbs zMddDxV{xJ`=VnOaohyf9rRgSv*rAfUXYucvcq_F};)^9h+$r#Lk0x*0pguevX?%c} z;S#SET%$2s<@WzB6FJGm9j(K_elz>KT!KQnZ)Jedf_QhyQ3cA$E2GUWP=Na+Mseir zt;Q+*=9Q4sIjNSa=DzfS0hKlSP@xWV(Ei3Rdd`&Sy}6-}S*?;|sIp%3ml#lXAz_T- zV)*}MIq&h}L;du($X{&r6Q{-w9gvD!?K(%dDu_(F^UUC{NxQF3qLu%$Lun;ZU#SbZXB0`K5Ulu6NH0J=lbfSXZj6`V*64l%;qwe zbYHq;+@Kftv}fr&6$zgd3KVxoHv;J!hsu#bep;u6z(tvT?|MA2Ul%W)&BiGA;}kQ;T|RgwQbz$VW5+9)&XRkW;JF6V z1r$iXR%O^BBGFHf?RV6-TzZ>*luB& zSPX$SariV2LCD{vv%9+&jWen}w&cPl$r<7>Ew;WD(fmFresCebTrY@q{XKb5t}(W{ zz7QeiBqZc+EJ}0PqXMu_G`vFjY~2y2dlEMiJw0|`_e(K zll6yr4rdVsi~Ni^spVEz-?F>#fz1QQjMzdH7H%|w#wx8AqUzs2OQ6dCF<^ECQq$G? z*AVePU7=sc*EZPF*vD|&Cd<)uuAWu|+JnBQeZmf+{u*4IHG3T$N3{E>=>q4EDvV^M#yIO!y;TTN8@RSbos0}%HGuPrczehMDqN+3~Vr^ zJwqWTbM&BiXa&fYoe(W{#WS z2+pQ$;tB`)QX z9_W9oC|JBVDjT#Jx)_d=qLU+Ca%X90(i}~QaF++ORe8EAPcRh`$*eyMeJ#xKs9UT9CO6w{vuJRrOI``gIje_e8RFXVt8FNrEsW>ib;4_^jML?Fp33 zB|lJA>>%mWtaWm0`A3N;<0<39Mz5Ra8)<1~7^jnGR4zF;dOWZwo_OcmAqTpRG6eYi z{RX+a5_#t%Y<3(ikkWCI-o>Pt>-XQU;X1K6O`q+Sdh}DR#UA@X?aqiO#U4V+6lf%-saNLrgBO{8(>`qA-IhJxaf&_9uW1+K zs_{YDZ%YLM23~Ye-~xf&(7ss;-$@Y{T)SN%`tALnTLBf4^XY9~OA_WXYc3osQbTgI zn|Jo7rlzo~gz3b!AZsQWG zxw*M#XX6gol&@d-i#BT?-jY{`b~7XXe#%n6r=Pm|y{AXCJ1ST|vF^I=%Uzjx`=P@< za>o@=VR7vhm2xS@YZJHkd^(tGH+x~S-nO5ap|F2yUN`eRJkLI#_3jrxyPnQ>Vd9VT z#cRi{<)hz>h8}z@vDRJc+R;EAP24Ff1@)lItMv*HV&dJNtbd41<8i4&ELO}$psBK4 z?}g@|2mal~T7?T7CW#P16<#g009aWpmfaj>*+D+jJYU`V#NSX)3kl zQJhHxXaX)N4j(5ZgzU*Sq$CrkK{iIo=%q95eqH^(;?BqxJ&Z1V_W3ehevKAcO(@2L z5-emrvmiT(*?lq(#w72gFkbWdx@9M`7Q~y;ly^{pZ}6tb<>H>>to1ksi)wA)i5g7I zbZp}emg9{gyTxRd=936U(1e*e%U4MOgY2pw;Wn&eRV4w&o98EqxPUWb8ze75?eq-r zhiqT?#b=dYI9?Zzri;5tb6na{HewTfvNj0t&|8d*Vh25Lc;PHbuZ)j(#YN+M|BpZf z0KA`}7qDE2E=*~Tvj{QvB`wn2xdn(e+6x<`eAxG@ppuMjs!+haoG5Dd8*nx$pLfKDST{f8*2#EmDtCB0I9>-EY@q%~Ju(h$)jUKh^^n=c=CMF zyym?i&_FLlc5O#3Y(9O;p3}~T_1JVCs%E3lX11ALRKkIglYsz8gDKdwg)pN1l#c+z zLo%oAZS^ow^5P;6PFel$3>S?DoYzEpAh)f>$R?-jgK?+9Y_342a|ta=71*bY9`j5*L`Vl<2O`Y z^XUXJ@0+e+<8NWLFvAiCkn-~+?vk&(2<%>=Ld+vwaC$bCi>gi zk~OS2aL;?J%T1YXI=`sUr{`nVM2wYZA~zile|n1ag_6e{MYaiebD0UnTLz04dvm8g zNd09@r7j3l1fUawyUMb*zlCiVon_5nOCIky3*WxgEI>oD$WOxph%s*3B~D}9kmGct ztWl8fW9@;F-A`RAWnW7BJ4#zr>ga96!6GO8J^Rj_6@La&0l0*P=A8XCc@}Gpm$%$l zum7~MwS583e%$kp-xU;r3s+*F5ES@%p%Yjn_2;$>sIn*qF*V@83BDqyAhrqSbTPyG5DkJvaujIw<4HqiVV(2G>=%DPJt_cvO z2-84k;ot~;u*BTjO>jBR64xg{4mLmZ7uvQHa6<8r7^6riNCk-N1C|bId2!( zHz}G+iZP8z?pLR-2H~LW^@SNJ*s7#4w`|3;`e)ou)K+K0>nR3o8V!`B1X9>|b%}0x z8w)%zkn_Cn^2cHdgoSZu8W=4>8ZQa9l%LYo?oB#;Xx) z7K1kfXXLZNj1f8`k)a(KW=Q2(8>55LeM*6wA!=ufl455#^+#siV*4bkLlR%+TovVoF@=cEhiR)Sg zTe1X0u}_m7f6sU~w7%px$eg7wWIwS`GTcsX0*s3+Z^!K4smMu7OBYHmf(IyO+cj(v zK~)>2cwe?G_gKFP{fGM27AWc=Z>6fc-bfu$7}FVfv9g4FsA#)^ zA3o<-|2srY{2y*2cwy4Sd*E{S}78fXJvEX5h1f-O4tqd!^9t;geRqw!Ty zyQO$n{It=SEE2^}A}T*QvCf@U#i+((SH9}Ma33n0o%sDk+2GatZDipg^3waC4rys= zKYs{ya?&ivC98!cTt4;T%fYiIT%UMDB)fe6FdjE^!qj2f@vewI!ZnGCj-_KW;5QvK zxmlW|z$bg-FCh8<^EN=7DAQTQeO^m~-lJlWq@v=tM0a%ELQ~D=wE~%Mj%g(T~W%3q?7kN;Y-eto~TNTMw8t3Zs4ov6XxMIgU%rWhfSLA%Pw+);GQeL*h| zgOem(Ouz#TyT+_OFCM4~s3OqP!Wur^wnEj$s(gKYB`|9%ExW~``UH;Xh4i?j!H8lBi(WPE`&8v&wl~rtC=FYF9Juu{#&sh9;cGdWr;Ejfug>VG5 zGrm<-R<`58wGedT5Ir?DH4(P7eV(DQIH5;VjzJJ!IkWv)fUI*EFncR|!tdONS!vmf z%>o4&HOy&l*>|WK?ohmAWtQPHvWcaI1WM^zSctE#npCdHb9*UQ!IU$6hsY)`igyaI zx|^j+R2`#tM(1?{D@F8=On|zF0V;IwAW8>o)qvLBLONj&26gx}LpxlkvHs!01OubGgov&TC z6p7o6E0B@gs)t)DD=)%=&ADczzu6|+x9w&t`-H0=5EEHB+c3ql^J-CC;0B5@54tTk z5hobyCGAWM!boB7<^<8SB@d55ZM?Qq?6iief*R>YBdtk=UJclC8l}`?(ATm>-PEnZ zZ6qtGS9|Gh8O({b$TeY}oE0Yn>6Oo(Hw*LH_JVYIHn!ITk#(_>vgL@no<{#y=`VuM?+mI>|k;534t%Jc<@d18d_CK}?vjY5HJ;&VKG z0kQ2NT6T@)8(LxdL`tdqynkV%C@jb0pzUN!jk491D4?%dtA*d1j#eI((VI*RelLS_ z^GWV>wvGm((y?sZ12xUpT|;nDD}51w)d8~&9SXOYuF z=-=pqYQVvBmVUSaFQKgn*)?19sam|`tE1#3@lha$Uot&$CvkRWL4mzp$Pa%I{9fbg z+e3XrA)fS(7a@6q{#@Fp(uO*-dOmNJ~zz!uVu;>uu5H{9b$bMFTq=R6ck4 zSxm@X6x7DhrVql1&MltI5rVZVkB&aheqQAz#8nq+_$Oic|7_NNNr2rpSn0a1l8irG zj~z)iuj@UjyAxO;%X8^G3l*b$gh*(MOLq9cS@zBHR6D21L-lG~e2rNLOKhh9`*Z`F z!~}ocodA9%RB3)Ca$Z+3_N@9a#^Rw(V^F0bLGBl5*@aL~|C%nKyCniSJw7-e&|CmD zR|D36QA7NMTV_4tl@?*W^WmDa8e!xneK1-t=!i}J*E}CB9i8~2-~*jGIt-qf4JZ0Ebje~^ z&U<>Zu9;QYn8^_;5!QbdlwWv&9TL(mcZcd+D${FT6@TydnU=dU=~gL}xBM#B0%}$J z7Mf7ACM z?$hKyAUsv&XUFq76lWH^q=j<2i?Hp2Up9-}H}SF>v8u7(a+^K9q`a1{TYJmM62Dbl zn+5zR%=hy4{%p*1k0+Ql{&N~E9Q!=XID#dNNpm@>#(qON*}ZxL&8FXK)b&jrm730= zqPbFX`=Q19_FM7~!{BkQ=m7(l{+j^g-=6Mc+sgUS!o=DrE-or+-w+`Q0tW&e38XiQ zzQN{C^S9|XxIsi}LpkZUe1a}zk#f`Xs-zV6=UZ!qWG8xdE&+7EFsiBc1Zk03tM*o| z_WpmkPCrAmZrO#*uUK#JxDpAjt(?fi?WLpMf*?yXs@(;^}XXV~jE2_~y za7mh#&3R!Oy|0~o^I}MbWA8dyW~kH)a~2PVAxkJ9Ab&wo_+%^TIB-5#D5L5@JKJIS z;3)BJ@zZ22PVWOh2~lZXw7nW6x$f)%@~C^!?;HCAZYR&|35?X?pfgh3w*Xt)9teGD zj30$fcqMO=c1Y82u@h3IWT7e%>0r~Rqa(sxz9#WWZ`W>;Z{Ka1{*iVaTMRNL&qehhU`(H**g{U8H<~HaZJwL2D zzH8$cbzm{F?$-yTn@#fHZ7-pnwiqmcVHbV9-@ZNixl4JD-pS&#LkGU@^DS6i?R0c) zG_4-=7+nogkcsIYl7KZW>9Hn2kLOBE7>@+EB-M}T=T$~8ebMM>M4{Nt9FsNO$uUlF zp>^sGL$c>`_NVmBnY(raMybMhg zat>EQ@BBN}Yr6Jt-tUWa0REc8#F0vUyJo)*`)XO0M5RhuKJ+`g;lmy0`4jnpKw&oc z`?*4fk>N_M4gu$3kX~yWE#2$mElz7)M_$DfU7Bhf2O2bKBERjpGwDsZWKq2GemWND z6qci}ko54AYkIz7=U|*I%+30zvDeJ%cCrIv_}Em#f3^~3V{Brim4AmV-)s;)FzzcP zpIw@bH(XK`kX`$05iMz;)sh?e#9c{Lq^ zu^QiPFx7l z0WPB?Zk+p!7&8!*Ni6pZ;_^b7PGc%M-)6xNLd35%xLn>QXMSpXbuF%(C#LL(jY^)W z@};$nVONinw$Z}+qp{DTFDE`k@hAz5yNVDms0ge`hJvkI@@n&nadv~SiQN4-6W83& zh6r7EcuD)U_2gq`A(fG&sS#5OODzfK23wYhInvG7U$FkqAWFqpcshkbui1H8mj7vCrZAX-lrl@x74ofo})nW>%HvH~LPu|G` z5Sl43c;Q7up6*q(JE_kpJUb$XgVC>oxqFiCU%#Bid5-zOf2uX4sbqA@+-|P0Bok3*t|Z*NkOTr>n@i}tjT6T4T3e11vJP9b2S>I2(Mg|D zRi3FMJ}bYJ4>AY;2Bvq^9vz7}68|C$i8Fsz`po#+v;521p1u99YU$@)anJJM z@ItGFu|f9(#R_{@!MM!vpt5&_ao-lkb_K*2mal~?%EX&qC0SN84Y@D0q!eW8Kh!Nv zC!ZQ_=G2)j?8GOJjg3ii@-uwf=oFs2Vg}EiOaCz~m}Q>P?y#5xd-a~^zkZCw_HjNw zdKX01TcZ!x8n3V3O{**~9|CokmevU8_+|Ji!?e-ca3Cje{Inhc0qn`k4)U9F$yVOu z%v%lLm*nizv*ZHSsdd?P#{0L&?dGyZ<{P>{w7aLqclv(u4ee!|bl7}QiesRo%deX3 zPixnO3V>5)1w4Q$yH3`#XST{g;2U5rjP)`zb zNS%*yke%N|=_k8_f7!Z4HGr)f4c5{46B)*#{|mv;JrY7izgu5l&oAo^_6*WFMV%Qp z?+T@bbR_Y+tz_)G55}U68xOfOl*Pi7v=LBEE^F1Or+9f>+ zBp&3xcTd_(%rrJEm(ZI*J7tztrGgWRyw`GcDXM2EsCT~UZYq5({~RDkrdwV6#-3oh8VlBMC`(v`2VP+}5&?WRe+V7g0x z)yfNnMVtdL``3rq$g@@nLT|c>&{KVi=*Yh{aZ&SCpQQDzjh5TjD9;+?5~N-53x8mPf> z0$KMC(>5UPZF_VLY&JMgUH+SC&!TY7U1Q=iPwdrmueBpz3A~C>JKi|YfXQW-hf92! z6GD6O2WM=E0`)nVx%D2ZnUaNI@ zM$>sEQao8cU#73J-W?_oTS<^2kkeIZjV-)9jFh%U2S$_ATNC?tM!(6%Xmkr?lMCI4 zYOg5IbVIk~=6BLtfR>=5z72+*i`aMy-|qpl!gIE=Rpa_$ZUl}6n4}FVIA!U69nb34 z`(?rQCG4`OGc|I}f4ou#t~#Ws`!l5%1d*~fyXpNTj%F*VuE#5BK%p-eD%y#&mOH1v zq;o#5J2xWSpxsuIP7KOnZOC!4yYl!QBW=fOSzcp_LNQe%)7ooLU(s`pPL>SSgM^X7 z*|tI?bYdr;_zUl^H{3e1e@c18UrY)55#E*;JuSxwhr75)pri$Uj^>|3ghZs?9QZFCYm-JtYI8=v>FIo%HjPJo5ZPIm-GsN-qoWel>2M z$>yY06s!QRn!DMg1eRSEa(-K_-)Jl|2J-17p;M#2FAT?onO!;xryPp}62GcgM@0{; z1Ov+;axNRBpGNnfHMhqNo`)1_)HlIJs#Jb=4B-MR!%^Vpj$99?-E|pSi^x6~QXGFh@!2ze6@062$ebCD0#~0gp3xRW`vMEP*QCBo=V;2 zc%R1kxw|T^5yFhPL%XWE!KUFz<&^pO? zyk2H)w{9r}`d#BGzlbO|0$X{Csje0GLY%-`S5^yp`BD593&rBlECfCiC*(XgPHvbI zJ}f;3IxYwZazl1Fy&IlcSt?#JRK4tE44CzbJVr@w27&0~+ST5b+L(p1t1HBv{9p)K zRGv1M7pCuTgX;b{s$c|4E!~6|f_oTZU~jFgtX6=w<8S+FO8OR~$3rWY_7aX0(wqHK zn%bUqxi|Ak-CjjSY7dj{+%1k26OV|)NNoF;xTgkA6|)T?SKoH)VEdd8@c&K^`TXnp z<&cIiU=CRTV7}rH$@1+Fjl04g?(ULO!y0VEBj27q@gjfQWS2F z=1XJ8VMovOt)m$BoHDgUde+gPy-(&7zr=A`G5%ok1nx;jqAv^1oy}FRr6J7pNup#2 z@-|c9X@QfAP7zT^ORem1S*q>)w`Ym=8gt6Ur)Ej$JjwK-SZAqlje#$b$Nap~6uU?5 zrH6c#Zv7r2Q}32#xi3Pox4xe;&aO5r^PEL5yGtnmJ!hgfq~O2P<&j?qz>s6;&&(=0IHFaJvVkm!@tl}UgsG4-g`w6&RpL3ZBuo|Gnxn%H*8e>lEhSNxlDA#lS{6B`v?ZEIuEnnjYR%CA&G zS|rmrV4@|wx;}U;D4JHf_u{Y7bf=F>7kNkv&;829BcnLlCGji_hKn_?UrBNxD-&tY z&z5XjPN_06xD@k%X~)R{EXsr9-k zBGLrzEVA8swQ&dgax%On&5_jbC96&ty>T2PTiVttOsTS@f{V0N#2`n$juz&$RPNgh z?^P`NHil*{DqvMal<2(B?zYBeb=0gdr|}=dDL7~62(N%z!fIK*vsDVdw7ozN1!;ik zdW;Va50BNC(-y%X$pfSQ%69=HE&6T9}+e7Aoj-Pv222W*FKb#W1=t@y~#Dx?7 zKwB}_?)L=4;nC7{9b6u~M*+WvwIKTW^{)X~v#%W!=<`qNcRRJ1VhE3c5aM8+KAi}U1@ ztw#u#{a}7pmNN!gs)}00XM-Y_H7%b$g_x z1i#tbS|lNVd~+oEahe69#KezciJ<rMCtpy z$vg?+nC$I;+1TaKG+21ZYrfhz16xi&nA&uCTA1ccqG~6QaQ(#STCOdkR8~$nG`m-8 z>>u#&In808tZ)sQ4(ed*r!?_VR#)!JRj&@oxT9k-Nq0&WV0}R=DXMf>GifXMSPGMU1Xe26G#Au3=UQ-vtImD7PA2x`M?6$;)PP-umPs}Mzcb0U=zbIh6SuFZjQVCNLHT*i7ME?;-AlGIMO95mUi@A1jxsGo6u z>BG+2k1%p%PtWdJsiV*SF?^-sXzWTHbW2rnIv29XwrgcuwYrq7)=7(819Rzj*eKP!=8#}f$jza_NuW2zwy{-Mx_(}o>7IIfNHbs%F_{ndT zexT%E_Em!XKa0z@w3swWKC&CRD3sZUQps;!YJrPM|65!iGYR=y;rA)GZ8XpufvMWEyuYDCx(H4BTAnQI`dYB1#l)ij)O1p!~072Emuz{@Y zn>xaMb)wRn30lZc0$dkKYhn+0g$>@rPPMW zBaECokD zqhH|R=4Zx}Nm+~xymr_1!KX`%qAN2tn`@6QtqeKd-iCq7jmO?QPIlU_0JSksus(`F zT8l(^e;2U^_n2?g)76x7vnEqu)OuG`62b7v_NAQY=xO+Ex$eJ8;q9(be)GP zyEV6Z)pl;4k=Z2Xz}%yrf-i^LVSj${%0swax$G~cdHA`E~ z%miJ;7rE3ZxAd+z>P~)MC+`ev@2`Ss77omJ9aD$ zg)J*@p4wh=Q&#Fi?-9Q-RL-baK7IQ6-r6%beC<)Syq7d>=3J{07kYH!cG8|#M-<8< zFmpdU;ZQs8<=}5W&J5ndzHXf%SQ@?;@*{b^wqRv^q@>)W1=&q(Dlb2+y_;;#FCeH~mpo;o*)ncy}ja23DM-U~F`9R~uwj$?&DP*Ci-CEOjtro&e-XYBUe0OE;ye*}2 zKU7EL!2!%la@oKltgMs}=;m}-+K)&fNfgW5WaJDjECJyaso$P-H^s;g13?r<`V4V| zgdqz}l&fDvktc@Xkbm6zg{?VCu2~~Bb=Ww?u?5pFrEAPbr8HEOyTpl!o_-rF-BrY4 z=My#6nqDjBJ0v6Zo_GCTt8UId;fE{YK9YVu*yOa296a|z0p{YeI8MQ;-1hHmT!o(9 z`C?_ZfKBx1Ih#hEMy1%F7F)|H(~$Q&f;;F{97RMZkd+(s-;Pi}t!Mi+eX5x$Yu?X2 zJQ6a;T7F>2)JVi1$@c0 z2RV!sxQ~yI=|K}Fo=&j_56CC`m`*L1s)$wHLpM>d?8IXD$Y)z|V;|er(O9~NM*Z*f zpf;$5`^uL|m_yN~%2i}GAZS^y)z!s%?JRf|*6MnAPRYO&>6+qAfe0nKlA35Sz_T&y zGnkpex>zsHjQx z^HeM;ua?4R=b$C^GkfiAWA7@bUVkYlEOxA5&{f8!_7Zy#EL#K`P20+mqOlrr2DIh5 ziM1hdejDxdT%d;A&C3P8ElI5c`PEf-R(ynybWo&r)_lyT6*pzRqGau*n2>hkb3arO z9nScGyn2-+3jM(-8!1Q7)tJR)#R!C3`L`0wVm~)|JO@JKG&}y($F{r%I%y5b4+VJW z3f}!RbOmg+HVg%{x*2I4F~Tv|Czv`U6XwFvWl!?6eirI1U5CFl9#8Ce4z|X*DbLP4 zR?y?R<*6y71B(A5ba6{?rA=vXsZH+V!*hE%}R za-Df=Xmw5ft+h&`(d|yTKfe47&{so?hOv{&jC#w3n~U57HRfc%O|(6w%cb4o6>8uv z=pz!6wfnJDq36WR6~hOA`kepgRXq$pv!c73t63|gD%!kO8-4EQ&(^{^BIiL98C{10 zs)fub&+~Lu5e4B;DEMjWEL{OL?pAE3@5tAtas{d?JHg=lRMn{nCuie`>Z-15uL%n; z5WfzKoJtrdpB719Bj_3%IQ8rS&C<`2!j*6J&d2rD(~e4RS3pXX3+HQw(mM7QWw_!o zX_vE(;j%4^N6c3TV)Eo|l7b5*ogN?Ml>rsvM1k3F#}owQ5x}N8>0oZ#h@cC|SqiA; z0mW~usq3S(?tH^OIfdTt)DtPkrMR)wtEt1OqA@#7RkqD}t^Y6mZVs?sYt}Pyc)*?> z@d^&Hm)ajVK0d~vlmd&sO)}}ONjQL?clNjm^5Bvd9Hy>CT|?>}z(k0MuWuMx<=|jL z6W?ZyU^h}PXY_*Hoy16fh5^T`uG*^Mh%BG4;&CaO?$0SiBWu8=-w z#nRo;+^rQ~A?fS`k3&FUp~>WmnwDFYYozr8lD+FHY9f1KrFq(facW&wSK~WXyr&98 z>M(f}YNa=@f;OntXuXIwwa{XTv0QrQ7tzmLn>U9xjqbsVEG93cdpK>Tgbaq0dK7!! zc!2MN*PIJeA2t#J`~SPwfDPz+IeHop zDwWdA;0n7B)T@Hs_77T)Q^`3mRghZF+S_f?mUgk6Ra&sLlqxEu;j6l($~Mk})X;=Y z`ER#Qn`hNZ0u05YIq;Y5lZq`&y>*QdNX6yL>2a$NGQG#)VSUC~4r z3WGX+kU|Nso{mnFgq3c}FM1aQ>anMeW)99nfbj95#}gid7^NBRJFqE!wAVE+Ol8op zJrZdpn&UB~AYKehtdC9_L8h!o6fWI?BVoRN6=k}d5E&#plnNPo0ynlz1)RNL3}|{A z>EuT$4nU?uOVzi`HXE@~Imbzt6kTO1-?LAeb}{5Rvw=q-cj^JMlBQuG9itk77oPY? z#~$}`-BTyr!E?6#5wLSbX}ZRwInBA|82$6T8)-;;Y$M-vk91V}JytjYe_b&+t))QH zN85fAlS=+qw%}F?Fntq^ZQRL#UhKx}=QTDAO|rVbgGMey5*&6RU*)PIC$Y13PI)pw zG3+PEmjbv1w+K=Ck*+3*CEJro{a(6l#CT>&Nr`OsslU5Uh}1Q^u-W{FWH zJ>W*LosH_*)mrWi_I5pF$Z5d!#hsebSYfH|b%^tKupaT}-{!_~E{^GgODm(5(R0{jA{*_a+l`aAx-Dg^HBu@wI+x?yDr2l=yD5IJX%Tg~_|p5`hSe*c-4((HAWF*)_g zyb~iNsQr+=1DUr29`JaRp)??H@M`{Xm?$rtnFz(+oiuWIXY=d=xvybbx2`fzS0%eY zrEcgL(34?2QF}tGLBWeB+m5rR31Tar7AWL2Nn#a!H1%UNt9b6zS?9j|+W|QxBS0&^ zFlZX{&2$kSxQjjO?k7f>}cBlJ&J)E01`aB1i5?_C{F3FDI_G!-h1*6#@exo73!;S zZ>M43&${z$mSl{~$Io5hxf=DUxmiW;@kZ<0Z|qZvCAS$TU;841ysR0jWIN1>=}D8< zMV}o%Mmy%UPSx)b zy0OWPy2@KXr%mkIFaIUUuRPB=d=#fC&ja!eDwmsFTF@r0^H0MyaL*l>eaUHKtdxYrQd^Nl=#qJ4Q} z8V>niI#AunUS=DKsy9Suiz?}Xi|$Q|m|KWWm)feAqKB3TX9yo%gr{(h8OHavDU##;+VJOlroit8Y);ch$LRjit70V*6t%{JNy@FJ$zAkd zN+l5Rv))xE$I=3G${HI`<@Zl^MJQXB*7U3h;_ts!GP2Q`&0KdCqrrc&j-uyg1?FCo58qM9gkK@Y&HK@q*;@S;K2G#Q8<7|~9lI_3V@K>TX5X;SKR zVE61{QF3~tb$r(G?ofRJ0?KhHl}cWiUl7lKyrq-61+Z-MUq;P}fVUB3Gjek)C3z>o z+{}l7(J|-GPnDxhK$ljmQQI#M)i18tviN|1)6&WdX57S>c-#Lh0^zguCn|rL-)`oK zb^Jaff^{HlY^RgW=7Wupn=~M$>=QH#~9UJMr;86OV<1^ z9{R%bN^c8wf&78!+!{cXReF;T_WD=sm}+&Ge@Ev+=c9nLa7& z1%$B^Yc|>RThIK{Af`a^gT~+3HS78%V~h+6$cn<0!@PEU#^H;eT%(Uwpx8>=REwKD z*u@t}l@O~zl$5Ga^9RW|f(~m_DWYg2Zpp%3?5sU@R?*eA7gPAovDwjd%}U3Z73rVt z-SpK=q1a|EKpj1agvf~TZl{^oYOI3wnfu@Q_M%RcyL`WDAo{`)#_c7c&N-aw+=7q9)k#7AZERDG$wGEQi-B#-WZ z6ZhWpJQXbi?|)uxLUO~dixih@ZXa>;B?>V+?R_`&KgN@6pm;yC(FTgK z?|Xv5V3wT8WJ+}HNWxxSCARRLM)$-oT#s9OR5AN%ho9MjZEE%D{0OTp3$joFcS#%= zKYbdHQlI=eKJF*fTD}A5kc*}9O+w9^#loG7Yp>OpwX_0kf;5qH31KZI=BZVWhw4hY zt+i0zL808L=K{og54ZGN-*T(A4Yc2T?|(t*q=MKA8C*1wJU3S-j1!>wYP(YML$}#C z?7p=r=Y}mH&$91JIMGKj=a_d@lu9RjX({Oxb`tHhpSl@e>#?8>skfI=IRqcp<;juB z%yW{O%OX;*rZLE^g|)%K8#3_X|JS{!p!NrqAAgL?08n|9a5 za!;9&dioOf>NBrrIG!X~bhrvrD*3~Jv17DuS@+%_e-&JtX^)`FaNCS#*KcT6l`EPX z`EXmm*1983@^xNEX!ILGqJIBiE%a9nulTAyn|ur;ZRFqtsAY5NMP2nXtFr|3t-`mu zB@h->_O|BYK;rfoEv~sfB&bmZ3QAt_E<_-a8FFSt{|{U58P(L+ueH{kYt9Mk;Xr92IaA>78aS^RwXx46BYn1%K3LMj;#ol`BSW?&r;X48-Ip@CiUGXUo_WQI5@h|av4$>|>xO4rQ;?3laF+O?6b7SP`Snkxg&Zl|PRa4KDWv^&3 zBX3?AHF327N6Zm&bQX0aGlO6MCFN_*@5!q#sq@2|uo7~&bWjUWb1~;n`;6ENS!mqK z8`ytPk`+G*HH63MuyhqfRz2u&aj0o}abP$PB7w*z2s{1PVTiTOUpLoFZ%`|NkLXKG znix6DqJ0GdOklX{)ah{x!}C(##(X`9ing29l8bV)76K1rRB-^Z9{j{Y z>4aQALHl^?(Zu9DxLBeyfOGFIDq5zbBDxe?j-IwtOxUWUq_kjZJ$<^x$F||0w9arz zyhD7$T)-PcLwKX>B-kJjw63slXp9?1524@TnJdwvj};Hl>ymyN2d;OW6~>cvd9e~& zP>sfk4r^Y3cAx*cYOrYgrcBkT`tCfQI95jYM|4##FD&yJLK5%kE6!FR27hX$Z_{OJDZ65|M!V}VP&br}1fwVwB{SVwiJU3n&cQZ#~=-?VO zg9mo%u`rDQdI^=Wb8U|XPh&jHSFJo>hM>{HusV8J!$96{-j?YbGb13;-AI`nB57Tm z>B_;i0Hh!7ey`-2hq{5>t?={FFg(BXZOTHWi~luKxDZhzLcDJ~B>VF7OJnG7jNlZ3RJKh;gl*b|O2=-yEGZ~Epu$+TbO*wA%F zbep{W)FEXNW!l*HG=Jma9m~<@Ty}WNM?gcCU_q-ip{3pH;!Zf!MQ5E1Qi7BfPTsmn zSoOg*xs@sDRZCNR&g~Fq_OAXzT`TSqaIhE+f1JKIZ=8k z&XmrAQM(UoH{tQcIo6{#`kz&@{~LYwGQY(#_@RJ*`bOuPbcS8`p+fL}CF11ed=5I} zxpgmQ0^A&C!A6uHO_JTIE{35PN;POv{U^R?rBjIad}rMiCo_9pS{KgMucJAubIHS? zgtHRc+g;mQ0^au`uh$gNp5CJB&Szh)vwbpR+;4rQRXiOB3H@uLzF0sK1eQA-c;UQ` zA-Sah){Z!;`8Vt|{K{VaROWWk<1yT~@KP-Vj6;7* zAMe>ZMgsz$E{=5z5~0b(60Dm^_+?lQIljcp*dP&|zza9iPr`t3{Ekfv9%}>xP7k-$ zRnW1Me5i*+D&{4t9XhP60O07%C@iYmpg#|ddOF*qJnXgo*m8&s1hYTK;Xuyku7nTzJDNTp#^&2l0zr%R`c66Pax=CIOfCecE(2|E9%gbLJ)?#8}oC$d~ zs@hDjfn^zixel4BKKKXdTT_3Gz)mhDRkml(o;sK~L+NI69~8q9qK4wU z9ZpoyUXQ^|Ymbu)XFZLYrmD*&!mf_-P&m5m+6?G{*^RU%>iCt*yzT5u-CayDr0!N( zhNnvI!HK$+2Xp z#5|55v|hK4G0K*5{<;w59oc`^epITx_n7-tVuDhG?P(twlBIvi!}Z2C{>8C;FUNl^ zC%su!O*m3v1G#|PXtCZKN6|yi4U#381Ph524B`aYrrKl zq;pQwF6YwQtl|En7+zxVveISP@8!8G1gV0Vjq!LZP=>8u-09NTy#TAlo)*(5I}$xk zPp?kyRNUT0i%Rt29(tL7E3mg|3ZVAzFdHr3pRXTZ3Xqdrc`_J9it7y_yAejVNCHc2 zg{IQJe32c<<)k9hTSZ6bk~w~Zf^4%L?YaPB$w9Hzrl|lkMWjR@XMj#*Dziu$M&siYSmz>;Lu6ybpBNhndQUjje<>)oEgo zAB5bgyyZFM-wtJk)xCOlCYi{W;}^5{(i4RS`+^T)NZn#=dG!gIUhy(EH{&F4_gkox zl}YYyj__t6gP!BUWq^swg&TlmmX0mx9I6?O*k}s4boE0AW$sh91ltKZD#`TJJawG-X@~E72UFY+^ z^KMrtTD`d()sCj@CvIe5kG9x_6_nv=v(G@=RV_uvO|S2TiiGlM8da3*Z+rLJ8zL-P zS)4$=$`R43gXH5vc~3cP`SWO=sJpHlGF#o_#gROU_~5LhrJvzU!`s{)gBqcQu=3OD z3G66+A-bOy-^NPi#34=1V65gwh%2LsDp)-yx%3cgwMGtvIbs5YP@+{nZB4B}sO zk*)8nZy>+gstZH_7H@RB&|228M)`~-HkQd!F19-s#z_ezmolH3hLm3qEuKmo%p;q> zTEqC{xC8 z(!Djt6~vXDiT87Kmql(-w1;apS=5;Vt`*4MVO2d!H^2KJs|bGiqR_Nhh+yN+`u3J* zFX$J|eeL&J3LwqEi=Y#@BeX%bmKRxtm{rSCaHA&}g&_IbPRvS`e}E zw9Ss}2KFt@BJiC_V-%xyW0w|Rq@C%)bvRbxJS)`Nk3e=&|Ii8>9;a6GK%W8n>OiHa zQb(}$bahoBkQC9La7ML)^l8(L=Ie0Qs4(1d{!*t)Cf%G(!0CBCJ?R-eYxmMI?i{st zXnI)sP#xES{2KW*aWXMRZcmKPI;Ptx+T0Q)S|Z?k?baWo>(kGa>LX*t|MFjWTI)~e z@F1-Vz%`a|s+ojwwfaSNz|p7&`kTm(J!QM(#vqs0X0BUP8XI-B<0a;2Q85&1Gagb= zOq{w975?{n{r}w)<*WRl)-H=76H73HB}ArGoA9n0lz8@1%@w`6MQ5zwfA_SP6Tf9D zAX5XQiMUbrlu_78a+a9}=I`&QN;=aeSaV{Iif+sxG)IYRYin?lJvjkSb$ff8rO^z0 zxWU+0(0Hyof2liD>7){%=DHH~a=B4fNKkWoq60KKeJyB9qnwh7jHH|j6jchFA>Ddb z+4K;{bJ8zkw&hD6CVnQp6DZR?sw~Yr;I@YE2Hf0D98qoBt|PhAOP@Yaj*&keTnAdQ zoL8*agUy19Cq44M$dq#J+1agRB|loL-Sv%Q zr-4V}Hy8bEj@7Fd(H5RtriG7VQu7S-$3)=sm0R6c>eFt<+&Lm!a9KJ9;=+cPNfB?) z%OT7bK}^}QwnbL|tzgSRe<~Q=x{f`$f}tZW(C4<29Xo-{zn^V=&y6*i{sPEiVZ~mi zC(o#?X|jtuvu&<*4q4!?_}3pz9QP!}TL+?_<5M2<+DoUjM+Q9 zcjY`h24PT67B-lxF}|u~fn(xzL${jG*5%ZN6~{3=bK*W5jsoAH$0;Zgf`dszPQN70 zbGj{C33+OI{1iMBhgc8Gl?-&ae1F5p@}J{z@v7L~4uH!RAn)IBy;;r|!M>NOd3<<%rooZZ`f!8bC3{Wt`+WVVDaoeW9tqvr#QbphmIoGL3QUen<8{dANRx{mlhuXNMi4M8Rk|v-ps>~P5s+2e7%`SOwCtXMhuO*F zOXBR0O!c=S55(!mc$x5Q{a1x$qD*Krdn`h);KQFVD2re|m9sWeUebuV-!86|G4RD# zR$98FMy{Csf|$T;4LP28#&gy$)U;zrubQa07e+Sth^KgpS;3OZy~qMR_vv9UuMFvb zBei56yGH10nz8ycS)*%W&+DPfE;H_1617P*7W5Z6&mCHEcIFJ##aLQ44Gt%{csQX1iTMRD+DneHA!zl7gsvJ*!r=KCtXVGuI69St_(b~k@Gd{0cNY?6+?(zms+^J_jRG$Je_9M3ni>0Y>BiqtF!WDbjtqgN;FSkH_gFuDiBV z&0kREmep5CthRG+a~}KiFJOpjx|5($%WLts@3DzA+)pX z6CWSdIUyyVF`d0ro_;*iJIj?y@qwtZBfoFn&Md?7wLx_@xIPkzL`gd3`XnF^V(59u zAP~Ml&*`J;2BtSJG9xnCAfc1x4ZNBssy^*oF`XR@>DmJ&`vGPhb$gvMU-K#4EZAu+ zlhl9sW*cMh&yu!?5CtJ{u|-;fjfq_A;ny$ndZc|b9Q_y@c00tSBE`YAJTNRXkzFRy z^Xc{2n5Wg*VM~P!5~d?2fQ`JHa$dX{>hcXWhpQt+I_dY?Sk|jf;z+f9H8pm?J0TYl zbNt4#AhB*f1iUHN`xsR!luMMF8IFeF_b~zbvN>yj7pUT$Q5zkG zDnM&<{<~R-+N*<^1|NE|<^d4k4N9H8ZQpxPaN)2dDFKj(p>br%kK$Jp&QOX^S^`49*2mnK>G$?knf-|K*O!B8z}opU&zeabxgkSZ(i=ru(6Ve- z?V5Fg=*+20iMQ=24z+gbr$mq^@ie~euIk>SYk$(s)AS7Coh;GBNS(T`IrB_)3mUJ3 zPt2{dLT@O5F7)t54J^{DZSOwJStm^J6qq-tN!t^RI3K zjvD##r6?Ip{Ca}j=+9h5nI>l7ekFkL?N7bd%$g=&ANGl^y57B}onbYiHf{4M#VZwKFBtysX5T|?v^w>-@DDaOxoiwa^X-L6_WvkTGT$ifl-d{tU0c3(Fr!tQ%`-T zf_(z7Zrvi2F`B=_fctkFiW7T%Y&ai1WMVp4gblAJBSw~iNp-Ims>zd>>; z*45=g)2B&DU+eOeqt^)Dx=KW~tCg|82}0W4(YiV}yD#nCO|MFV2~yH}%^h*P=#DIh z9{u?;9LsCgp$VCR1E$s9HQ8b&eyP1fI)*eBi!3M3FO-+>y?A5k7#eBj0q}4X!AR1k zm=7)xMs%Vg9A14Z5X;(pK~RlKK9&d(BnLM211jm|_7>~=5-95`Bi+}3!k3rb9(W>P zX??I%4D{&Pzi^B$MmIOTyH86@4W{cn?6thdiY87v4%X-oMWba%wd0hkHT?MbM1Z)K zU?f#^u+N$|H`{0;OPg>Plzxi-aGBJf;NLv~wX?g%xtS?FA=d>ER21p(+OOjE<4yrB zI`{PRD`vah{+*?~(|qdUHT4ln=WPcPMcZ|5_XC8XXqqTH;^Q8>w?5>J-ov6*TTS?O ztHJ$x0cH5SJJ}bM@Ez-E=TWF5)cWTp>-eLXvYgiF1&CN z8=rXf@&VbXtER<=^gvhN-FUMAD3~Qykn)o={Eg;oKQ~RgQxm%xyC80X5(WR7P` zUl~O`U5*c^|EwG9py{l&-n&l4IsF_Tj&doMqgE^#0f`J zk#wIN%@)lP_L=4A_{yeA^IU*D6%}^~r~Q?8H+;hVXn|S^cV*kGYcYtG*vb7Tg5Dj8 z3f;5tgJ_O5_{P0}J@rWvw(~USRCFL_{%4dWi%)`R;!>Vu+Pr?%a@Y2Z<3*dATZ)Rn zCJ&=izJ7mfMs9vNE54TCesflL=f3<-3%z_9p`7VAxt`q;tuiR{C@BEV==uEU!5cz; ze0yZbE##6Vbd%PVZxwgdx`kqSf`Tg{w>_>i<~B6z^~yqfgeaatCi6=CEt*DzzzkR% zl(e>#{*w8=7h z#WGzlA&|;bL`H}hwe0rQbz2_JT2{~}>nOJT8JAQ}l1J9hv7kQY_2TP`+l03}dhCcU z7`J6@ds{^524nT039uU#RoYgD(_O&Buq<_@2IF}}LEsaOCl6T4n7tSPpEFPe8fp+ae@0roSs;uvM4eeqF4}s@I;TX{ zXoK|E>|wPxj+Je80N?OKfD`Ip+TZgtLjulT*XJH0Ld9#k8z5BY!Y-(OWHgrQ1 zI&ts}d2xi#`9VXGlKa6(k-@+Z=)u|Pace@sZLTY;3EX^_8{WsItt9a25gx$`9$Ld( z8Z3;|VMEqUf$nU&i=RHzQh&VCLSgaY@0)Ow>FR$zqJ-w;l9t~tCKGS*RlV~z1HQd& z%XL7P!tS3{F3J#)*`;D#mc0bPNEt0zPo-289O#`eJ>BPPKQE}ojZNqUWbLGl+K=JA zP+78BaMe=Vb(qd>M)(rFO4=sboF;RqYmuAz2!Cu+dsgUeA8mK~;I{j>sW|6EEjW0v zrgTwNsk5vF>IXJsY*I-udec{=;SV+f;wlfT=Gn_~c+7{AVAvgM;bSr1UY@Z#%ggRz z21`-!ZNmL&wb?SjipICuN+D>e` zrDSU@JFb9{yeD~erg@Y4!REnZA2;eyUyoAFcFl@bgKCO#>bt5j36yR{gmTQv?8GQ{ zs7G?=r#-&f*dP;-@-0rkDVv2WIUsyH?S0*qtoqMU)IYIe6rI+6mpFg6!b*d)g^MqV zYWCm9XY{C?7Nngojo64b`X0t98XkFUy3JtJ{`trG`Y8@S&M(?AvjvlH$MOtC+V$aA z_NqamKqIjl(}71&!%N@oF%J!K)v}bInco*`MmrvRP&m_cvD7%(&2_wTGNYCgoGXfq zr=8S5(HPH(zy9P=Q*A6 zU+3&g<}KAsDQBF3-Jlii49xR(>Q#1_+DR6Zd|m?AOSD!%u|(!?r~Ik%d8y*MTZy^( z-mAY&XR1Ie?M}50i#$D!6#&&$o_~FmzCDtm7DK)E^LR`}UL-?!s&3USg-tMyS$^@#hetJn;CgAgW!bM;}$u z!?lpYeaec;6&7sDRC=5G3x8?KTmkGU^ETA!$oNQ-n>o<^RGE0U^g6OAeIQ6F8LnD0 z?vV^fT{iHzS*L3f%>L&`u2QG5P;c`5=Nb*7_L^I5{$lX*ciNsYA4P4iqw41m3-mN% z8+I-S=eA<+bnK*mJM;UQSfkwi&L_xBVa*+6;jh2Pu5n!67JmXv?z6@+M@P(l zJep!vN$VHAR$ADUJ{snS_)ZR)J};7~qp%Pg1DW2VoV%4^-#cOd z|B>}SPO!eBD*%v0C1(eDB;T<0CkKz0&`CBOOWBu((*?U|!T0om!V~ zQEI0;0mS4xPxfP-zju8;5*>jxUoxe@hl$~5&f;yK^61ygwtt@0lL^Dg(z;a?S~gn( zPsPU$V(hRj=r|7Bk1_&ZoSeZKj@JMg*F^>+6!N5iHV+O7Fnx~sPjSgv7*G7YQ0=*> zGpDjlW@NFZP4Wkp|F0ze&*v-u3cy(lnr}Z=Dn8q~<)GhZ#}Rk*Xftog>|u(%nU4SC z*j>HN9`5pn?m~g;WL1G4Z5M*RtO^3|Q|g8=Gx<#4T(^|?6FW!NX!YknZuJT`o3ylF ziNh9J zL7@MW$W_wGzQA!TT-1DKuz4!4KgR!^UY`}tTVgkBPgqXNSH=3k_E+u6lO6LR!72l9 z$3dmt_U+>}JYjewI5;?{9WwvqpDKiGp_sqvDWH`1LPE&JU-(-cxw@>T9w!D{uRl|E z$|ArGg#e^vO?1YG6>h5RT9F3QTHx#zb#3{PW@(NmCREKlGI<_QBhi!k1-7yT>tw!L z#>*-M{q~LgHH$NF`LUfr*@<_%I#Pw;%>p@HnJ!YK8UYgD9)`}_L%;x1`IHKE?Erok z=o1u(w5$=1_IJ^=Q*c8zYM-)r3FQxnlI2aOIj{$Z`ro2OE{n=dU26%2QAFENsM-f= z#>q5fET^12pKhyr7ElJs8pvJp?dUD&*@Qf0EoLXXc&R8J$L)dEitaI{Vjp z3OBV{W%Iii<R*u)FHSM*Nl+q+6u!` z-Q0SGO@B@1h1y&iJ%)b@$^WX9Y1GtWootQd4fBsq2V6e8t6=ZHz}N!2-dwKh{yAQn zvdRWlK(eL^VgFcjGfkkEFA)U1)MA32vWK_=3AgpmoWp2)tSfp z8_>yvoF%WZD&TQgxC{DNVcv{+MqLA!0C#%G+~&$nmt@}J%cV83o7YP;8)ZyFe^t2A zRO&WM1sNYzsf6AH&{{^QbcwFL_S2Z@8=Ft<+wJf?GzxX{guh#=>9j!NVn3r4oXsJ? ziMk6=033cG2Q*S|j4r*7DlLu*^{{Pycn;ap9;2=lNwPL3Jz0%XH8Tb=SkWXQU)GAR z<&JWj=a+excFpj>9bCL>_#=xlQd@2TsbCxVx6y)-j0ZEB0lJHFE;ASUVTPTk>(GzU zgt!@BVppyjnXX`HJKV_K@e^9)tNXY(K0M4|UjP9);=p`7nASh-?2qpz+#Czh(~Eb+ z$d!9#km3eFhMAdpd$0UZah9?Lo2kJFg{rt)VSHx$z9gGnmIn zWmHH%;OVaRYDx%!+9cYMAKvMT}ZSdy!iz&UsycHJ+ zGG<@uI94Wj_)I;9i)OabPeC!hP`o*Rp=N>6>93p4i$@H}YF1kkV)NX&hh;3$|ErX)^zSmk0Fzkcw2Ou& z74kBXf{Z-$*2}v86ub?R6g`IQ1n7DjMPCLbBFJ&fmS{EF3Rr2nB9?PBT{oh|Gr@ogXW);U!%OG(IOim5B$QjE!- zQKG?QO#Zor_UBX}p~B^+rMA0~-)J1ig3D@Nzh(M&f~TvyhsSRD=p*Ft^bEs#=t3t= ze(^Xt%FriHd#6xo^ie8`K_-{oPYyLde}aVf!oOcyE2&Ce{coAF`9ONo8>TD9aGhLX z`Vz0O9Kbf=bcHXE$T)c`n?rd;KgA6`ewH*>@6UX?f8)>xH=xStipTyIIr(fZ-Tg2(-Kl^Ks)C zl7kq@2s2kou-ujvNS6JPX+BZ&f~`~LsE>0OIVGfi z7<)vxmDue0GL4Uo7M8R9NX~V!If$y& z?TxaR2>5hA-^)dHie?0N^^>jwipf+b#e{Omu`JLax6``)7Qs^o#9B<$!_lI8ug%^8 z)eF5Mg9HChlP4?4^bA@Qa0m}zZ6KSq=Py~rPo!lGG~XH3uf4dg+Iy@tctU6#$`J4` zmZY`gh+g0p?{hh1BQ&SIl(pj$;7FVLlG^xk+%s_Ys=w$#)zU|5<03zCvSAM|UyYeu zyLgl3+HUpIThEXCkG#xd4NkP|(yquB{{%?Di+(FKLrwaLFHQEpo9@wmz8*RD(Nez0 zh3l6Z99ucR~QLoycaivAHW?LF(8-f|+(93C}3x8RWy}f0VyQ8mJ1}d=}g5M2y zt|dbQthF=4#~#r#tIY5bI^m+2qauv!>Y0AD#g4tuo5yghKq>`b1*JyjFbz`|-^iw+ zm0!wF{}AZHb9M6rW0jcLye@Jk7T*|FShRyD-sIR8Ar>pgHm2>GjV7B5oCWU{#vsNF z=aWeseI3^ZBsKm!qt5>64oJ$`17bohGeR#Ez6?DNzoXdO(Q#Zu87tH!cEOUnn_tbT z?2ey`9mnOG&u@&_*UQchI+baO{HUR5yB7t)UpTiohWOhU2X91Bq4On`kWc1UiZ%d=A8*5H-~NXK!&(}n3_W>#$d?vM6mz>b-bpB~DdaXQ}Hk%2UXXPm71}S2EG(AU*W%({%6v;wL9L; z3M?O@an0h?J@-?Ic9rd}_z=W_c##240f2~NkgvY_5`)L#E3ihYT2)tZ(r?war#f(7$!h7y zBXO2|0G>7uo&Fl14OT%x2TtmKRchx=zJ-v{9R;DE_{EG{_$Ra%a4a21ckIii;`R)7 zLCSAANj__!a>`U%O6sI$fZDF!YR#ycQO3!W&;D!7;pg0t+t*0<9I|GpB)R*IRQ z@|+VPNq<@n*!M>xU&EV6Q^}q9`sy3FwQ$x+{>2r08cfaOjEg*D`?D|ZeG^v_Nn2)f z>9eh1M_zR5wTN9+F;edUA`79)_eVF%x^W=`85kCq;<_5drG!ngBVdWe%l0|r|q*_Tky--x2!ShWFA zG&W^@q|a<}d=KW1$5PMebhRl(Pn~phD>4bmmUO+ovQaQ3v%n%#BpD&%;5Nt7u~xX_ z?1&540Ro+}T0hg;$T|Uo`#&B*R{3%IHDEmQK<{41=?f0DOd`iCTk6_lXY$+V9Q{S#tc(OI6V-CsyemsBL zjVJGi8w|a1=hWr$E4_YK_qX(boer(lys>B=T)+tTcWFTFs= zHPh!ZOO@4?)!u@tNw2zwXkV$ECsWj3cgwgb$kmrII(1vQB*#GvN=@(l=?B0tI?h|8%+J zj1D436WtYhWd?p_LE)%TC}77e)j!pZaGz^7>_kSSQ&G?^U;|`qG8pO~v)p8a^et=* zZ|&+IR&LPCc+Se~VHj|K_PVbVPaVx}+$fi5c#>+}6dL1LlyS2?^h~NDC-dx^yR^Yb zW?+*{t-psIb(WH%XXES=-_TarknAOqLK?Il1(0kNb@gw+cFx`K2kL1Wt)pts-z^E*qD&oS_E9L)<8 z^0O>}d$TW&O1asEJoVmzcHxY$C3n5ld#Mg_pQui&j#sT>KuU*JhU_vt3q8GV^>ICG zPW7uelxrRRsr{B3)Ae%x)-`vTb{nKYy$tn15Yz|-SGM;1|;7NwMCXt&VPqT z|2)lLOL;3mN$*L_;!RIoXnvC}n|ftGV?bW*Ffv6@+#Gie6%qb(o^)uDl3H-%i}Yr2 ze~F7jmNIxzu685gykW`yJoBK$>Cj)msK~fyTF>9G@8ZLhR#z9I<-A{JSCsqIjZU)5 zdaAc-?4f;K`jp#c;*LwLMX4p&xOnE;+%CO$E|IYbh=d&M1e)-Pif&-a1R;GsHwh}3 zwNL|P$x8M*GT21dqT~pe3H@n`EG5-1;L)=N6HVH+CjzHXz$z!St~IY{kt@lD-H-pF zvklN5(28EK8S1JgCrPPlVsJP2HZ+v=&G&3}!7+&edArY6Wphj^S6o-Q#*A^oC361x zJAQ)!-|4z%!HB8>>Oi3{)pBik?=ZB)@OagecgH`mu~m9b?{P~C9Oq|W_ZEiFqVA#= zO5Qq;fZ7TlJpQ{!lr>{|#UuEiYhk8WuTT%k?6fPcBZ`^rleq07zoc|;E#ynD2gkgu z*#|6#N1Cna@EjD<|Gh+T-S>2N%%PHg=*@8iv#1OAFY+Q~xQpEU#hgeJ&#QQ6>*)*F zOBlt%3?_T;_Rz*fYlP#s1n`pf21#13 zm@vv%7G7Oiter;?O7%5h!?Gza&({h33bFCeD`^pRjkI6!#mh{B{7>rg!3q(odSSWA!D@r>>W0kle?Q}O?Jq7pej*$bZ8mrk*6Xzt(exsv zb|Ez7wwW%XmJO7%aJ4gPlEO~pOFt(+bnYgDJ(AecZZ~Jr4o{&w(}50bfTfYOqgk|f zn_xRDx1b~9CCd`Z^@WEEiu1mAYL#`lY%bDjYlkJlvdUZS)(hOt9(df{kTW$hXy@r9 zXuz?0TS7f4o5J)dyy!R^6aQHB(V*i1sc0f~vb0c1w8yo6Wi%vyy9b|OhpXBWBouD; z7PWaahIe>`egM0rT7lRD(DRCzY_2w<4_AQKrq5UG! zpb{(}kWF&VQC@=#&f{sOHz&aQeF{VWRFNl!U)@Qvw={zP`up?Ob_xZyk0nIC`DjY( zh!*Sbi@B5z4*3tiEUIzL)ZZRAe>M-3bgE!Yd}ul{7o)<5`u*+NhTs{@$q6C}Xvnj2 zqnLA7XDvJc&$qq*Ua7J84;)j^v_eWf5*d*b7~hCzX{9TgZ4u|-dkAC#7WG>$zdwr% zPNkl(dghn9>ay3Eb5!{~Q}UFT{e}=)cJVX;>&pd1nqAv!xklRwaMH!|UU0I{KDV;4 z(UPf|etDLahE1wG{4Nq&#hD&%rDJV`7Yv*-8=6 zemytv6ZLxRXTUB$^%pAh6VFNET-?F;{K|WXt~Q;Uow5#;v@ni&FG%86GgXVlPcd<_ z-|2&twcy|@6Rp24jDx9l1)~3-iS!SE3aq?h*lE?*IYrDGeJR(~)&c0R-m>C{$}Xvm zfjgom8o%@Q$|Q=arm)*7wV&8U93~7E_mH$!A2uTc%OvUUiRhFaj>kGJAO>h$0ay&j zZk|J)woj>ho_0s&eQ)mLzi7)ue9_R1!!%HBfRtp8KW zu$CWOJ}D?>fNjYeiqyZ2-hUWd!ga>D8j}4T(;L2C9M6)TLP@>y$-c;jyw=ctrWRDa z6Dbg+oy+I`mn#w91IJUMsN6LtegtG)ybUUKeHp~=C|kAl-D>{Hj|-zn=>)BdewYtd zBXa|?$5tgj0N%NRtaNcR@`)0wq|ijO&VAXQ9%;Hl?WM`!3|Bi(dVgIrQRyE1?qh>s zdq~hw2~dss%tLncd$^~G5xp=ux1u@N{nnbGeoZQIM)tJsX9b<$Z@PoR^lbx?3S zD;2Tgc*MYb+$hT5&(qsGMc&EF`ulanPmdbmByYq?ZOOB7v!@duXk3zxUyu-jy_5rm z2Y}XO5bg@%(GNM=>9Btv6brunAm^rt5R+1_IlhG+v!Sqaz9IAzWeIPx&!9_>QrP>h zFPASxaQGKOpINTAJIYPnXuN02G4n;#uS^yxH3X}c zEU&uLk9Dl$s%|te>QG(Asix0tS%yxhA(E@ z;%BF5_oFZwM7QYM2KxG5j)78YEzQQO5b0CSQEG-&QU~AD0QJxQ(f<23fm1&)ko(Nu z+*r3nUp~o^52n@PouWjNZ&;_X1TnwzxOUDnyz*EyFvk5R?35gU#P0oFa5=N^za6>} z8HEOpEi+Dpka>M&BW}lNd+bRRWfHsbi}_^i{oL^qn^)a)(N9zENKfNelAMAM!vG^q zQnBsHL^*{4QFJv)v?mxBcc9@@7;Z|0^uXl#co@>NsZ)H%>chqKRTskeee{VeMo9}xt@ zO^hXz^#ckQH_4{AT7`5o19@F}+|H>B37uF9g0zf^lh7|6*1Gb;$LGCjKcBWc&O=FY zhu2TV>Wt0ZzdcOr39X!KqyH}Zt%N#nawS1cnd4%!%?B!9rxDzep|nj6>&4E;zXR8K z-d4x%q?c$Q& zueY6ig6XcYy6Z8@MwQK3@jnv|lge*;EzYr8th12*GTdnWSmvT|8JfjFdnP}*~t z3WB@=j9nyK{(B>PI|uM)gk~8>plZrW*q3cNCA-H!gG8D0k7=j;g!00K;_QbA0(9Ec zU?@(e(e=GZQBl7u)OV=%#$ES&qp~B9-sdSSG=mMs4imc{wmu#N0E_ zb?!JO`_J6i$Svb-0t7D~zC8VXI1cZEuuAAA%(OCSPS^31B2ZqRnP`AUqpqZqU3NOr z!S>(%UI3!~y268VZiDbx%IWqvSfEaTwkWM1S3hM1S9El=Wa;lvzJ(uJdjG!Y`qo`@ zZL23Q&0OnEis$~2L|~&SY!7`h#v$`bUogj6g{wKON z2^-=ckhVK><>X=%g!{f#M`R#h^ZtMpa9lqbdFYBK@F*NwIWP6B9L{|zoBX!85j9aj zu({sKYrAuZQlvRbeUdoCiH>3;-I}iBKt((?^=K5hhPLVz%;9|rMI5-AxdT?wUSb!_ z6DfprT}X=Ip^`@Cz1h_I&C&(koci4U?A6$9Xvc$1YTX%9^P%xfqGmHXV)&*!lX!81 z7G$M(iUuUH!%*bJ$*Saxyt7}!yNMOT6>AL&IhuMK?p>(Nh>8gfTfEPf>`TA!jiF&w z-J?jG&E6YHd+b6@R(!V<&pEv~LzU;K^E3G6sHo;BZ#Kos8! z>^QzfLUij3#K4|*zYPDG1|#WJla{Ji+(LSjF^KPO7fB+8bTta)@A{fEiq_ z$pvNflT<3P15KG84n+-~^&}5%|6I*qI=!yNZJd_appN)ZGDjcE0p7r7E8&6X)vZZT zlc%#Gl0oIGX_~UC@Bu7zQL%5gQuAg@sY7PW!y@z){4j|NQ5H<1(HbgyJgYlOiA>rs z=^G)QYL6pg82u$545|GhO70@DJ?TJN_U*cZHDze?x0;$7m%Zio*=;P%7dUHw;x=IY z8-KUKbrMhdCBvlrSWVGKCBMtO3ivcD`TE29i+6vS(mTey zJFp{0D!GJFE+?%EPcKo!*dpxd*T+J;m50}0{M8>a5b=AWup&>mnnvs&KuLBb{deEij_~dDb1s{yt+tLKe{#@M28wuGWG_ zA!VzxbB45^@R@E~X?en2s<@A`xKN)UjWz#=|FADg7KPs~K(jDOQM!WTrJUnb|PiVTL<>L$O^*aPj z^dfMyv+gYFU{wYjY}mFNV$R?=+DCU&@(wxA#ghj{+i!IlG^_ySa~3h7U}Xgn>4>`T z?M40W7ptsLks_DRI^P~g!LemP0S5yEr=2KR(k+s7Kpe;F*U`xvfPwMUT8u!RxMRL5 z9iIwzid>WYb51t%{mpu0t(HNAA&{x#nKbvCaW*aq@lmE@oIGK^V>jT3jNhrV5*xMN z1vty|ZxgJ6t**SMoFU#Jg3T*BVIYhgD%~W~``pe8^_HJeA-SzECnn>INFC)11MFi*E8mi|!{7>++NTIwHY_tD zR1z-u2*c~Dfs$H;U6^3dDuD&Kxs$;wg#)?)pR#iu25A*6=LnpYCDR!F+YWOqKYgL* zN643O`_LbLOonsxKV_K#dcV~e5Yn!*XAWx7pZ1H!!xm4&iiZx~NN^fHQ8PC*d_>z6 z!`AwE)>b~1rb4H&swydU18F<-(&_LEy>)fr3EW-MBwHR@UbrcavUOG^Sk3_aBE51B!aJhXNDo0^4roTuRUc_|Ru^!n}HiMR6NO z_hUVzyHF9MyVrh2Svltr5;!gD?2%dlS-2Y&`M|hWRUin@C`Hb~fX#*kPG{rL2hmm7f zIs7}k0{La_pN#Og((Wj<_@TErbdQCM;@O3?T?b~YdKI!B$S$qjc2)K#pnO}bi^j;+ zs&WSZqV}1l;g|nt@6MduT9?;y?iR@p5Pn`=H0~tg&(Zq%_m7TVoSifg?in5gjFfl< z*$zKXa}7?4qhB_bZIQJ;btKWw*oWM~Iv}7!=*785wxqX!5J7P$3*r?W+CQRaWAS6D zwL;f>8=8vuF@2aPTIbB3A^!OVExrLf0HwPOND%OttUpN|N1;IRrk?v|4j%nTv88g8 zA%1_VFV#0=S+OuAvqwv%+N zusiw(g8sZsU?ngq7>hFgE-qax>`y+@UGFWexmRMIk01-!A|uwatH*F2dYQ#e=z@-|PRVFy22@Crf8@s3oQ6;? zdq!!xXz1j?2%i2giEXk9ReGFWxv)Jhp4Kbu`c{avJ0Z z6VtzX*pVuE+IDezU^y>U=+afCA<7#)+qenR;TDCPYUAbgo|8ysD_v=Uc+1GyTJ2LE9%#aJ^<0bJr5i>U_}v@)+w22*PDh zs5!;(JMWRHbDZt6-l6F&4PZbqzkR+d!FOs%YsDZ(>H7ZS`tLh;TH+p}efTXJJU)HPHcr(ma&mg>GgsOI(}?VBzuW z;vmFS@2 zo7KG6dt*7`BeSB90o#KX7LBt-<4js-M-Hj{pv8z=&X$~Xv(H8%M8-Mjrq{K^$+QdZ zO6)rc{WPUgn>VN+Lal`plf}A}FP?G2ABK_0Nu=B(^=u~n!XBSbvnZ}+ys~J$U z`^PEOVpQr1EJnuYPk)i5d5P5>3B&VJOEzD8jkzuIbde@QU%@DJ&iC1|Y_?4a+gp7_ zsv_q4A9OAKYhrJ+EgR?^qg6#`N@D{miBnC*?St{CS&+!Wng?*&Mc#PZQb9E*+LacO zZLXVf_;k(Lbs^%JXlFhJxx-eU*XON2ai}|nj@<9;ukl>qQchhYmQ#*aSpkF2e(1&< z^MNs;+-s{Z`__}AJX{7dCz{{AB{i`Zap>o8A`6!mTb{F(j>oe7>oxpw4Y4E*T^j)< z&^#lhBn-DO6UskQP%vxk#O+#+m`hJVP#vp0BbHvZF_~>#=s-?Qxn^547C)5q(E5;~ z7&H>DvqV~SReWj!%HFum24UDN`zqf*8|o^LEiC^Ym@7bkFt(P>tO25zeIJm9^5J|w z#z=w?%aY-YP(#qfswmQ}z?K}EwV9|(YCF#^$$^+hRu(~%AFt2cy8~!@Ks~MG^6sPv z&%Mr71U$Zp3v&!ym|&spB@v}KFODrW|8U`KwDSefJx(&pZl?QzZ04dm!JqgNy@0Pi z^t|qOA{wcG@zSmk@Qtt3(F|j4bmo`efmgzuzZ!Lp7QcDkOY-$>LMY-tn{Vfxdf9nh z@gSd2m47txksFMw{P)#E+NwM7cbolp=Nm+6`(tXqRdwEi^?G$Lz7qUVDX?jrwzqxr z2c3gg^{1Douj&J-rDsX%N`8!pdJ;bw6NqbIl!Z!ljv$*gY)FW-C&I~4c7|cRGTc|3 zK0_sC5@oe8sXh72+y$h_<}RnzV<@-G_Br!rie$$8oTjhJrC2P?F%C4sg^pbmaFXmc zX=-&FC?Kz{q?gWy01qlS?KTX7E2?MPUi6+V3+7N?Q*Rj`BYmn$q|lnsbl2p?SIs{m z6z0-_v)WR9hWq2_EBm7e5#U=v>+wL{#r*doEH2jM< zI!Bx*w^b)&Zk847!3xeHc(k&d<7(hj>t?-V1ZhXGnKX!|AwC$3FI*=^#*01;_`$yx zbH_>k=tg&@QQErqG=o^DlkGU`EJ>>akC96O9pAK-8xyZ&$>1Jclrl-l9}Z58rFd7AJx0{B?kXZD*wOI(LYMkh2d(> zB_^lWtldYrY-Ib%h{8u9>x_4!FB~b2x;L*qAn~iR)j0#IY}`AEKdc)R4186B_Lsd2 z6HVd_?RMa|3tr^CEI^4PdP2nJ_mZvskL;4$C-B=DUXB%2Rc0yVOdS4t$fnTlN;jSF zXS#9d_1`7r;gXQ+V}b(@K8z|3V>QYFp#poL?nWPi)ot>-rNG-Gv{>feC9~J&;hBT# zXaT2`jTFh#f~Y==As+|pOqdzYy-VhowLPBGP|wP-0Mno9dR%o!e#fj7^TMy1T~i2md4wl!KngfA7gl)cb{Kx29+H6n}G*ZN!Jy z&C`47My-|?SEkn=h*&ajwJwGw?b;MT=swH{vwvXjCli(2Q_OM-KFF;F$7(%?Fq7`j z6?I+RnHVU8d|0Zm?8FjQRl0B~bXFxBE zeEZYGUdzdl7@EWVCEWyLBCjyWd-~D(K!L{G01pFFfuokA>TdD)l6;0rnV4rxB%ayt zS%O82z2w|quH7=oHYsxG;2AxX;8-{!w%PuOMQlEYHh|5nOyjgRonSg+6|lmNIMgaXR)9dac=@O)0n5!5{uQA1Bkvjcn>;#K&Sza9DRUz6 ztovY0>@k4VMJiHG)c)bxFN4(=fh(;>VjYR5JnlaG8iyx`{cxvkC_qSUrC%HwbtoBw zH}dDU3#lLim8AH*x4h3#{Z`#3<{*FOw#&U7YJ@5$6ELGeySnl_x@3N)ABg{@0$0Bd zxzfMc^1w+u4k)4T*3Ga>;HSI@LJEM&-oF|Mf(uw?)ur_F(Ce%a)=NGc&kP1htoP}Z9L>oa!Q=u@_8jY?IElcXcKK&==Po}8J-yAv zBzw1yM0Xg*FTl@6UAV~)?C(b_uDpreqcZ3GZPo&^GCQ9^qfiD0uPE%J$Q^ucv;6C> zT+(pO^;AC09aZfi9{1-u&GG_$j$qUAR*cDP34dhmZuci?(1~>KN`HxLjelh$ z1%UFb$TQPtv<9$DPSt%fdmTDNnQ%yMwTyJAF>e*==ratYo_B`)5htr92&|?uWcV;J zy8DI_uKnnwefMPe*z}++KmY{{)nw}Tc_x})%Xn%KPp9ooeeR@kRnqVZ(%D`G+%745 z#Lfo39r)HRX?BWl`H`lhYI`-vZ0OBSDgj0O@NSX7^K0miu*Z7cqj_+yo9>Uk9iTkN+q(ke)qE_#ht0p znP%CIOmnkY76&|Ub1w#%f@vGHPt@sw77k#=0yv>pbHG8bUjhc2gY)U`!@D z%b>QHao@Sl#^2)NpoYkGCA!hXuu353IxN0&mOHWpr4=~P0UAs9R`jx*Y$r4ob( zblK-DVG4M>wHO`!4q>EwQeZ=_Zs`X{B37BB+ z2s#qL*6K4n?E!cA5ZY<-Wc<*FWX*sd{?(^%G4PUKbaG}xUWK^PR@5isp`oE}BetIF z6i`@fC^j(a5H>pAdjE1pQVtCNFCFZiOB=n&1bva2yj&FH=#F&#%8Q z3*(gL6&yb1#grcw7w~E(rmA3AC1=zEbR0ho5r1)wru8;gqZf-o{(m_AomW(P3s$(+kZaYH%67UfBzK zO+wc5QVqIefmLKns{f|AX%E-n_Zxi{L8s(@oREGA#yv%lM~!nC zJ~nD-Nm!QS#`WLI;{Khudm);)D1* z%3)ptC+`ZvI*w}bHiIqvVB=|#=|H&lrdUwc^z?KLLE>_7fY}ddgAd7gUdD_Ea^+I^ zx3uCb9hS}q&&p=>^ct>v_gX%;R=V)@DbqW5DeKmb&0IBO7YJzn%AM>obR$z`kv?1} zFG1e^)ERpnLALmsqG+qE9Ihl{qhsetT zg=Esl7yCrJ)CHOzl8482YK8}&pt)@)@&#_#qIL;&oa5mEFYy?<&9v&56h?Xk43uj! zf-vPlSc{%m#NErr#0uj)eY`U(M(?MCY|?X+KOK&)plEfbB_)xprrh)?0sOPpZ`oh3 zUU6f+{i8;fg8Cgi?pXW}-ud$eW=yzJzV`BGJ(w`ET9?FuZCYldLb^aY{xVKj0sl%O zjBAc|xSH(S(3Sis*Bap}$z|x-b3LwMaCRcOU+~+}h4D7pv$(jpb>C@{fBT;VPGr5T zclmgvu0Yb?=F9gRraZYi_vC3iS*!sfP>1Kkb6T_2jRCvSePxc8zkB zq-^Eo+sWX?F{A(os>>Pmyk?5HH1}KA^#^vK!{Ql@8Uc~k=MQJbLx6`i--&bZl5bPO z6LNN1_l1Ak27CK1%>OJhMUlACihD^oZ5^It-;j>r{a?0Q7)30jiA)(QJV!;Vom7lP z0NxpXbTUK4P4|jN@+QTqybV04Zo=%T8OJknClnb|zepV^ zPST%Cny3p-edNt(W8|au2|~bf$Cwr=A>Ep|&>g%8@}G+DDgUKH2uyG8* zE^rN;dM01V9h}G_;Sb0)dwFa$x)-As>SVOeAtkMZWrt+Vzqpk!#h$Wq@k=5~IXFAe z8?1v071&?(78LL$E8b16Vlqq_e^D3ZL@)xKIzm3TRImnIY-=l7x40jxw@yu`vmKkB zqE5vS2{QzZNn?`5LAtkc9k{;PtbVHJKK52aXhmGo8T+nP{M-!JwIGzDbLg08+sc`S z<;Cf*FQ{YGfx9rf zn449Rd2p`Hr#EcJ=PbVyO~@BBg-JzNdhRXvU}7$D&yN!c*PH`N7aD`M@7*+@wv$&gnd6?T<-I$hPsx4*aLvA$i6RFL z$*tELjkmmIwDq8pxj$UMT%mK!Xt9RW^}bzxz(X%fNGK~6)TI<7i(xrZosItbut}wu zWR}Ho6OlrE`fG!L`x89A0`D5kCmcS)U1-lIs_Y;Bgx}f=PiO=rIe2(?b{ThiI5mi^ zhz9HS!#%lEnun2q@GicrRT>6>S#F+WAF$E21{}un6lveTKRin9Uw1>Z6tqBl!7a+T zPftNA44Hrc7n4Hfit(;gP-8R0DP_+~yK!43N#}r-{8(sOD>rj&;{%l}`{>=Co*rST z2QRBbE7S*iM0AYk*IS6(Ix!4rQMXVMS9T5mx1%~WlKgJ+?vT4hzo`6@7^kt-uT;Sv zKWE@XN&jwo6cML6-TUjRymn3EA8}=MOFT|OJ)X=kCqS1fFY2>aCi0k)=dO>^A%|7{ znAr#JOOd8l*a=XqH$FxgMQ3RG^POfD8?BUIKEZM!Cl|F`pV4C`)|le`3l9yud^yi# zy%tNPD&4B0wcfI$t$1ZVMJ$4rJ*NanMy|N)EyhId1SnYt$px<58rj=2VuWbc5}z_6 zE#lxirF^<8$BHhdE`}HLlGTbO=Ema+w31A%XPX0wCYN#~vtnU@$k z7y3RIsYx22xaXI)F}?qqRa4~vR|QZ!O(*n^rF?mGqX$qr)#bA z-)YM+D-WsD|M3>||FUtck%?bD{w~~&omCoIju*c@;g?ebgR zz1YqN*}axsHp)2BU>Tbli59plVa%#yn8n(F<|A3OR?iS2qbg>8YJf2FZXGe*Qb{+p zxfSF3(Cx8q=IL<8yv}jD$eQPPx%x*MMkoWcoUH8E%9O_j-Qigxb)4W9f-k(+^N9fa z5H`u3Y>XkSBPvDUy|HW~65Z@=Ty~0X?u&1fc6R{zmk#B+hv&H4Y?#iZ;)qPAY4k9A zd(ShUdF6gnP7qP~gB@eb9-Le$f=#@5%NjBz*36r#Jdf-p$^e#8I%()kgy$=@+N#?+ z+H8Dm7M@0s{w63IzdprBQf6`ubesCsbJSO5E_pP>)fF8s;c(s}_KjD#oGb6MooaX^ z{muvWq(|FF3kmXzw4%KhL<8%^qV&hqREG4y;7p3<2ZSE?g|vfgAT`|Js5MuC)zQK$ zkN-x~;E3{U>UvvGa0d0{Pq)Lp;DqEZ{1g3W3Ksw05~4FJPp9NN18l~FrMKNC@{3J0{}vNe&wD3f9}wF5ctc3ev~%6;Ll!UOFhN`W@fyq^G^4W4 zrmspmo>zFYD)DplCg#x(o9e?)j7W@u(=?6&gar4L1Pt3g#&y5INU)HpgWb>34q2=_ zb5};|$xc`W)kE-lU6W~f7PXb>|qx1p>*2V5qivGo!Ds8>eVVd2dVRj*!Ih5{18GlxWTRXc*E4Q zP%=31%+rC%Z}->t!o)Y}NCs}j^5L$WN^DrMO9!bCpZug7QZE#!_pw84*lMPz3$a6> zF|`c}Ub@Kd%+7!Vj)Fa@%!jyl2GH&;!w?F9AK%=?szjQI-c1TeQmq_C@q>rtO=XOL zo)*}RGIrt*a+yQJlPzFn3TKwS3)ZGGT=5M^zZdA80)RBwe!{*SZhGIZtf!O;vgStg zt2LW{WkwLQxO_M8a@Hf@Y+>at%qsD1lL?>mo!&X`^HcuWmT%f$h|W(5t?A-v1RtjK zrtS~L*<^F7AJTxKgVzr<{Oxb7z3Icsud3S?M6sFjDW6!_n8801!dH=_Hy5n!6Um8C>fJ?Il^dTi;K-x5~q8&p4-X30v#UGAHP-;k9iYzh1Z26>x5C%TsrSELW9*t&ObpE@g2-6mKtUo#QMO zVAO9%T}}9=eNH1D=$nY8 z+s~d@DX&!Z8UNnYl_By^g&0ux_qh~28&~WmX#Cd=JBd0uEwzBc5u+qY-bR)^S$bsj zqQbHPMQ*K6G~&p72cP^B87QAvdy#~6ki3KcLf&T`RJM0@pe)mtkS0W#F3W~Cxscwn zepabpXQ0;k2Yksx`(rQMo8@Wvsim~3JME_D9WzrTV}7KPia5LPrr&vbJqI}%-BWvr zY`23mAl-p90o|6~5x#lSk;3UM@xq4+=h}b#@*~jytJ7^htQ319qq0-()c2NO#p{K& zLrJC8S*am&&G;3CE(Iw|*=17E^PFVKwJfjS@`pD!ka6``F>*u;uZqa%9$?qyd!kN( zWbEC`6z0(oO3v<aW$xvFRhcreOLn zkC6y>9ExAmX_^K54k>wq?N} zUXuT2Yg%e#0Y9>$W5sBn5bnuS2Ay;x_ukxLaeETd&9L+utK$5cZk`(tn~+UUd@(EB z49n|!5v>V)gfnH>bSig$v=DTwsR3+j?9X5-gA7mBvnuF54;4^p!MIsW$Z=i8+ol(Sz-Ov<{x)dbP%0m~7z(9%v8ROTs=Uo~ zN1Ez&U+fnIkITs;m#>5nlEJDtspW*fMzkd`bg1{yv1OCv()WSA1~(M8W+X}S^sBPc z{|X5I{c*H|Sdt0w+1&4-=P!Ase_~=H0`;hXfQwXWvcy(kP^YJ-5#+b{b2eDFjRj&U zb_Ceg8b6V5Z@Nm-V*p?4xHGJyD(pb2!+Q$wQtv_7VO#L9dD^7ki}SN!0KCXrn|Q5{ zK89}FIZRb_iep!7Cg?ZkbAWlVj#apfnABEEBD8B@s8rB&i5_vhnvz$_+s9*ta`&G1 zQuoW;UbSLGEl|P95a$`I%wD<&GMpWHwI(y=!++UM6-o@;xTG8jHx>;BzElE9rOARJ z8+UZqH6TU%u-|2{RSv!IA^Esy)XG0IfTjJw7irnbYS1?+u4NuhWWF&yP?GOZz~QZT z!0u9Z=Dv@4pP$PMxYg&^;xcfZZ(u&0y4^n?YnF6lUE79JyaM z6+FKq5&G7UbaO^`hR7wt_08#7I^jtQ$U6>N#?!X8(}Ph|Us<})6Ie}J`C(hX0~<$2 zLIkd{HvE5dR#MV?6Sf;BkGcQzoW%Pw-bxkioGiNzEY04oIQ7;Z_f{9Ib!kGyONPC zz?)nd+jrQP?fF+;anTPo9zWuMisv1_CwH@Y=_Eg!>Yd8QZVjN0eY>#vrK!CtSCUSS za)K!9XT}SWd*im?@^8$8)PKUm*LPsdbP#PFrDzRLzpK>tF010;AGU)-}Q{ zO@rifTI{bue%@q3%?Y<)c`ZOEKgkndHW5HNH@e&8Zbl+ZJ2=E=*iQdTcb)C9y1~$5 z%2%?rnvY#%qJm{`o>PLG<1*~>F`4z}0QpuLCm5$$+rvL}&&49B&M`=?0u2$SBb#8Y zIJ=jyVp!*H>PtJjvmIeH*iNlv-dq8w4geE1AH`$B0AfXZ0msuocl)>IC6}kce~1k! zHb3g&5pIGIy!uH`g(_p{rJheai<0<@xlc6Jp9+olZ>Badia~3=#eP;3e9hX%C;t`F zx&8|2E%@ewZ-0GNi=d`kU(ejtv<{W;0!G=+FXU=_VG=UzmwZTX>0K7>=GjLwI@}B! zWgl9G&lP4ow^EhhZvI^JM0vYJ%8A+DS+@5UY<#t#l%IHKZ?**R+6DKD+JE1D3p^Zf z=O$=85_bUMwjm4l2913%QzwJy`WI;ngZkklIqg3rwv z(95&4Js3lxi5;d91T@oUfvGdMugkZ~iiQG0M!$OnPd(7B**6t2nt+ zK97?=7IUh-Fy)tw`g1b4uo7v8xmD_$`71Hk(wHFBy~EQZc0r~LLh6L1_x9;ja;lp* zW4d<-SgDHc6ujEzsNlb7PB6SKGx1$aR7^ty4u;jQDzCPI@cAm|h!BszXc(Xy`$ur8BN9u;86NBy(LNRCur*RMNbnQdT!pDU_v2I~H&ERo0NwGSw{i z&u^>6tmYA8h5Q%=1p5rc{4qTYj$q?NK}Zw{^`aU524O7UpF`x3{bQHt@AXIT z3L-M;sHw)?730Y&Hl0gq?@Vv}Qlx)K<`5Ki&|SM_81YK6WsKP8Uxe&cKf}*0L1<=s z`@QW*L8gb_`N2@_bk~~82uga*LJf8S85Qi^WI>DXPr&`E)QdOeHya;AkgMT3^n^HR z(?`l2d1=6pHIqK|pZiC0<}4I$;$t!2|7R_9F5_`#44gE~v6PC3_M@lGM-L8vBy$0m zZQ7l}>DK>VZ}bC7e1zVcfL$r`TMCbr@EaTl``16<*ZfTD5|q@R=E(Eaub$O$VGQ7E zP2cYxmQjU+Xo|2IZm7>r;-_4X|7|hq>>wTt$|s4-x_5+3H4lbYPG*!7@F@tP`yWFx zdtQhPG_15^Rpmsmle?0^EwJnlks{wQjn{HKFLARC#iSYxyM}z#wIddnv4leETn%}( z_MgkE08qpOo!GjB#0u8j{-EkWx?e|@hGDCEp>I7RH9LL`;0QG@>wwjUgF&1~(ZYw6 z`k6d#8L(gJj?4B0YxxjbdpmX{_xXe-a&+E4pqX5fWU%$tW~BOhq6{fyXZ#0WpZrI# z@yr2SsIp)1X6mE462oy!?-QPF?y?oDpzzwEzw8$s`0y)4ib!nZl%^9w7lft3=>(!33oJf50?(e~XCt&Br zXKjU&@CN{_I)MY`Yqq;8HZ6Sgmx)yDwlp^@dNo{;=>91BfBuR8hwstJ(fGOVbolAp zDL+&`N{~j#GmYg_wzImZy3E+3h5kXuzVur$a(hC{h)8@;(1{te`cV}dqnk5|+q!3mKWNS*!$wK9} z4DfKo>U+a5P?=EC3=r$s>10blr@PE>V<=~DqU&#+=@2&V?-hY0jJB1G+ zBe_E#i2e9>C0ZVkfbQ9g=4mQhFVujiOZ<2`+sZyiTeg|bj@AiPf@@rh#S3G;tLmGq z9vEzVQJP3?tg__}A_E2d50{r72 zn+{l^FlIOg;Y;P2O1p*FGBVTC;0+u9^bd&|$c!)KJJ6s>YqieFJA3}G1L)K;Z~qy( z&WniROk`nrb4i}y(f-s*J&%+T;4LJRiu8v1hMFF2C0om!_LVBp81`NlZ#DJ%jkDeZ z;aQw<9S<-C5ryqG`5$&YSyIza_X1<{*4lpibS&7{Z+3|@u9gV!)pdl8wMwHmK-6i@ zVH+Yhv)QadB0|~d*UY#^>dNf5?McnFR{Z2hrJuiE`qfy;rWtMy^Ri%Y%^HStbGb9a z3(&-kQzuR)?LO|RV3)=E&ise&l5N*01QubPs7K&Kd&xXDa(`tfxxtpmpcr2IP1Yi( zRy^2v>xCtae;_t<<=1v^+oJR{snd!#|91A*fD@-Fy;QPvIEaF*^6oH`)BQdX0ydY6 zb@S<6<{dI|T|_dIJ1jo#GkLDAs5{z9l)042Y5w47*LheyN&P%sXYFR6Yk5=B)Jw;*|ufmwVVAGpsMTd&}+dyjg~y3CL%>lxZFuiRe`!B?q**cN^zRn#}=TR#KMCd#2crX6#ux4GZvFM)H@ts)PFM(#Tv0A zB`Gcy{TJ4OFf-9d|fWBjv;hvNj?#4^>0dJp2qMk;3; z)JrK|7+ychb~_8lZuq1GVYOMSHumFrwdJq4ts=^OCCo|XI%TEcrSk51H2I1&5Ld36 z%IolHB>vkgjcWUUHU;NDJaMdQ*6{T4@Biq>@2*q44ANlI{mmxHZeJ0&zj~dhzw+-1 zr@BF`qk@uUh}N@Mfi1aid^faIT)JqHK)CsS!@BbZeg!S2lCAsU?cm;>=)MI`o$23T zW^d~B^jsa8l9k(69+AkrS5!YQkpZ232j=+OT$1;5%Dd=QWqW~p5+wNGZ zX~K9Xj^nxSdkssIT?#k?@&)4g@YF|avzQzYMcS)N*y=k!T|5U&$QKk* zsxYFtqUE}VQX$k~IbRJigZ9=p+6druiVc)E z4AE>VE(7Vsv%QY2=;E=HiG?b7D+*EQt+);vpmXla;I;4?W}jC-^V$WLGU+YX_g7C0 z9hd#)YBpu%#c3mY7=CGjPCewD<#u9+U~lrig=Q_NGyUWBL+JiY^8)O_m(>?HJTg5^H7Z*7zA`lOZ>kBppKz-V=bur*CprZ{BymWGYFt z^(S+c$~iJ3TK<>@t*30188S@wS%~cl2O?KDAyj5OC{< zC_CZ|BNdTu<*G=NZBVL9d$kbrKG4!w7_)D4izv1U}Y?&TXi zZ^Ygp{Bj5W_BWzoN~|e!?B7r&(6Jj|ci4pB&4u#(Kq2$hCnApBmqn`xVZ^)ciy&u! z%?90Ku5$RUZXdQ};DLtFj*6hu8#{6p5OcWXDaYM#B3NpY<_@Lr7Ur6{_}2p1EQ{Ln zse1i*G>6??+#+%72?NOg&@Ia`3GKCI9xl<}Xz0kX zP5mxViUmo(`k%lcVS#!2+s|)weDLpiosIOR)`u~%^Zhk>$9GR=WaCCY4nDc>qjh_j zBv}vlrMf&>wA!SlHlOT3!NDG3`|`qsNJ}Gi--K2Y&@vF#gfk3_dRt>Zt7EXPl`@;i z_Lxvdon=HFTs3H`6y5$U+{%G;Z!;G4@0Mp7Q-=83Iqnp9-5zgQ@w z1)X`GUub@YGnGD9zxI}*>L6M2cCYJo(9hL$t(7xUx%sbx^Qv;xfgL*Mzmc<;>otTe5oT#jBD(F|t*kcoisbAc5&ANj>xXO_ONwWI~{_ z6{Z+aM+o`IEseoQS7eh~LhPcd$j!B<|z?$XaelCh3 zS65eQAysoARh%H`>6pNh-RF$?%s*vI3yijrQzhh!-oH>a{7Qctd22KBG2|~~O1#vpc;BCDAHqDrs z-Z0KQmH-8B=%*1cZG)6Uwv~+3-eY}L9&O(Gj!g_WVBlYKm4v<%^ zJZ@d38x}_L`-k-y_MstLJI0t)`E6I)Z53(nC#QW+RF=Rx9+?%{ZaP4nP$%D3@~xix zPM}<+?5fEj$&zqBp`-^qN&_M9{I)ap)fT?Eb|$@^sm2F>y~=vh<8ry8t4Y6s(@y3Y z@Xor-P{_v-#(Uu%>}Bi0Djwv;bK~nj=^V_yr5_oAl!U2QIrKEL4`mQKukBwi>2AK@ zxZ2x7AKFet0mk|D4JMts^&BH9A@QT6U-=97xW>N?5Ni(U3;g3y{$Jv<^Ih&vSfsNY zpSqfjmP!4EU zYTVOlGKsBA>MeHg zkWt;0ifV*x?pgUYDjh`TkY}^u0^9!hmP#Y4#Vbn!Av#QFY8TI%x_P(|T{C`CHQRx) z4LDMxy#hWB&7xW}whnqPs|#?$o2`srIz7M_;dfiqW^NmD{kZOEc<{~5w-`NZD9^p% z#hynn?9tx%v(o-g6x<2*%OLZ{WX=xj`+?ig-akOjTlk@OyTQjo*^2JxVT zo2f=0hf}c6X`-?e{0Heb=%*Oyt;xUrx}6GPcNxa zrh5vPoR=+rr$FMZRfolgC_htR4^-7~w4C%ZmjHFGl)n?7OemyogZw7IQ)D}BDf`DQ zah}XXjHJ>((}*b{&Cb1tC%<@ZOpAurmp;Q6Mtfb`*{U=rA8Cs!#zKy8$s@AZG_z$j z=ZYOY4U+F=TXuE;`mpynNp)m^mwC*h-P&O6GO@q@mKYDMbhOp5e3a|TvPK=nY{j66*eLX8 za`>%OEYnt1-^=G1v&sOqt3W;kXFF&%w(Orb!_Ss_ied zt18oD*S2;SnlQe6(Ih*^K;(yBuKP_rv6*WIzDKHjD#ac5TgEb#mWw6H0^rxB!4(Qs zZ*uf{Wb7*TLypcuCd|1ybh9%L00fLs(${~^{-envkPdQTO2TRNQeXG= z+f9QX3VL~NU-c3+-D4vuuaKSFvFN#WK(6w4k1kbyau+p3n4`IO@wu<9t*y6@5B($g zI6S7im&f<+%~wFLw|6T#ZZ0An-4LT}3|yjGs05sc=yV?ONKO>5TsE3CkMv4F2)G#h z6kNVPeQ1RDNtl0jmm5?R<+*I%7ep%^G_p?m&&&NEL+k0XWI`caB5N#0W@a6^;!2DQ zjej1gNCIY^tW5)s80>D@*Ag^oWcql!TGMc}ito`;T1a+cP9@i9c|ag%U}G+znV zcP@A9r&<{L-BoL8me>{XuaXk*>f;9fR>Aq%V`<)#{hoHKU!K3Ca3$pT7NP~rke>X8 zhbAQ)eWxd^e#^83M-81c>Yg61Qun1k^47hT$!;i-%fd9BiL^LuWiw=rT9@oT8EZHR zGRo7mNO6DP7N;jPW3E5py_|q{d*wFcsXLNaEsu$U@TB~s0Fqpxm5gOs7Imz#HvKD< zHuHDxXPV=v@P)Ji^{F&kjjJ@9FHdBhL+B2>^VE_o#VRe?Z?M`|&kwaJo|bCp@0czLOn^bIg1&B4E*ET!3>}CCf5(;e)$7R7W6jUXM@2AO?Hj4sf=h zPs8EX1Elm+SF9ORCLD1rYT8lxDvL8k%AdwG4T$r5fll_W9QaYW5Us7NwdqNl`kjnep`VohtwL<7VGLa1_mtJ+w=mINs zTd0qE?!)_?*Q30F+40k3B~`O~cLXHnc;_#-MZS;wv{@K9epOs)IFbLkJd)Vn2QJWi zfGtEn=)!WImu=BLpj&ON=kYtpF#FB#>eP-|V@OBXgd%>d8u_x0NWWgMJvqSs+Q88+ zRvc7)tymt}Ww`+#Je^hS?E=g(hUA|9;4+pv)HhRdkz*S<5rPF7I$S)05a|(lRC>6X zJ30=FdB)P%{%;7ooMAvyS3ho`U$CDv3M1A46WVXCh{Qw_NtO0cjQun~xqLGR^-_#U z*5}c2#h2e1)J}%yVZt_Oa2VJER}&B3o^I}}-2Lm%AwC3Mqu!YGEU7!cyW9jvAmnON zK20`(iCW!^1y3E?pG09$D38WPou&2K>)h>Crq6uGC9x7O4WzINXongH0lK-fr-t#TS3iDacX|7W%NS69`*g56jF3`#5%m2m_c*Ax21#9B85{VN{;RsiZY~gSyipotay4lYg6{yy3$GuyoUiw2o-8=k zuM7WGy!={yP1dddM*icKR_3B1?^~r8oLr&wW4A(EdY10e!|4|B*cNKzwm$lQY-Y6h z<+>v=rUIsG+nkHu4(XK`a89$K=;{L;C0gaoCXbtoZhH9&EYPj4)?)Jms<5M}^HG2* z5juT1wQce@FPxp+URdUIgBZ)1*^|)kC(u#$)6B)bST7?B(6{gbH`gf&sT=Y#_T$<< z>BeS9`r4QeOok#2qgM*P)P!dpcJ|n;UT-tE;Amn8`}`+XugG$V#_(BMiDqeAf!;m2 zx5n^o0;#(3f5)VM?2KUvZBbXU2_0yro$^8jEPK~{AA0&)@@IY#)12xBC{x1j7O>|W z(_!FHeb(?B|0W7A<%;v!*8v;OWKto-BwRF5`U-I1Nx};DcyIebzeRnjXC(>TFTc7va>H#udg=9L#Pgfv zpZ(83goyAD5d{O3AGbazNp$JqDDtZopW>4jcR@422}Q*vXxP5MH1!daToJYb{^`O( zE=S5GGC&IdEe1*mT$kbhlAc{!Txx5FKCiT@D!Py=^N*?HYh;rn30RT-6Ak5Q$u{yP@t4pubk~ppE#Y@t0U(E@qIuJ+9#nYDxHC4!Q1$= z`zUqPuC4muZnbJ6>oZV@xm@fssWr(%c9A^X$H)En0KV6>lH>ROevCzengAwKP5lVh zplo*0>{XG`fyOt}!y_~d3=DmimX^t*A8@wtwfzdH;76QEmXGfPL9eqF<4ILBPEWMO zr&{wJK0WZODBiX7Yoe^VjJ{R|o8YO<-**0l-ZyStHoy>$HWN)~q(c~I3cMSdG zEtnhVgPeYdLKt>>R)FL=rTv;s!!c7=F`=h`R-gGj-{7i_FBLv>R=E{6ixMWc}@<2Gwp<6piH{;*{1_kqsK{0skGpvI_E)mq~r4hQn#S%Z%eAT zqMOQ`w&}BH;QM^7xxU~Na;tFL5m+RX($3So%T#De zFQ4UaTE}gkDdC4E1kh<PIkpV;xw=0(I1|SSmgqhBN zv~4x@#*?|aXOiG+Cub!74Yy2gI~l@+Q=(4qMHC+j13+f2x#+&s!3$&LiKY%#2NN}G zssH_+{|atDOAF4Fi?HrjyAFR5>3Thh7m9{)B^4j!rk$y`qL`9CjyX3o)4`?_4k$gq zuDmHBJk+w>xsn%N>Q#-Ij^8f=E4F5Z?N=YS=7L|{^p=0jYQ$L`l;BEv&a;0H$X}=X z-^1=SjL!wct$e9L&s&}N3v*>%H-pciV={dex;H9ISk;ucB}ofQkgY2P!?8bh3G(TT zXF=ry+E3?CKZh^Z0!p>@^-CQelc)RJAM%&a=*~YtkS#`cE6@Cu<)=R144L~nPyMoZ zr(PSUuGiBxHH|gYJ4*X-zhl#`x!KW2V-(T{fJZjIv_dFJpV9kp^0x?{jdOCHB43Qt zIb8?tb$s-W@p;)1AR6z4VoxGbVDN3ruiTA?8f}U zZM*hVfm7WiJHss#^dgt?BUqIw$!+MI+0S3q7(R)5@dOP`BR-W`!$c1uF$XjMaRR%{ z8NGNG_<^$YmdBQD!H9I4{OL-yM+ELD?$$-TTmih(U_pHNbIm}9`HVpnTnw z2~7(cw7{B<)MD>nX?Dr;7VZX8h8RtxW=K>P+nlF;qU?A10R}ZZ8?xDpL>S*FkL+oF zzI={hpCq-GFL6c8Ox9}FZ-+3u1=pUa%7z-Kyvx~5MVsZ0XfOG5F|lxyK(!=P<0;M{ z!A~^){#fU)`4*MoR2HpL!+!^-cVvqker$b|wTO$(je{5dFv%&&{E_$(YuE73Br;c! zL9XR{KM-mrl(&;xV(h1g*xJ|g9zGTi=t@Lh^iXfiv@*l)=-JU$?0S8B^~IRMp4ejA zhFko?hEi&xW8(CB%Y+gE^xE&`g(RgX+5Z**idb_@bdc88B{!B znxW$iZ=hA;+2w2tl`O3Pi^D-9&QMk=|JFL;ur$3D#MtQ*WOMc$d0TeHi9w}Sk8U0z z6h);FdhXL|w^HT-MRsVqw5mwGJ-g(*U_8l)=ortjR;d#OM%RVcJ7qyWdYp)=8qF7M zpBxqTue~p_VhMd?U(ydgrGg=C%6Ay<3SkFuYWSVh%)pySoMT*`ltku8`i8GInB^(W zoWE}6Ad(dD1a51aMjNGZ!Z2oGlH#MWc4rz#Q0Ccbhce6*Od7yc|IVNLpNK?Q_aNu@ z-NLRaI{>`$ z!OX;BT!r4`IA@lx&sD=o_GD(w)u;tyC%x61!r5J3|8iQlKBCZw4q`7_@tzd++X>Hu zvm?ewSJ%{3bL&^awra{T=VHXWhf!97GL5=?GBbqX5ei(1YIPbNT4J>_ZgU8iHYL#} zkUU{?hE{^X`SYBcO=2bt6M?VDEfNa7_KRX#T{24M*;)7CC_)YODqxrdS_|MrV@6ZH z#-bZ7GMDtYwW=*qw?P@0WS44q+he?WXQb$0t44UFl2r*~KiO*qxA{DJ&so}~Z zW{{J~qQ4sK)xUbdS{qdLl_%}kev#4Dbqh}o{aVPvk(7z0=i<7|!zeG>0yO25tgJ|p zUIt2=2~$uo&5zM>R%5W0%b$J1iO^ae_Hi*D%F7@2;2|2sq8C7J7t}l1+#>gU{KcGB z(&dJazO?X7{!OG^O*Dc^twNy5L0UPpXLRIxs(RaZ!d$0Gu;S7&Zdxx2qk()f?T|0N zuaJ#0@aM1SO>58hqd9T$_*xEU7ux)+Jd6m5jVrSg86HXg zN{~{@T(Q@&5Qw%CCA}$BQ+V6Rnc8f2B;Li%0u*UzaHb|!aE{hl1B5*oB61|{%b#;u z4VV2-;PA%skKX@wcoQwHl8mcC!Tq#fKp)LylDVG4G=`s?k8u*mzoU(^<@_ETw?y(R zndYMkDcO;R!oXfn^Q6ZL;$0jl#?#m*Cdri^fj5h(u(_C`Du$n*(@v5;21{e!av#Flv5_A?O$N5VDX7*kOF zJ&rG52G!)dq@L)5ERI!(x73&8&Kbp5m( zFdh-)AToPU*DBCl4rn*4%BbG1QiqmLSAuU}*u%sZF4SWN*5OvLvxqo#(w`jE;X3%j zpU=Dy(yY@+85k&DgTX~W#ebzVXSr1nR%155Wp_E(Un|E4orSVYpoV|15KQu zL+gzy6sf<4NmT&hd({I4K{?~n5dr>eb?@P>n@XA&lLv2Y^#Yjs4QuoTA zK#X#OJah0;`S9pTD7q5J%}}saN#VO7%t-!DDv@+m`R8@9H26$`dElGKF(`4V`F-xK z_2%r&*>`5rN6~7ysnpIHE2E}pFaiK8#LQYZd)v}G6$8tom`hF^R-Ag$_BA?fHYYd= zNTJqZJ zrDUY%rvcUX*d9IhduHTgy4mz=O?Ryd9!VaAD`ekdMtHE_rK(k=t2~qy9D!0A8fBXi zYj`PSt;KOuz%f!6XpYq>S232(F#df_i9M<-y~+SpWCiKmhOclGm)mV|aOkM}>f=lmPr==4$qKvRSarAD7%v)Pv!8fTa(YjVK$KOkwFK^cmA-?WKZg z+8_XIX2PCvNw2rocwD8Kgt%bVJLSHp$Mq~H1kcAq1<(=Njg?EBAaKQtR;)GmO#39fnkumCe0C1Uq%t4Tv*m_Ulb+ zSUt4qYH|cBj!P&UiPb5mZ<3ocSe)th+_T8@B!2lDryZaxcz~uqVp?&_8$#0KubeZJ z)HxYzc&sc&igd&EE@P(y^6)O|_j+42w@jUR6kHxPbc_>b+@%hs z7(Qx!i+CW{GA(|qcfe2Z0d*gx`p$HIT&gsUZySzippzbm`SNt-%z_xNA?Agk=s*g@>C>6j5(diI|H}j7rsO10oO086F{TUyh|f zjeU=p?vFXmdztJb`ncQkPdSZ|H&J1Z_n4Mk9LL@6H91u0f0q9OVs=W40D#Nc)^=(#&v3P?t$ zw-;HR$qih*!jx~xj-*ta)foLE$OD>3od#w~kGKJ*fQhDNYJFTdI;8;?E!J_a)L4g` zq0QD@%u@RJ59*UhwDm56%I;Wd7I#M$6>FclOFl(p?^G+V7H#gNzW`@ruZ~8%Je2Xn zX9#<$HbCERwW#)wQcL1@&~4~~`8`gqAGr{8Ul>HaC)k`R`~;KchMIkjE@nBFifHdm zkP?8H$$&)KwVG?|8kX!#F2^Rpkgb(|0DtB1G3pd@jjN-c;b36W-lbpx{J8R`W}|8{ z7OV<_zs$5{XlAZ7Y5G^c*Ihu3hsvZUnt%B&#m(X9scUr0uew;{l`m20KZx9^?Q|QKaX~oNSwZ6!sgwdEae9(tF=vHNFJti)tD_99#|4L8hOwR0~zdU4kYot*l5> z*YE$~$J~K$g{sPO9=vq##S_aC;##d}${aT)7SGwu&gqe|S^=9n<6EG0K~ z3G%m!Z(?R0izD{;yez=3)dW){hATfkK_{F?z-IvF=H)&zl|LSE?$_6>E1y|g`67-4 z6j+V3>7vd~UAtSHGo$(T(Z!c0Z+<}r_Gv;K-I+E%rf-W!)Or||p5=*-G#;_xR>?KJ(9Hz>r+kaD}d#0JjM-> zQ!IH?dgh7j3rOkRH}=#NAq~1zI@l*3adPzIIa&((T(73DW+XS<>{#zR*SkVTO|Ei) zB-lK`TDNNI+y?4GP%F{$3%H#}F%W{IC+hzJ?QR(a&{h5?{Vpmt1TejpNw1T;SUwxT zTx?e~-Rz)nqt&VDHnc5t9{0#q9?8?(5GuF^0Wn{JOI~J)MEVIRL^U^$f5`h>GUThf~KdW$v@0AS-lGkVxF{G_&#U0Ha6#?VN3fM zb-}k)&S!q#Oha$lt|`%~d1fJ46p|}i{uMY@SNF-uF8r#!IO&-Kh?afSK_yEfj%Q<$ zhM<({u0A-QWA#%sH8`V`7`MYRuzxos+lCtfzKd=PBB>(eXIE_1yKQ@QrW#{Q49g{t}a?PV*&S68yw6$S~%xfz|# zM_dDrJkR!mE@V`YV}VHg8!Snf+dDZjJ(Qu*rkmk~3rd7by;TPSc?N&jczOb8hVOe9 z@zO-$Cha_pAZV4;hO8>OA z(YMdn@0@Qk$!6YIM6tx0u;o=Ow{z2xKOeoTS94_;vhB$7Wav0&W6rT@1)U<_ZPQ-~ z)N=ee37I(QpVo~M$!5?4(LwlIG^oZs2Etl%a7zN5??d9{%FvAvL%j>9WruEM=JPGz zA?@j<&9qeS?VE2F#x#(hDdl_eV-pTljyLVcD+eGpQCL>)++;yt*j%bWy$8hyfTILCjk)_xn2cOWeOA9Os_Dp0Sv+FqrPzov3{ zKrni>c7g6Ae%QE4V`}8DT~)6n#>}-i)!qRRv7ZQnNj%ByOH?z`tF5C5+INCA1EI#8 z2s%iwXoa-Omlw*NmPki^o-~#q$%3r8laLX&W}oU=N)(=Si8rC=*(#_(EXv!2~s8FD25vXbGJ>y=p|N4n-I z`eagM+BcL+14-gOPWhcf`HcUqSpP3>;ax3}H*|46&A1$xfc4kB zIemgzB>V}W@^5kvi?;26ajC2?P2##1W zS$92Rvh%P9p;q-k9#6i{ONb}8Yb;D0ZZTZ{A%wTChKUp`@xu!iKgv3pI^DTQYZiDa z^f$QN3a4GP;Qp@?{as&*a35L{V7+43y>I)$USm4vI`@|&=&O;I3e{@kO$`iMfu^wF zte51EnwYNgGz-ZjDZ!XX%$o|XoSC-+rJG0k$3rXfqfZK-YAhI)!+Kn)!jCX_f!uG~q$D`qM2LlKED0+amu1=5 z%E}V{y1Uc82f&-I5PA#}Vr-dxOXPK24d;-&n6j*-7vnhbwG9q2%DIlKlBw)ws59eqz=Sx}ChWQmZ z@v+*NDj4)_z>QaPrmn!iZC}4Ya>Qg&benBvX~BQ^r~jrG7G97|wDU`QVm2Ji7vv>#1-e0A3t`a(?{-Ng=Nd4Mry4e9;c`1N)yOifJ(Y=jjZzN& zyk~J}PclsQrq67BR{ILPMj3eAC39=v)_&u?eQQf$vzJCOOz?Q&K>wQ*;q1nCtaAh5 z2-W!_moSuioV&&SPi%d@Cw$*ll%i75q->iT*f0%VIku6rqfgvD1v(pN&a6weu8f}k zmKoFcoG2@jTfT_5^V#cb^_V~J3CMA$FBlPM+xGuqd^9Om-Xe!q&jC|6IkZkSO;zMq zY>PwmAa5255xF9%$6>B%vn>}}wu*1{{Pa3Zz#7sZf^}e7(srG_Jd4J<=X6RBPg?H@ z`ASOj5341bgr=n>ql6|A4}*fdyNoI=7#%Qwg48iiOKdu7{HLg_tZaK3MTvt-*FpALU!;b{^>uo59M!s!vOz*<(l+KCX<}Xu9G5H!|7EWCvLY1m+=qB zk8R_BAfJ=%`2F!AJ5fuZ9KpW?`n3(d;i6$(k6R%TTJZ{cC-&o$H@$%1FJG<~$qd0wDEKif-6(+eKoJBfIbTb}?$Z-SP-zwgEa#(K<_v|*tu>&`Pd zb&)D3<9Xw_#?Ec-k|ey5JI!@4=R(F>=65!6f-nHP7(PfjN}piR+MGMsJ^si-BYqQb zOn3^SI9Fv|) zbP&GFkQDi$IBRllK?*Zz|7MAhUW8$y{OQr~vkWhibjPe}W{79D+VgTV_k*58tlHa@ zvm0E2X|R8b@YhmJ&1S?na`Dqtb5SGQk0x!R(f5HrVCrx|C|4^(r1`b|n5ss~-=ys` z!)LUMUQ-=e`#%(}z&>;yEJZb$F0%bFFztwpusx~cCVgX`RjsDM38P+`EVP}=eQeui zC?jL+=rm$AGlp?(lEj|N@1{&+SnOcRB8%^2ND?k;Mj?w#K^W0QG4Ofn+ugruyD2@R z=ivSODHri*`vV#Y9ts-#=doGHHje2y%K`iIEoa7LzXhkJrU0ngYSFlD8t38tr!_Kh z+R3ot`;&4~;;`l5dF7FeGWqIHIOCE=dL6X*0 zw=h7Ve8Jm^#Z|1|N-q zpNp51UC6IIx_up@+YjQ|v@V`1#30nQZue+;m z!AD>gNGb=4mGeiz56~W^${!&4_w@YB=q@}Wn~83~ zn(+dP+w%8Kusby)!&^!l216@D{SBFMEJIHn*6Wr|9^KT#(wD)yz*DGJMqH{7bloKI z%;$KS>7g}~F5kdD&NbXe0o(L3{++~txx&J}4i9r5a(xy6Uo(kdZR!^6@He^v>h<0w ztdzB0`N>E-BBjdg4{CUN)twzZ9c(+l)%=nw-8SWh&+aOhiAiZ#!8@m&InHG~*3QRC z=4!OpPbW)d_N0)nZCcaJ?-JW42+3tg@_Iw|6Bx7Pe+etuwDWII>bods=btBUJ)u+^i(E7_ zV#oUvx7(mbb4lAd?P*o>7Cmfg=%N-U_aE}00-g)BA2BJkGu%^WOYsvqZmEh-&T6aR zu7;-@YXY6gLtgh7fWJU|wg(RvJz8p;9iW*jVPa-Y580&pRKD?DxXN0mefksVoJWwy z?E}KaqJ4@t_1VfRb{NV}KJfVr9KaiApr)pFl_lTdyo4WTW*mJS$BI3Y_)P4DBPfs0 zvjnl`_)pGtBwt@S3RU%WGj))ToInSxer?tg4lhHgWebuU*Nr)S}Kt)<@2VbX-Zl!aym8-vIOf&wb9dzsT|Eks>>tpQ2HzQ5TH^kO}Z#;QBOfoU+i4uiTC6?e#t9Ymc`HTRC6 zs}5;f2NT8y3?IrE;jbKLE7CaF7($7y1(oi{&$a7a<_&o(Hb^Lp<6T2?jJd`qy{AKE zKe-5Tt{!5Q@n)43X!{x|H}SF1RI%};y9JtC91Z440w&UVaqLmoYZ4t&{@5Exj7EBt z8ZCg2%wo%2yPcr9YQqBrajUk!TP_m!E|a8Y9=^`@$X~)TWigH%6qcr)F}`=s^z>Gw z^wJ&*H{GQvM3TYk^#&D}sw8_;fxW2cgZ^cA0Yq#5UmBSIbtCpe&P7&G|NO zG5}XsE9iO6OnE2{JO3iZ&T>@?3eFr~zF@+PdQIFk;QE!TqN}};gnd}SjXrfps`kf& zhH%EN<_@_~2o)8@iK_?>wl&}D^iFlsbhG4qkH4%Jp^Eiyl2Sir zPRvd3TwGj84Xs?i8X0VX5w=4)ee9J`e+Ir*_HU%A+t2h)Pdd&^NhNNN&~dC

    PWx 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

    K*dNaxwo8;!dM9~S(Z+H7qiT;7 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 z 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

    t3<&#)|w2aF#TI@40R- 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

    AUTIp@RqAC))Sr9f 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 literal 0 HcmV?d00001 diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py new file mode 100644 index 00000000..910300d3 --- /dev/null +++ b/tests/integration/__init__.py @@ -0,0 +1 @@ +"""Integration tests using documents produced by external applications.""" diff --git a/tests/integration/test_word_roundtrip.py b/tests/integration/test_word_roundtrip.py new file mode 100644 index 00000000..ef4ef061 --- /dev/null +++ b/tests/integration/test_word_roundtrip.py @@ -0,0 +1,131 @@ +"""Round-trip tests for documents produced by Microsoft Word.""" + +from __future__ import annotations + +import io +from pathlib import Path +from typing import Any +from zipfile import ZipFile + +from lxml import etree + +from docx import Document + +FIXTURE_DIR = Path(__file__).parent.parent / "fixtures" + +A_NS = "http://schemas.openxmlformats.org/drawingml/2006/main" +ASVG_NS = "http://schemas.microsoft.com/office/drawing/2016/SVG/main" +CT_NS = "http://schemas.openxmlformats.org/package/2006/content-types" +PR_NS = "http://schemas.openxmlformats.org/package/2006/relationships" +R_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships" +W_NS = "http://schemas.openxmlformats.org/wordprocessingml/2006/main" +WP_NS = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" + + +def _fixture(*parts: str) -> Path: + return FIXTURE_DIR.joinpath(*parts) + + +def _round_trip(path: Path) -> dict[str, bytes]: + document = Document(io.BytesIO(path.read_bytes())) + document.add_paragraph("Round-trip verification") + + output = io.BytesIO() + document.save(output) + + reopened = Document(io.BytesIO(output.getvalue())) + assert reopened.paragraphs[-1].text == "Round-trip verification" + + with ZipFile(io.BytesIO(output.getvalue())) as package: + return {name: package.read(name) for name in package.namelist()} + + +def _xml(package: dict[str, bytes], partname: str) -> Any: + return etree.fromstring(package[partname]) + + +def _relationship_target(package: dict[str, bytes], relationship_id: str) -> str: + relationships = _xml(package, "word/_rels/document.xml.rels") + relationship = relationships.find(f"{{{PR_NS}}}Relationship[@Id='{relationship_id}']") + assert relationship is not None + target = relationship.get("Target") + assert target is not None + return target + + +def _content_type(package: dict[str, bytes], partname: str) -> str | None: + content_types = _xml(package, "[Content_Types].xml") + override = content_types.find(f"{{{CT_NS}}}Override[@PartName='{partname}']") + if override is not None: + return override.get("ContentType") + + extension = partname.rsplit(".", 1)[-1] + default = content_types.find(f"{{{CT_NS}}}Default[@Extension='{extension}']") + return None if default is None else default.get("ContentType") + + +class DescribeWordDocumentRoundTrips: + def it_round_trips_a_minimal_word_document_in_memory(self): + package = _round_trip(_fixture("documents", "word-blank.docx")) + + assert "word/document.xml" in package + assert "word/styles.xml" in package + assert not any(name.startswith("word/media/") for name in package) + + def it_preserves_a_floating_picture(self): + package = _round_trip(_fixture("drawing", "word-floating-picture.docx")) + document = _xml(package, "word/document.xml") + + anchor = document.find(f".//{{{WP_NS}}}anchor") + assert anchor is not None + assert anchor.get("behindDoc") == "1" + position_h = anchor.find(f"{{{WP_NS}}}positionH") + position_v = anchor.find(f"{{{WP_NS}}}positionV") + assert position_h is not None + assert position_v is not None + assert position_h.get("relativeFrom") == "column" + assert position_v.get("relativeFrom") == "paragraph" + assert anchor.find(f"{{{WP_NS}}}wrapTight") is not None + + blip = anchor.find(f".//{{{A_NS}}}blip") + assert blip is not None + relationship_id = blip.get(f"{{{R_NS}}}embed") + assert relationship_id is not None + target = _relationship_target(package, relationship_id) + assert f"word/{target}" in package + + def it_preserves_an_svg_image_and_its_png_fallback(self): + package = _round_trip(_fixture("images", "word-svg-image.docx")) + document = _xml(package, "word/document.xml") + + blip = document.find(f".//{{{A_NS}}}blip") + svg_blip = document.find(f".//{{{ASVG_NS}}}svgBlip") + assert blip is not None + assert svg_blip is not None + + png_relationship_id = blip.get(f"{{{R_NS}}}embed") + svg_relationship_id = svg_blip.get(f"{{{R_NS}}}embed") + assert png_relationship_id is not None + assert svg_relationship_id is not None + png_target = _relationship_target(package, png_relationship_id) + svg_target = _relationship_target(package, svg_relationship_id) + assert png_target.endswith(".png") + assert svg_target.endswith(".svg") + assert f"word/{png_target}" in package + assert f"word/{svg_target}" in package + assert _content_type(package, f"/word/{svg_target}") == "image/svg+xml" + + def it_preserves_distinct_latin_and_east_asian_fonts(self): + package = _round_trip(_fixture("fonts", "word-east-asian-fonts.docx")) + document = _xml(package, "word/document.xml") + + chinese_run = next( + run + for run in document.findall(f".//{{{W_NS}}}r") + if (text := run.find(f"{{{W_NS}}}t")) is not None and "全局笔记" in (text.text or "") + ) + fonts = chinese_run.find(f"{{{W_NS}}}rPr/{{{W_NS}}}rFonts") + assert fonts is not None + assert fonts.get(f"{{{W_NS}}}ascii") == "Open Sans" + assert fonts.get(f"{{{W_NS}}}hAnsi") == "Open Sans" + assert fonts.get(f"{{{W_NS}}}eastAsia") == "宋体" From 45e0fab3408cc1e3a3ecc19c10ab6c241e94d097 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 21 Aug 2026 18:14:36 +0800 Subject: [PATCH 087/115] Add safe Custom XML part naming --- src/docx/parts/customxml.py | 17 ++- src/docx/parts/document.py | 4 +- tests/fixtures/README.md | 16 +++ tests/fixtures/customxml/generate_fixture.py | 127 ++++++++++++++++++ .../customxml/multiple-custom-xml-parts.docx | Bin 0 -> 11812 bytes tests/integration/customxml/__init__.py | 1 + .../customxml/test_custom_xml_roundtrip.py | 90 +++++++++++++ tests/parts/test_customxml.py | 19 +++ 8 files changed, 266 insertions(+), 8 deletions(-) create mode 100644 tests/fixtures/README.md create mode 100644 tests/fixtures/customxml/generate_fixture.py create mode 100644 tests/fixtures/customxml/multiple-custom-xml-parts.docx create mode 100644 tests/integration/customxml/__init__.py create mode 100644 tests/integration/customxml/test_custom_xml_roundtrip.py diff --git a/src/docx/parts/customxml.py b/src/docx/parts/customxml.py index 5597d4fa..45c4426e 100644 --- a/src/docx/parts/customxml.py +++ b/src/docx/parts/customxml.py @@ -1,6 +1,7 @@ """ |CustomXmlPart| and closely related objects """ + from lxml import etree from lxml.etree import fromstring @@ -17,17 +18,21 @@ class CustomXmlPart(XmlPart): @classmethod def default( cls, - file_name: str, + file_name: str | None, content_type: str, xml: str, package: OpcPackage, ) -> "CustomXmlPart": - """ - Create a default xml file in /customXml/*file_name*.xml - with default content *xml* and type *content_type* - """ + """Create a Custom XML part with a unique package partname.""" + if file_name is None: + partname = package.next_partname("/customXml/item%d.xml") + else: + partname = PackURI(f"/customXml/{file_name}.xml") + if any(part.partname == partname for part in package.iter_parts()): + raise ValueError(f"part already exists at '{partname}'") + return cls( - PackURI(f"/customXml/{file_name}.xml"), + partname, content_type, fromstring(xml), package, diff --git a/src/docx/parts/document.py b/src/docx/parts/document.py index 59124bd9..442861cb 100644 --- a/src/docx/parts/document.py +++ b/src/docx/parts/document.py @@ -36,9 +36,9 @@ class DocumentPart(StoryPart): """ def add_custom_xml_part( - self, xml: str, file_name: str = "item1", content_type: str = CT.XML + self, xml: str, file_name: str | None = None, content_type: str = CT.XML ) -> CustomXmlPart: - """Add a file in /customXml/*file_name*.xml with default content *xml*.""" + """Add a Custom XML part, using the next available `itemN.xml` by default.""" part = CustomXmlPart.default(file_name, content_type, xml, self.package) return self.rels.get_or_add(RT.CUSTOM_XML, part).target_part diff --git a/tests/fixtures/README.md b/tests/fixtures/README.md new file mode 100644 index 00000000..3f0b8e05 --- /dev/null +++ b/tests/fixtures/README.md @@ -0,0 +1,16 @@ +# Integration fixtures + +These documents were created with Microsoft Word and are retained as external +compatibility samples. Tests may open, modify, save, and reload copies in memory, but +must not rewrite the fixture files in place. + +| Fixture | Primary behavior | +| --- | --- | +| `documents/word-blank.docx` | Minimal Word-created package | +| `drawing/word-floating-picture.docx` | Anchored PNG with tight wrapping and explicit positioning | +| `images/word-svg-image.docx` | SVG image with Word-generated PNG fallback | +| `fonts/word-east-asian-fonts.docx` | Separate Latin and East Asian run fonts | +| `customxml/multiple-custom-xml-parts.docx` | Generated package with `item1` and `item3` plus data-store properties | + +The Custom XML fixture is generated by `customxml/generate_fixture.py` from the +Word-created blank document. Run that script from the repository root to rebuild it. diff --git a/tests/fixtures/customxml/generate_fixture.py b/tests/fixtures/customxml/generate_fixture.py new file mode 100644 index 00000000..049f47af --- /dev/null +++ b/tests/fixtures/customxml/generate_fixture.py @@ -0,0 +1,127 @@ +"""Generate the multiple-Custom-XML-parts integration fixture.""" + +from __future__ import annotations + +from pathlib import Path +from xml.etree import ElementTree +from zipfile import ZIP_DEFLATED, ZipFile, ZipInfo + +FIXTURE_ROOT = Path(__file__).parent.parent +SOURCE = FIXTURE_ROOT / "documents" / "word-blank.docx" +TARGET = Path(__file__).parent / "multiple-custom-xml-parts.docx" + +CONTENT_TYPES_NS = "http://schemas.openxmlformats.org/package/2006/content-types" +DATA_STORE_NS = "http://schemas.openxmlformats.org/officeDocument/2006/customXml" +RELATIONSHIPS_NS = "http://schemas.openxmlformats.org/package/2006/relationships" +CUSTOM_XML_RELATIONSHIP = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml" +) +CUSTOM_XML_PROPS_RELATIONSHIP = ( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps" +) +CUSTOM_XML_PROPS_CONTENT_TYPE = ( + "application/vnd.openxmlformats-officedocument.customXmlProperties+xml" +) + + +def _serialize(element: ElementTree.Element) -> bytes: + return ElementTree.tostring(element, encoding="utf-8", xml_declaration=True) + + +def _zip_info(name: str) -> ZipInfo: + info = ZipInfo(name, date_time=(1980, 1, 1, 0, 0, 0)) + info.compress_type = ZIP_DEFLATED + return info + + +def _add_content_types(parts: dict[str, bytes]) -> None: + ElementTree.register_namespace("", CONTENT_TYPES_NS) + root = ElementTree.fromstring(parts["[Content_Types].xml"]) + for number in (1, 3): + ElementTree.SubElement( + root, + f"{{{CONTENT_TYPES_NS}}}Override", + PartName=f"/customXml/itemProps{number}.xml", + ContentType=CUSTOM_XML_PROPS_CONTENT_TYPE, + ) + parts["[Content_Types].xml"] = _serialize(root) + + +def _add_document_relationships(parts: dict[str, bytes]) -> None: + ElementTree.register_namespace("", RELATIONSHIPS_NS) + path = "word/_rels/document.xml.rels" + root = ElementTree.fromstring(parts[path]) + for relationship_id, number in (("rId8", 1), ("rId9", 3)): + ElementTree.SubElement( + root, + f"{{{RELATIONSHIPS_NS}}}Relationship", + Id=relationship_id, + Type=CUSTOM_XML_RELATIONSHIP, + Target=f"../customXml/item{number}.xml", + ) + parts[path] = _serialize(root) + + +def _custom_xml_parts() -> dict[str, bytes]: + return { + "customXml/item1.xml": b""" + + Alice + Bob + +""", + "customXml/item3.xml": b""" + + Paper + Ink + +""", + } + + +def _property_parts() -> dict[str, bytes]: + parts: dict[str, bytes] = {} + for number, item_id in ( + (1, "11111111-1111-1111-1111-111111111111"), + (3, "33333333-3333-3333-3333-333333333333"), + ): + properties = ElementTree.Element( + f"{{{DATA_STORE_NS}}}datastoreItem", + {f"{{{DATA_STORE_NS}}}itemID": f"{{{item_id}}}"}, + ) + ElementTree.SubElement(properties, f"{{{DATA_STORE_NS}}}schemaRefs") + parts[f"customXml/itemProps{number}.xml"] = _serialize(properties) + + relationships = ElementTree.Element(f"{{{RELATIONSHIPS_NS}}}Relationships") + ElementTree.SubElement( + relationships, + f"{{{RELATIONSHIPS_NS}}}Relationship", + Id="rId1", + Type=CUSTOM_XML_PROPS_RELATIONSHIP, + Target=f"itemProps{number}.xml", + ) + parts[f"customXml/_rels/item{number}.xml.rels"] = _serialize(relationships) + return parts + + +def build_fixture() -> None: + """Build the deterministic fixture at `TARGET`.""" + with ZipFile(SOURCE) as source: + source_infos = source.infolist() + parts = {info.filename: source.read(info.filename) for info in source_infos} + + _add_content_types(parts) + _add_document_relationships(parts) + parts.update(_custom_xml_parts()) + parts.update(_property_parts()) + + source_names = {info.filename for info in source_infos} + with ZipFile(TARGET, "w") as target: + for info in source_infos: + target.writestr(info, parts[info.filename]) + for name in sorted(parts.keys() - source_names): + target.writestr(_zip_info(name), parts[name]) + + +if __name__ == "__main__": + build_fixture() diff --git a/tests/fixtures/customxml/multiple-custom-xml-parts.docx b/tests/fixtures/customxml/multiple-custom-xml-parts.docx new file mode 100644 index 0000000000000000000000000000000000000000..0bf50af6ad539a9bfaebc066b19f4f4357897522 GIT binary patch literal 11812 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 QJwzZAK#@T{#qVGL1MOL$Gynhq literal 0 HcmV?d00001 diff --git a/tests/integration/customxml/__init__.py b/tests/integration/customxml/__init__.py new file mode 100644 index 00000000..d183673b --- /dev/null +++ b/tests/integration/customxml/__init__.py @@ -0,0 +1 @@ +"""Custom XML integration tests.""" diff --git a/tests/integration/customxml/test_custom_xml_roundtrip.py b/tests/integration/customxml/test_custom_xml_roundtrip.py new file mode 100644 index 00000000..70824204 --- /dev/null +++ b/tests/integration/customxml/test_custom_xml_roundtrip.py @@ -0,0 +1,90 @@ +"""Round-trip tests for packages containing multiple Custom XML parts.""" + +from __future__ import annotations + +import io +from pathlib import Path +from typing import Protocol, cast +from zipfile import ZipFile + +import pytest + +from docx import Document +from docx.document import Document as DocumentType +from docx.parts.customxml import CustomXmlPart + +FIXTURE = ( + Path(__file__).parent.parent.parent + / "fixtures" + / "customxml" + / "multiple-custom-xml-parts.docx" +) +CUSTOMERS_NS = "urn:python-docx-oss:customers" +INVENTORY_NS = "urn:python-docx-oss:inventory" +AUDIT_NS = "urn:python-docx-oss:audit" + + +class _CustomXmlPartProtocol(Protocol): + def add_item(self, tag: str, text: str = "", **attrib: str) -> None: ... + + +def _parts_by_name(document: DocumentType) -> dict[str, CustomXmlPart]: + return {str(part.partname): part for part in document.part.custom_xml_parts} + + +class DescribeMultipleCustomXmlParts: + def it_loads_multiple_namespaced_parts_with_non_contiguous_names(self): + document = Document(io.BytesIO(FIXTURE.read_bytes())) + parts = _parts_by_name(document) + + assert set(parts) == {"/customXml/item1.xml", "/customXml/item3.xml"} + assert parts["/customXml/item1.xml"].tag == f"{{{CUSTOMERS_NS}}}customers" + assert parts["/customXml/item3.xml"].tag == f"{{{INVENTORY_NS}}}inventory" + assert len(parts["/customXml/item1.xml"].items) == 2 + assert len(parts["/customXml/item3.xml"].items) == 2 + + def it_round_trips_create_update_and_delete_operations_in_memory(self): + document = Document(io.BytesIO(FIXTURE.read_bytes())) + parts = _parts_by_name(document) + customers = parts["/customXml/item1.xml"] + inventory = parts["/customXml/item3.xml"] + + cast(_CustomXmlPartProtocol, customers).add_item( + f"{{{CUSTOMERS_NS}}}status", + "active", + source="round-trip", + ) + inventory.delete_item(inventory.items[0]) + document.part.add_custom_xml_part( + f'created', + ) + + output = io.BytesIO() + document.save(output) + reopened = Document(io.BytesIO(output.getvalue())) + reopened_parts = _parts_by_name(reopened) + + assert set(reopened_parts) == { + "/customXml/item1.xml", + "/customXml/item2.xml", + "/customXml/item3.xml", + } + status = reopened_parts["/customXml/item1.xml"].items[-1] + assert status.tag == f"{{{CUSTOMERS_NS}}}status" + assert status.text == "active" + assert status.attrib["source"] == "round-trip" + assert len(reopened_parts["/customXml/item3.xml"].items) == 1 + assert reopened_parts["/customXml/item2.xml"].tag == f"{{{AUDIT_NS}}}audit" + + with ZipFile(io.BytesIO(output.getvalue())) as package: + names = set(package.namelist()) + assert "customXml/itemProps1.xml" in names + assert "customXml/itemProps3.xml" in names + assert "customXml/_rels/item1.xml.rels" in names + assert "customXml/_rels/item3.xml.rels" in names + + def it_rejects_an_explicit_partname_collision(self): + document = Document(io.BytesIO(FIXTURE.read_bytes())) + + with pytest.raises(ValueError, match="part already exists at '/customXml/item1.xml'"): + document.part.add_custom_xml_part("", file_name="item1") diff --git a/tests/parts/test_customxml.py b/tests/parts/test_customxml.py index 9edb486b..32c3ac5c 100644 --- a/tests/parts/test_customxml.py +++ b/tests/parts/test_customxml.py @@ -1,6 +1,7 @@ import pytest from docx.opc.constants import CONTENT_TYPE as CT +from docx.opc.packuri import PackURI from docx.parts.customxml import CustomXmlPart @@ -23,6 +24,24 @@ def test_delete_item(self, custom_xml_part): assert custom_xml_part.items[0].tag == "bar" assert len(custom_xml_part.items) == 1 + def test_uses_next_available_partname_by_default(self, mocker, default_xml): + package = mocker.MagicMock() + package.next_partname.return_value = PackURI("/customXml/item2.xml") + + part = CustomXmlPart.default(None, CT.XML, default_xml, package) + + package.next_partname.assert_called_once_with("/customXml/item%d.xml") + assert part.partname == "/customXml/item2.xml" + + def test_rejects_an_explicit_partname_collision(self, mocker, default_xml): + package = mocker.MagicMock() + existing_part = mocker.MagicMock() + existing_part.partname = PackURI("/customXml/item1.xml") + package.iter_parts.return_value = iter([existing_part]) + + with pytest.raises(ValueError, match="part already exists at '/customXml/item1.xml'"): + CustomXmlPart.default("item1", CT.XML, default_xml, package) + @pytest.fixture def custom_xml_part(self, mocker, default_xml): return CustomXmlPart.default("default_file", CT.XML, default_xml, mocker.MagicMock()) From 5d81836cc65abe25e39cb059adb0aed6cb200332 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 21 Aug 2026 18:14:44 +0800 Subject: [PATCH 088/115] Add Python 3.14 CI coverage --- .github/workflows/ci.yml | 84 +++++++++++++++++++++++++++++ pyproject.toml | 1 + requirements-test.txt | 2 +- src/docx/image/emf.py | 2 +- tests/image/test_emf.py | 5 +- tests/image/test_svg.py | 1 - tests/opc/parts/test_customprops.py | 2 - tests/opc/test_customprops.py | 11 ++-- tests/opc/test_phys_pkg.py | 4 +- tests/opc/test_rel.py | 4 +- tests/oxml/test_xmlchemy.py | 5 +- tests/text/test_font.py | 10 +++- tests/unitutil/cxml.py | 6 +-- tox.ini | 2 +- 14 files changed, 118 insertions(+), 21 deletions(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..eb8e713f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,84 @@ +name: CI + +on: + push: + branches: [master] + pull_request: + branches: [master] + +permissions: + contents: read + +jobs: + test: + name: Python ${{ matrix.python-version }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ["3.12", "3.13", "3.14"] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + cache: pip + cache-dependency-path: | + requirements.txt + requirements-test.txt + + - name: Install test dependencies + run: | + python -m pip install --upgrade pip + python -m pip install --editable . --requirement requirements-test.txt + + - name: Run unit and integration tests + run: python -m pytest -q + + - name: Run acceptance tests + run: python -m behave --format progress --stop --tags=-wip + + quality: + name: Integration quality and package build + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: "3.12" + cache: pip + cache-dependency-path: | + requirements.txt + requirements-test.txt + + - name: Install development tools + run: | + python -m pip install --upgrade pip + python -m pip install --editable . --requirement requirements-test.txt pyright build + + - name: Check formatting + run: | + python -m ruff format --check \ + tests/integration \ + tests/fixtures/customxml/generate_fixture.py + + - name: Run lint checks + run: | + python -m ruff check \ + tests/integration \ + tests/fixtures/customxml/generate_fixture.py + + - name: Run type checks + run: | + python -m pyright \ + tests/integration \ + tests/fixtures/customxml/generate_fixture.py + + - name: Build distributions + run: python -m build diff --git a/pyproject.toml b/pyproject.toml index e720bdd0..7b810654 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,7 @@ classifiers = [ "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Topic :: Office/Business :: Office Suites", "Topic :: Software Development :: Libraries", ] diff --git a/requirements-test.txt b/requirements-test.txt index 97282cbb..16fded72 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,6 +1,6 @@ -r requirements.txt behave>=1.2.3 -pyparsing>=2.0.1 +pyparsing>=3.2.3 pytest>=2.5 pytest-coverage pytest-xdist diff --git a/src/docx/image/emf.py b/src/docx/image/emf.py index dd66ebd8..771c549f 100644 --- a/src/docx/image/emf.py +++ b/src/docx/image/emf.py @@ -43,4 +43,4 @@ def from_stream(cls, stream): xdpi = 2540.0 * (x1 - x0) / (frame[2] - frame[0]) ydpi = 2540.0 * (y1 - y0) / (frame[3] - frame[1]) - return cls(x1 - x0, y1 - y0, xdpi, ydpi) \ No newline at end of file + return cls(x1 - x0, y1 - y0, xdpi, ydpi) diff --git a/tests/image/test_emf.py b/tests/image/test_emf.py index dcc7294c..26f9f392 100644 --- a/tests/image/test_emf.py +++ b/tests/image/test_emf.py @@ -2,9 +2,10 @@ from __future__ import absolute_import, division, print_function, unicode_literals +import io + import pytest -import io from docx.image.emf import Emf from docx.image.helpers import LITTLE_ENDIAN, StreamReader @@ -38,4 +39,4 @@ def from_stream_fixture(self): xdpi = 2540.0 * (x1 - x0) / (frame[2] - frame[0]) ydpi = 2540.0 * (y1 - y0) / (frame[3] - frame[1]) - return stream, x1 - x0, y1 - y0, xdpi, ydpi \ No newline at end of file + return stream, x1 - x0, y1 - y0, xdpi, ydpi diff --git a/tests/image/test_svg.py b/tests/image/test_svg.py index abaaa842..e2d47cdb 100644 --- a/tests/image/test_svg.py +++ b/tests/image/test_svg.py @@ -91,4 +91,3 @@ def it_calculates_scaled_dimensions(self, viewbox_data): width, height = Svg._calculate_scaled_dimensions(viewbox, base_px) assert width == expected_width assert height == expected_height - diff --git a/tests/opc/parts/test_customprops.py b/tests/opc/parts/test_customprops.py index cf83e95b..7f203a77 100644 --- a/tests/opc/parts/test_customprops.py +++ b/tests/opc/parts/test_customprops.py @@ -6,8 +6,6 @@ from __future__ import absolute_import, division, print_function, unicode_literals -from datetime import datetime, timedelta - import pytest from docx.opc.customprops import CustomProperties diff --git a/tests/opc/test_customprops.py b/tests/opc/test_customprops.py index b63d038b..04aa4c1f 100644 --- a/tests/opc/test_customprops.py +++ b/tests/opc/test_customprops.py @@ -1,6 +1,7 @@ """ Unit test suite for the docx.opc.customprops module """ + import pytest from lxml import etree @@ -20,7 +21,9 @@ def it_can_change_existing_prop_values(self): def it_can_set_new_prop_values(self, prop_set_fixture): custom_properties, prop_name, value, expected_xml = prop_set_fixture custom_properties[prop_name] = value - assert etree.tostring(custom_properties._element, pretty_print=True).decode() == expected_xml + assert ( + etree.tostring(custom_properties._element, pretty_print=True).decode() == expected_xml + ) # fixtures ------------------------------------------------------- @@ -63,17 +66,17 @@ def custom_properties(self, prop_name, str_type, str_value, pid): @pytest.fixture def custom_properties_blank(self): - xml = '''''' + xml = """""" element = parse_xml(xml) return CustomProperties(element) @pytest.fixture def custom_properties_default(self): - xml = b''' + xml = b""" 1 13 Test String -''' +""" element = parse_xml(xml) return CustomProperties(element) diff --git a/tests/opc/test_phys_pkg.py b/tests/opc/test_phys_pkg.py index 6de0d868..c0439c7f 100644 --- a/tests/opc/test_phys_pkg.py +++ b/tests/opc/test_phys_pkg.py @@ -58,7 +58,7 @@ def it_returns_none_when_part_has_no_rels_xml(self, dir_reader): def pkg_file_(self, request): return loose_mock(request) - @pytest.fixture(scope="class") + @pytest.fixture def dir_reader(self): return _DirPkgReader(dir_pkg_path) @@ -114,7 +114,7 @@ def it_returns_none_when_part_has_no_rels_xml(self, phys_reader): # fixtures --------------------------------------------- - @pytest.fixture(scope="class") + @pytest.fixture def phys_reader(self): phys_reader = _ZipPkgReader(zip_pkg_path) yield phys_reader diff --git a/tests/opc/test_rel.py b/tests/opc/test_rel.py index 79c083df..9758ab1a 100644 --- a/tests/opc/test_rel.py +++ b/tests/opc/test_rel.py @@ -260,7 +260,9 @@ def rels_with_target_known_by_reltype(self, rels, _rel_with_target_known_by_relt return rels, reltype, target_part @pytest.fixture - def rels_with_targets_known_by_reltype(self, rels, _rel_with_target_known_by_reltype, _target_part): + def rels_with_targets_known_by_reltype( + self, rels, _rel_with_target_known_by_reltype, _target_part + ): rel, reltype, _ = _rel_with_target_known_by_reltype rels[1] = rel rels[2] = _Relationship("rId7", reltype, _target_part, "baseURI") diff --git a/tests/oxml/test_xmlchemy.py b/tests/oxml/test_xmlchemy.py index 66f197cd..9919357e 100644 --- a/tests/oxml/test_xmlchemy.py +++ b/tests/oxml/test_xmlchemy.py @@ -28,7 +28,10 @@ class DescribeBaseOxmlElement: def it_can_call_xpath_with_custom_namespaces(self): element = CT_ParentBuilder().with_nsdecls().element # -- this should not raise TypeError -- - results = element.xpath(".//w:zooChild", namespaces={"w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main"}) + results = element.xpath( + ".//w:zooChild", + namespaces={"w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main"}, + ) assert results == [] def it_can_find_the_first_of_its_children_named_in_a_sequence(self, first_fixture): diff --git a/tests/text/test_font.py b/tests/text/test_font.py index 4edd632b..28751c7f 100644 --- a/tests/text/test_font.py +++ b/tests/text/test_font.py @@ -43,7 +43,11 @@ def it_provides_access_to_its_color_object(self, ColorFormat_: Mock, color_: Moc ], ) def it_knows_its_typeface_name( - self, r_cxml: str, expected_ascii: str | None, expected_hAnsi: str | None, expected_eastAsia: str | None + self, + r_cxml: str, + expected_ascii: str | None, + expected_hAnsi: str | None, + expected_eastAsia: str | None, ): r = cast(CT_R, element(r_cxml)) font = Font(r) @@ -89,7 +93,9 @@ def it_knows_its_typeface_name( ), ], ) - def it_can_change_its_typeface_name(self, r_cxml: str, value: str | dict[str, str | None], expected_r_cxml: str): + def it_can_change_its_typeface_name( + self, r_cxml: str, value: str | dict[str, str | None], expected_r_cxml: str + ): r = cast(CT_R, element(r_cxml)) font = Font(r) expected_xml = xml(expected_r_cxml) diff --git a/tests/unitutil/cxml.py b/tests/unitutil/cxml.py index 36d6ea86..ee3ca924 100644 --- a/tests/unitutil/cxml.py +++ b/tests/unitutil/cxml.py @@ -17,7 +17,7 @@ alphas, dblQuotedString, quotedString, - removeQuotes, + remove_quotes, stringEnd, ) @@ -242,11 +242,11 @@ def grammar(): # np:attr_name=attr_val ---------------------- attr_name = Word(alphas + ":") - attr_val = Word(alphanums + " %-./:_") | quotedString.set_parse_action(removeQuotes) + attr_val = Word(alphanums + " %-./:_") | quotedString.set_parse_action(remove_quotes) attr_def = Group(attr_name + equal + attr_val) attr_list = open_brace + DelimitedList(attr_def) + close_brace - text = dblQuotedString.set_parse_action(removeQuotes) + text = dblQuotedString.set_parse_action(remove_quotes) # w:jc{val=right} ---------------------------- element = ( diff --git a/tox.ini b/tox.ini index 63f3d1ab..2d5de091 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py312, py313 +envlist = py312, py313, py314 [testenv] deps = -rrequirements-test.txt From 51d535f36e8180dc6918422e107d8d644e211ff9 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 21 Aug 2026 18:14:48 +0800 Subject: [PATCH 089/115] Expand project README --- README.md | 190 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 172 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index b2ff619b..645ad9b0 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,186 @@

    -oss + python-docx-oss

    -_As a Brazilian jiu-jitsu player, OSS means anything and everything. It's a term used in BJJ that is a way of greeting and demonstrating respect to others._ - -[python-docx-oss](https://github.com/lsaint/python-docx-oss) is a Python library for CRUD Microsoft Word (.docx) files. It fork from [python-docx](https://github.com/python-openxml/python-docx). +

    + A Python SDK for advanced creation and manipulation of Microsoft Word .docx files. +

    -

    - PyPI - - Code style: ruff - License: MIT +

    + PyPI + Python versions + Code style: Ruff + License: MIT

    -______________________________________________________________________ +## Overview + +`python-docx-oss` is an independently evolving DOCX SDK built on the proven API +foundation of [`python-docx`](https://github.com/python-openxml/python-docx). It keeps +the familiar `docx` programming model while extending it for advanced OOXML and Open +Packaging Convention (OPC) workflows. + +Use it when an application needs more than basic paragraphs and tables: custom document +metadata, application-owned XML, vector images, floating pictures, East Asian fonts, +or low-level package and relationship access. + +## Features + +| Capability | Support | +| --- | --- | +| Documents, paragraphs, runs, tables, styles, sections, headers, and footers | ✓ | +| Custom document properties | ✓ | +| Custom XML parts | ✓ | +| SVG and EMF images | ✓ | +| Inline and floating pictures | ✓ | +| Independent ASCII, High ANSI, and East Asian font controls | ✓ | +| Low-level OPC parts and relationships | ✓ | +| File-path and in-memory stream processing | ✓ | + +## Installation + +```bash +python -m pip install python-docx-oss +``` + +The distribution name is `python-docx-oss`, but the Python import namespace remains +`docx`: + +```python +from docx import Document +``` + +> [!WARNING] +> `python-docx` and `python-docx-oss` provide the same `docx` import namespace. Do not +> install both distributions in the same Python environment. + +`python-docx-oss` currently supports Python 3.12, 3.13, and 3.14. + +## Quick Start + +Create a document entirely in memory: + +```python +from io import BytesIO + +from docx import Document + +document = Document() +document.add_heading("Quarterly Report", level=1) +document.add_paragraph("Generated entirely in memory.") + +output = BytesIO() +document.save(output) + +docx_bytes = output.getvalue() +``` + +The same APIs also accept filesystem paths: + +```python +document = Document("input.docx") +document.add_paragraph("Appended by python-docx-oss.") +document.save("output.docx") +``` + +## Advanced Capabilities + +### Custom properties + +```python +document = Document() +document.custom_properties["workflow_status"] = "approved" +document.custom_properties["revision"] = 3 +``` + +Custom properties are visible in Microsoft Word and stored in +`/docProps/custom.xml`. See [Working with custom +properties](docs/user/custom-properties.rst). + +### Custom XML + +```python +custom_xml = document.part.add_custom_xml_part( + '', +) +custom_xml.add_item("status", "ready") +``` + +See [Working with Custom XML](docs/user/custom-xml.rst) for lifecycle and compatibility +considerations. + +### East Asian fonts + +```python +run = document.add_paragraph().add_run("English 与中文") +run.font.name = "Open Sans" +run.font.eastAsia = "Microsoft YaHei" +``` + +SVG and EMF streams can be passed to the standard picture APIs. Floating pictures are +available through `Document.add_float_picture()` and `Run.add_float_picture()`. + +## Compatibility and Scope + +- The project maintains broad compatibility with the public `python-docx` API while + following its own versioning and product roadmap. +- Compatibility does not extend to every private or internal `python-docx` API. Test + those integrations before migrating production systems. +- The SDK focuses exclusively on DOCX. It is not a general XLSX/PPTX Office suite. +- It edits document structure but does not implement Word's page-layout rendering + engine. +- CLI, MCP, web, desktop, and Agent runtimes belong in separate packages that consume + this SDK. + +## Documentation + +- [Documentation site](https://python-docx-oss.readthedocs.io/en/latest/) +- [Installation guide](docs/user/install.rst) +- [Quickstart](docs/user/quickstart.rst) +- [User guide](docs/index.rst) +- [API reference](docs/index.rst#api-documentation) +- [Custom properties](docs/user/custom-properties.rst) +- [Custom XML](docs/user/custom-xml.rst) +- [Release history](HISTORY.md) + +## Quality and Testing + +The test suite combines unit and acceptance coverage with in-memory round-trip tests +using documents created by Microsoft Word. The integration fixtures cover floating +pictures, SVG fallback relationships, East Asian fonts, Custom XML parts, and core OPC +package preservation. + +For local development: + +```bash +uv sync +uv run pytest +uv run ruff check . +uv run pyright +``` + +## Project Status + +The current focus is stabilizing the independent SDK baseline, its in-memory workflows, +and its advanced OOXML capabilities before expanding document inspection, comparison, +sanitization, composition, and validation APIs. -### FAQ +## Credits -**Q: What's New?** +This project builds on the original work of +[`python-docx`](https://github.com/python-openxml/python-docx) creator Steve Canny and +its contributors. `python-docx-oss` is maintained by Ethan St Lee and its contributors. -**A:** [HISTORY](https://github.com/lsaint/python-docx-oss/blob/master/HISTORY.md) +## Why “OSS”? -______________________________________________________________________ +In Brazilian jiu-jitsu, “oss” is a greeting and an expression of respect. It reflects +the same spirit of discipline and collaboration behind this project. -More information is available in the [python-docx-oss documentation](https://python-docx-oss.readthedocs.io/en/latest/) +## License -This project is based on the original work by [Steve Canny](https://github.com/scanny) and has been modified by [Ethan St. Lee](https://github.com/lsaint). +`python-docx-oss` is released under the [MIT License](LICENSE). -### Donation +## Support -[https://lsaint.github.io/donation/](https://lsaint.github.io/donation/) +If this project is useful to you, you can support its continued development through +the [donation page](https://lsaint.github.io/donation/?utm_source=github&utm_medium=readme&utm_campaign=python-docx-oss). From 60ee643ec4279227befd05ba300d334e0f2b62bb Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 21 Aug 2026 18:27:33 +0800 Subject: [PATCH 090/115] Update core user documentation --- docs/index.rst | 26 ++++++---- docs/user/custom-xml.rst | 109 +++++++++++++++++++++++++-------------- docs/user/documents.rst | 38 +++++++------- docs/user/install.rst | 31 +++++------ 4 files changed, 122 insertions(+), 82 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index a9d906cf..3922a5a8 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,14 +1,12 @@ -.. python-docx-oss documentation master file, created by - sphinx-quickstart on Wed Jul 6 15:38:29 2022. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to python-docx-oss's documentation! -=========================================== +python-docx-oss documentation +============================= Release v\ |release| (:ref:`Installation `) -*python-docx-oss* is a Python library for CRUD Microsoft Word (.docx) files. +*python-docx-oss* is an independently developed Python SDK for creating, +reading, and updating Microsoft Word (``.docx``) files. It combines familiar +document APIs with advanced WordprocessingML capabilities such as floating and +vector images, East Asian font control, custom properties, and Custom XML. What it can do @@ -16,7 +14,17 @@ What it can do .. |img| image:: /_static/img/example-docx-01.png -Here's an example of what |docx| can do: +The library supports common document operations, including paragraphs, text +formatting, tables, sections, headers, footers, comments, and images. It also +supports capabilities needed by more demanding document workflows: + +* floating images with position and text wrapping; +* SVG and EMF vector images; +* separate Latin and East Asian font settings; +* document custom properties; and +* multiple Custom XML parts that survive a load/save round trip. + +Here is a small example: :: diff --git a/docs/user/custom-xml.rst b/docs/user/custom-xml.rst index 72bd8b05..1cbbf01a 100644 --- a/docs/user/custom-xml.rst +++ b/docs/user/custom-xml.rst @@ -1,66 +1,95 @@ .. _custom_xml: -Working with customXml +Working with Custom XML ======================= -As we know, Word documents are .zip files under the hook. -Can we add any file in a docx file? Literally yes. -After we unzip a docx file, We can add a ``customXml`` folder at the root of it, -which contains any .xml files. -Files with other extension and paths are invalid. -But it's enough for us to store custom data. -It can not be seen or modified in Word like :ref:`CustomProperties`. +A ``.docx`` file is an Open Packaging Conventions package. Custom XML parts +store application-specific XML inside its ``customXml`` directory without +placing that data in the visible document body. -python-docx-oss will create a default XML file in the folder if there are not. -Then developer can add/delete/modify items in it. +.. warning:: -WARNING: -This feature may only work for Microsoft Office Word, -Some other docx file clients may delete the customXml folder after editing. -Please use :ref:`CustomProperties` in this circumstance. + Some applications that edit ``.docx`` files may remove Custom XML parts. + Test the complete editing workflow used by your application. For simple + scalar metadata, :ref:`Custom Properties ` may be a more + interoperable choice. -eg:: + +Creating a part +--------------- + +Create a Custom XML part from a well-formed XML string:: from docx import Document document = Document() - cx = document.part.custom_xml_parts[0] + customers = document.part.add_custom_xml_part( + 'Ada' + ) + document.save("customers.docx") + +When no ``file_name`` is supplied, |docx| selects the next available package +name matching ``/customXml/itemN.xml``. For example, if ``item1.xml`` and +``item3.xml`` already exist, the new part is named ``item2.xml``. + +An explicit name can be supplied without the ``.xml`` suffix:: + + audit = document.part.add_custom_xml_part( + "created", + file_name="audit", + ) + +The resulting part name is ``/customXml/audit.xml``. A ``ValueError`` is raised +if that part name already exists. + + +Finding parts +------------- - cx.add_item("my_tag", "some_texts", foo="foo_attrib_value") - cx.add_item("your_tag", "a_word", bar="bar_attrib_value") +``document.part.custom_xml_parts`` returns all Custom XML parts related to the +main document. Select a part by its package name or root element rather than by +list position:: -2 new xml elements:: + parts_by_name = { + str(part.partname): part + for part in document.part.custom_xml_parts + } + customers = parts_by_name["/customXml/item1.xml"] - some_texts - a_word + print(customers.tag) + print(customers.attrib) + print(customers.items) -will be add to ``customXml/item1.xml`` -you can retrieve it:: +Updating child elements +----------------------- - >>> cx.items[0].tag - my_tag +``items`` contains the child elements of the part's root element. These are +``lxml`` elements, so their text and attributes can be updated directly:: - >>> cx.items[0].text) - some_texts + customer = customers.items[0] + customer.text = "Grace" + customer.attrib["status"] = "active" - >>> cx.items[0].attrib["foo"] - foo_attrib_value +Use Clark notation when adding an element in a namespace:: - >>> cx.items[1].tag - your_tag + customers.add_item( + "{urn:example:customers}customer", + "Linus", + id="2", + ) - >>> cx.items[1].text) - a_word - >>> cx.items[1].attrib["bar2"] - value2 +Deleting child elements +----------------------- -or delete it:: +Delete a child by passing the element itself:: - >>> cx.delete_item(cx.items[0]) + customer = customers.items[0] + customers.delete_item(customer) -Be careful. Items are stored as a list, the index may change after deletion:: +The indexes in ``items`` can change after deletion. Removing an entire Custom +XML part is not currently provided by this API. - >>> cx.items[0].tag - your_tag +Existing relationships to Custom XML property parts, such as +``itemPropsN.xml``, are preserved during load/save round trips. diff --git a/docs/user/documents.rst b/docs/user/documents.rst index ecdfefab..d3bff846 100644 --- a/docs/user/documents.rst +++ b/docs/user/documents.rst @@ -61,34 +61,36 @@ Things to note: what you intend. -Opening a 'file-like' document ------------------------------- +Opening a file-like document +---------------------------- |docx| can open a document from a so-called *file-like* object. It can also save to a file-like object. This can be handy when you want to get the source or target document over a network connection or from a database and don't want -to (or aren't allowed to) interact with the file system. In practice this means -you can pass an open file or StringIO/BytesIO stream object to open or save -a document like so:: +to (or aren't allowed to) interact with the file system. A ``.docx`` package is +binary, so an in-memory stream must be an :class:`io.BytesIO` object:: - f = open('foobar.docx', 'rb') - document = Document(f) - f.close() + from io import BytesIO - # or + from docx import Document - with open('foobar.docx', 'rb') as f: - source_stream = StringIO(f.read()) + with open("foobar.docx", "rb") as file: + source_stream = BytesIO(file.read()) document = Document(source_stream) - source_stream.close() - ... - target_stream = StringIO() + + document.add_paragraph("Added in memory") + + target_stream = BytesIO() document.save(target_stream) -The ``'rb'`` file open mode parameter isn't required on all operating -systems. It defaults to ``'r'`` which is enough sometimes, but the 'b' -(selecting binary mode) is required on Windows and at least some versions of -Linux to allow Zipfile to open the file. +The caller owns streams passed to |docx| and is responsible for closing them. +After saving, rewind the output stream before reading it or opening it again:: + + target_stream.seek(0) + reopened = Document(target_stream) + +Always open ``.docx`` files in binary mode (``"rb"`` for reading and ``"wb"`` +for writing). Okay, so you've got a document open and are pretty sure you can save it somewhere later. Next step is to get some content in there ... diff --git a/docs/user/install.rst b/docs/user/install.rst index c63da3d9..223847ef 100644 --- a/docs/user/install.rst +++ b/docs/user/install.rst @@ -3,28 +3,29 @@ Installing ========== -|docx| is hosted on `PyPI `_, -so installation is relatively simple, and just -depends on what installation utilities you have installed. +|docx| is hosted on `PyPI `_. -|docx| may be installed with ``pip`` if you have it available:: +Install it with ``pip``:: - pip install python-docx-oss + python -m pip install python-docx-oss -It can be installed manually by downloading the distribution from PyPI, unpacking the tarball, -and running ``setup.py``:: +To work from a source checkout, install it in editable mode from the repository +root:: - tar xvzf python-docx-{version}.tar.gz - cd python-docx-oss-{version} - python setup.py install + python -m pip install -e . -|docx| depends on the ``lxml`` package. -``pip`` will take care of satisfying those dependencies for you, -but if you use this last method you will need to install those yourself. +.. warning:: + + ``python-docx-oss`` and ``python-docx`` both provide the top-level ``docx`` + import package. Do not install them in the same Python environment. Remove + the other distribution before switching between the two projects. Dependencies ------------ -* Python >= 3.12 -* lxml >= 4.6.5 +* Python 3.12, 3.13, or 3.14 +* lxml >= 3.1.0 +* typing_extensions >= 4.9.0 + +``pip`` installs the required dependencies automatically. From 3b397f35ab98db80eddd7bec83806cd4a3fb6c4a Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 21 Aug 2026 18:35:36 +0800 Subject: [PATCH 091/115] Prepare version 0.1.1 --- HISTORY.md | 10 ++++++++++ MANIFEST.in | 2 +- docs/conf.py | 4 ++-- pyproject.toml | 12 +++++++++--- src/docx/__init__.py | 2 +- uv.lock | 46 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 69 insertions(+), 7 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 3f1ba6f8..0bd58b81 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,15 @@ ## Release History +**0.1.1 (2026-08-21)** + +- Added Python 3.14 support and CI coverage for Python 3.12 through 3.14. +- Added real Microsoft Word document round-trip coverage for floating pictures, + SVG images, East Asian fonts, and multiple Custom XML parts. +- Fixed automatic Custom XML part naming to select an available `itemN.xml` + name and reject explicit name collisions. +- Expanded the project overview, installation guide, in-memory document examples, + and Custom XML lifecycle documentation. + **0.1.0 (2026-02-02)** - **UPSTREAM MERGE** with python-docx 1.2.0. diff --git a/MANIFEST.in b/MANIFEST.in index b2d3fadc..7d3de476 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,4 @@ -include HISTORY.rst LICENSE README.rst tox.ini +include HISTORY.md LICENSE README.md tox.ini include requirements*.txt graft src/docx/templates graft features diff --git a/docs/conf.py b/docs/conf.py index d97fbacc..81a18b59 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -20,8 +20,8 @@ # -- Project information ----------------------------------------------------- project = "python-docx-oss" -copyright = "2022, Ethan St. Lee" -author = "Ethan St. Lee" +copyright = "2022-2026, Ethan St Lee" +author = "Ethan St Lee" # The full version, including alpha/beta/rc tags release = __version__ diff --git a/pyproject.toml b/pyproject.toml index 7b810654..605289d2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,12 +4,11 @@ build-backend = "setuptools.build_meta" [project] name = "python-docx-oss" -authors = [{ name = "Ethan St. Lee" }] +authors = [{ name = "Ethan St Lee" }] classifiers = [ "Development Status :: 5 - Production/Stable", "Environment :: Console", "Intended Audience :: Developers", - "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", @@ -23,10 +22,16 @@ dependencies = ["lxml>=3.1.0", "typing_extensions>=4.9.0"] description = "Create, read, and update Microsoft Word .docx files." dynamic = ["version"] keywords = ["docx", "office", "openxml", "word"] -license = { text = "MIT" } +license = "MIT" readme = "README.md" requires-python = ">=3.12" +[project.urls] +Changelog = "https://github.com/lsaint/python-docx-oss/blob/master/HISTORY.md" +Documentation = "https://python-docx-oss.readthedocs.io/en/latest/" +Issues = "https://github.com/lsaint/python-docx-oss/issues" +Repository = "https://github.com/lsaint/python-docx-oss" + [dependency-groups] dev = [ "Jinja2>=3.1.2", @@ -38,6 +43,7 @@ dev = [ "pyright>=1.1.401", "pytest>=8.4.0", "ruff>=0.11.13", + "sphinx-book-theme", "tox>=4.26.0", "twine>=6.1.0", "types-lxml-multi-subclass>=2025.3.30", diff --git a/src/docx/__init__.py b/src/docx/__init__.py index 7fbe720c..97d9e7c5 100644 --- a/src/docx/__init__.py +++ b/src/docx/__init__.py @@ -13,7 +13,7 @@ if TYPE_CHECKING: from docx.opc.part import Part -__version__ = "0.1.0" +__version__ = "0.1.1" __all__ = ["Document"] diff --git a/uv.lock b/uv.lock index ff0927c1..5d15f5fc 100644 --- a/uv.lock +++ b/uv.lock @@ -2,6 +2,18 @@ version = 1 revision = 3 requires-python = ">=3.12" +[[package]] +name = "accessible-pygments" +version = "0.0.5" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "pygments" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/bc/c1/bbac6a50d02774f91572938964c582fff4270eee73ab822a4aeea4d8b11b/accessible_pygments-0.0.5.tar.gz", hash = "sha256:40918d3e6a2b619ad424cb91e556bd3bd8865443d9f22f1dcdf79e33c8046872" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/8d/3f/95338030883d8c8b91223b4e21744b04d11b161a3ef117295d8241f50ab4/accessible_pygments-0.0.5-py3-none-any.whl", hash = "sha256:88ae3211e68a1d0b011504b2ffc1691feafce124b845bd072ab6f9f66f34d4b7" }, +] + [[package]] name = "alabaster" version = "1.0.0" @@ -647,6 +659,25 @@ wheels = [ { url = "https://mirrors.aliyun.com/pypi/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992" }, ] +[[package]] +name = "pydata-sphinx-theme" +version = "0.20.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "accessible-pygments" }, + { name = "babel" }, + { name = "beautifulsoup4" }, + { name = "docutils" }, + { name = "jinja2" }, + { name = "pygments" }, + { name = "requests" }, + { name = "sphinx" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ae/8e/add936feaaa9dade7d5b87c6852566d85e518b38ad32224dea32ef958984/pydata_sphinx_theme-0.20.0.tar.gz", hash = "sha256:0da172d41e19a66de875f4002f7054b385372ec65763852193791e658d50bb4a" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/80/08/28e2194ed1c3c3a3e86e0600e2dcc7f21dcd670bd31f3efab2e3e2cf0cbd/pydata_sphinx_theme-0.20.0-py3-none-any.whl", hash = "sha256:56744483c9d72c783e075de716ab95d486108b69605df7528078090b73f11f69" }, +] + [[package]] name = "pygments" version = "2.19.2" @@ -725,6 +756,7 @@ dev = [ { name = "pytest" }, { name = "ruff" }, { name = "sphinx" }, + { name = "sphinx-book-theme" }, { name = "tox" }, { name = "twine" }, { name = "types-lxml-multi-subclass" }, @@ -747,6 +779,7 @@ dev = [ { name = "pytest", specifier = ">=8.4.0" }, { name = "ruff", specifier = ">=0.11.13" }, { name = "sphinx", specifier = ">=7.0.0" }, + { name = "sphinx-book-theme" }, { name = "tox", specifier = ">=4.26.0" }, { name = "twine", specifier = ">=6.1.0" }, { name = "types-lxml-multi-subclass", specifier = ">=2025.3.30" }, @@ -927,6 +960,19 @@ wheels = [ { url = "https://mirrors.aliyun.com/pypi/packages/73/f7/b1884cb3188ab181fc81fa00c266699dab600f927a964df02ec3d5d1916a/sphinx-9.1.0-py3-none-any.whl", hash = "sha256:c84fdd4e782504495fe4f2c0b3413d6c2bf388589bb352d439b2a3bb99991978" }, ] +[[package]] +name = "sphinx-book-theme" +version = "1.4.0" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "pydata-sphinx-theme" }, + { name = "sphinx" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/e9/8a/cb008736682b3974cae6925c54939792fe56f5a167e37984cb45d8a85d8a/sphinx_book_theme-1.4.0.tar.gz", hash = "sha256:fee3cd70573d9a8cd4ab380a3cb1f11139c24dcaa2cf47d06d7f924f1b44eaff" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/00/5e/6c41ee74f0a4caef53f224c3e6c3869b577dade1a283767bdc874f11e51c/sphinx_book_theme-1.4.0-py3-none-any.whl", hash = "sha256:10fd57d667ee0b565928c3ce95562e281c5d1b94bd5a2aafc5cd41a5d498dcd0" }, +] + [[package]] name = "sphinxcontrib-applehelp" version = "2.0.0" From 07e652b20137726f07f646b8b00a3c5357975e6f Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 21 Aug 2026 18:35:36 +0800 Subject: [PATCH 092/115] Automate PyPI releases --- .github/workflows/ci.yml | 10 ++++- .github/workflows/release.yml | 78 +++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eb8e713f..7dcd52c2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,7 +60,12 @@ jobs: - name: Install development tools run: | python -m pip install --upgrade pip - python -m pip install --editable . --requirement requirements-test.txt pyright build + python -m pip install \ + --editable . \ + --requirement requirements-test.txt \ + --requirement requirements-docs.txt \ + pyright \ + build - name: Check formatting run: | @@ -80,5 +85,8 @@ jobs: tests/integration \ tests/fixtures/customxml/generate_fixture.py + - name: Build documentation + run: python -m sphinx -W --keep-going -b html docs docs/.build/html + - name: Build distributions run: python -m build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..9baed0d3 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,78 @@ +name: Release + +on: + release: + types: [published] + +permissions: + contents: read + +jobs: + test: + name: Test Python ${{ matrix.python-version }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ["3.12", "3.13", "3.14"] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + cache: pip + cache-dependency-path: requirements-test.txt + + - name: Install test dependencies + run: | + python -m pip install --upgrade pip + python -m pip install --editable . --requirement requirements-test.txt + + - name: Verify release version + run: | + package_version="$(python -c 'import docx; print(docx.__version__)')" + tag_version="${GITHUB_REF_NAME#v}" + test "$package_version" = "$tag_version" + + - name: Run unit and integration tests + run: python -m pytest -q + + - name: Run acceptance tests + run: python -m behave --format progress --stop --tags=-wip + + publish: + name: Publish to PyPI + needs: test + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/project/python-docx-oss/ + permissions: + contents: read + id-token: write + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Build distributions + run: | + python -m pip install --upgrade build twine + python -m build + python -m twine check dist/* + + - name: Verify release version + run: | + package_version="$(python -c 'import docx; print(docx.__version__)')" + tag_version="${GITHUB_REF_NAME#v}" + test "$package_version" = "$tag_version" + + - name: Publish distributions + uses: pypa/gh-action-pypi-publish@release/v1 From c0cbcf81c8319bd608e5684c307df8e2467e3ac0 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 21 Aug 2026 18:40:14 +0800 Subject: [PATCH 093/115] Fix CI type stub installation --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7dcd52c2..30114abf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,6 +65,7 @@ jobs: --requirement requirements-test.txt \ --requirement requirements-docs.txt \ pyright \ + types-lxml-multi-subclass \ build - name: Check formatting From 97792c2adf0b440919f995dde5c5201c793d3fbf Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 21 Aug 2026 18:45:21 +0800 Subject: [PATCH 094/115] Fix release artifact verification --- .github/workflows/ci.yml | 8 ++++---- .github/workflows/release.yml | 11 ++++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 30114abf..329e7a7b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,10 +19,10 @@ jobs: python-version: ["3.12", "3.13", "3.14"] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} cache: pip @@ -46,10 +46,10 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python 3.12 - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.12" cache: pip diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9baed0d3..1d677665 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,10 +17,10 @@ jobs: python-version: ["3.12", "3.13", "3.14"] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} cache: pip @@ -55,10 +55,10 @@ jobs: id-token: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: "3.12" @@ -68,8 +68,9 @@ jobs: python -m build python -m twine check dist/* - - name: Verify release version + - name: Install and verify distribution run: | + python -m pip install --force-reinstall dist/*.whl package_version="$(python -c 'import docx; print(docx.__version__)')" tag_version="${GITHUB_REF_NAME#v}" test "$package_version" = "$tag_version" From 91e48b59f14f88fa6d39561bb58969f6404bd785 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 21 Aug 2026 18:57:19 +0800 Subject: [PATCH 095/115] Ignore Aikito project skills --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5aabfd8c..ab5bd2ed 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ _scratch/ Session.vim /.tox/ +/.agents/skills/ From 295628d4d5a1438a4903b047f5a53fb51277a72b Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 24 Aug 2026 09:24:46 +0800 Subject: [PATCH 096/115] Update README header image oss.png --- docs/_static/img/oss.png | Bin 319228 -> 139761 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/_static/img/oss.png b/docs/_static/img/oss.png index 462e3c4975675ba2321ec44759ecc6c2f2906563..3f71045640fa0cf5c551ac3bf0ad542526fd8a92 100644 GIT binary patch literal 139761 zcmeEt^;28_^EE9+TL=zCg1fuBdvSO7V#O)$5Zv90L!h`7cXx*%#oeWR-=&|w;+bdi z!=2noCY#-}yJye7Zul1kNhCyEL?|dIBxxxzWhf|kZz!nuv+&UW-4UCSH2LpBWFn<3 z4+Z5(0R`n31O@f@-z~p=C@5DZD5yh2C@7v(C@Ac&nJr3uP*CrVzsRYI|M~NJcYilC zGaDHh<>l>dV`HnXu2o!I+R)J4)7yK0e@)hh57pV?(hFLGBR*;cZY|A_xBA*NJvBh z08&y@%gZYQ1B05HnuLV~THD$PiHN2qrfF$uSy@@X`}?B+P~hR=s;a;mnwnp~+UMou zFDxzLU}HNwyTruBZLV+RW@rEE=gd6D_J2*O0QBn#C2y$_9=^N_*C@C2qpJHZaw6}Nc z>gcATrX(UHR{Eltotxe9t0Ox*Z*g&Pd~$q#ekmq4#?irviGk7I*Vjm2e`|9C9t9yh zG!_q=3;`Ae3+c19h2!h%YxPZ9<$r*9XDllzRxq%9hWp~pPkkajwks+(Q z2!$!W6vPlrftPGn!@Be#`F!y+8vKy&#vgEJi`pC`zwOfY=i{yH&pHisBgz_XbERGr z{0mGd@E_j$3laVQ%m1q`;POeubtn55-&F^!fB~qtaQE^{lBCI4C@<-*i#`4W03^Gc zZ49QzI}D1d4iSJo*Z$Gn^56F|86psRG}&Z}9N_<4$Y)%UBYy}IRIXB;gO2_F&u?6q zR7M9*dpb#I-ghMrB}&_g3`%~6M6@8Yc+j?y$lHe;wO2)b%A9ML-AQijJPcG~0m~5C zuXWQDK|0b`Q#?T0HzanfYtGKqxY5GDj0c~oNAE@=6N1U!fZM?k4P)w z*OEM;e#328t7OW#c{kIQyuyOeKJlL!DBbN^qaDv8d%ywQ+a~~Y$h401Niv}HBHd2i z@;R2I)@M;gtxWG~YaF$YQUhg*yz}lKg3M@&jgZTV!C|6-f778iaESjRpqXMS@+l@1738aF6Y-^Wc{I4 z!j8~9O-N?bquNF9f_^hS^eXV2hnSamFGea?-}}yu%{MWYk7}VB>GiWD;GbcAJZwEp zsS_zOuaxX^{Pws-`ec_z$%lQfj45X?xm{AMaqc7u3L1yz`RVrx?br8AS(qTYGzosC z&XE*i0l_ooan1*>{t`F`$LVi2fS$9tx-{%wn*m3$zmbNtp#WayA|EI-5^otOo{};n z^b^qny-9M)3t7`r5amN};SMf4UEpGmQ{B^5yr{`T6~zbnc@B}!@sASCt_$=zM+q%p zxzgWCQ>Go=QyXc{F`(L9zacEigCy^?Orx$;F3+kN(2P76`A40jn;A<^(6|=gqkqO- ztJ!Af%O&cnXyYQRa*N<8)YQf#uM{%D*uDM zC_EZ{pDhja6jDjt?ke?c%S#R~a^w(gn>l^fp+GgQojfZUK^N}#N4rx!h2MxiRF7Z@ z``OwEr%$!y&VEz>Gm7X+lM0!pCuH=8ZS^nfb>n$Py5^1*Syjvi?P!ra<_Z}f$x`iw zPF!v8#8Kn=N9}6sY=);2yVM)3&se755P2guq-xd}vQ&OuyQIsnQ~t8- zN}yhnt)4C_uG)gU<)7o3=;H!^7vLwC=>zrR-k_7Hl-flul9LQ1viu(LmMt2DS4=q* z6d88SzST^T54XE`QFb38@7xTWSr2T%TqTDFI!sZiVfoqxHOo3M8drYNKR#W#?1#$i z?YJ!`tm(2nofi)Xs9p!MJ-I$8f8R!-7?#88w_*fq6xfVA1K z`Z6z;Un&Pg$vgBU@-2uCMTRuHTMLJ9&Y0QsSpZFTNKbEsizh)6 z*j%AXC+1-~)N3EP5&u;WZud~_z@yjnvPzLbp*ZA*GW*6wU;#&7^rg<)b057W~5-RQBi1X;-1D3n?s*I&7mkOT?bRMwOerD3uuFovY3PG#eH4S+NGZX$!rWBtXDd~m z`MLO`i~%k*6Ce`xPpc|9bC&zBtnjXn&{ud5&l8Y_V)Od<2spG!l{qv|O`1ePyz0d| zKIh*Oy%$YqLnxeA8=%R<3JL3Xa!qHSApD#(`~UhuuTP}Mpg3oS{@jsMp)mihOTrq; ztZ2n-@bF5A665DO8WmaW?MOGUcE#&)uu)fh8uCTk!8CP;=?oRe;3o)kdrxMB|NTb8 zjcA3-8WSvxh$U{)k2heh3O-)kb{gc0S@GF_(TX3o-2b$k*E^ip6+hzrhw6P^@|kB9 z?Y+K)6sW~#d{eHOwI4s6Zq#G#>)i#+;>B(4@*{3S*UVIXME5ScC z?81d%E#KE82N*BY_p56ZrKD=+IhfLP5{A{^&uPduB7g5Nt2w_HeRLfuvX1`IsX+N^ zh||u=pxUzZ11&^Ju0w}!&9)zsf1mM+FmB-zX>Z5e!XkgWCEw4x>}`s^KIIQ0*PDPo zT$XPclcrZPs=dVe8v^*=QY8=!sliZ3GQK`#los*Lq!LIE_QX0%t`R$2>%T_0#+Nyv zYu@TxNURskCAE7HutQSupkDMV%U_9St?}K7R#*k}`ceS)L;<}$LZd}2KoQ3L8P0y% z(shD^9EM5U##Elp=ik4)&Ifv=u!inmCc`J@;M}Pr_V}|9u*%-FXq~8seD~f~4A+vt z`6Vk?m-_wc?kr^_wp;4ueVp=D|u8p z-CCYgycfhwPdlAp8)F(Xljb*VAZ641&K~DgG~c<&nSefWzbB*VNfJm%5L+FecTDhP zDRyUct029QwxzlNKf@7z?fUuXoCWwqg!&%RY5cj&NUk+*?I69s9OwBj&OSiMsC;x= zG%M6Y`9`YVqqJTqP^EN$kGpQMz^uL{I?{zDctvi{59RCO{kc<>fVtJ74Fe;E)7mIc{pubm zOsLb3Z&q9t%`R4=d}Gscx9`wYwf~HBZKax`4|q9zyu9E>emN}5p+9H?l`S4Xg~HS7 zFV_VSDxsF~_X{);K7Xw%1~b*AG5%}Y;JN1?^@@Ia_gb+i8r~L;1Jgdb_hH(>Msumz z_{@Ui$TMkj4~&6_8H~F0P4lP9L@Y3;%;N$L&w~3rI$kj`%6gj@+SqgyA zQZm*3I5 z-YmIN0x3fd=*N&n9`nTWI5BQ4%_Gf(6~5&TZ!hf#%@@+ay+ic4deZNf+u1l)6Cfnh ze_1+v()d{ITnqjflRJ%PDsQeqAwtOc%Wc-U+5$IuS2I!Tsq=+CGAWm>)8W}`>;m4g zy5o=MG$0C-qud#jQU61O^}-yYqHdkkKGxe=;k0_>s-bz8|+!cq`8SiiA>q%fN1@ zwdxc$EGi_aR#>JMi|@{~k|g}$e)~N^H)rO`&yTCZZ757GlmJ1M&-feuK6%7VBUcj9 zC>UkET(Bk+-L;SrX_Ngp`KACW$&m7UQ;V zv)33qe#1+H?S>tiua}*Gu_|J?RX=Mnw#q4iH3#60W zKeq!ORNt6omU38GmY;rE%_7RnHs}V5^BV$r{Y9;>tu!=lpi}!qdYn(P^Hw`GNmYE0 zK1$=+e=a&RzYJhYl8NW`DS$65R?3M~d|zT_Y&XW~D%WX=J9 z-yCkH>HfL!ZdWDTq0!)kp?4HaJVcPWqqFfEm6qd;tSs>x&_rc?{tD9#oT>@DU$o}l z@KtNyM8NEmPA{SIu-0b&(75~s43HP7Vn(J>_Hr@Z>}eP{2qkzik4BUH!o$itYIOQW z_u&7VOq@g`E!J71A{B2kh&l>?){AIx6kLSL?`~83wp{%HZ7M0W9tbj^Ax^J zYtu+2Z{ixX1bEnrLSU%i(T_!wmz=chy)eCvp$ls zJw(%8TzY0oY6Gb;s!I_-&3OVx^cqm=o=LF%<9Dy{LNjl21qPRXvnYRjbZq*PAG>9T)DM$A)uBjchHzu^@161^Z8G5WmQxTd=ZLxRUG`LU?X`K4qU@lfsk;Z!~f zy4D@R$`V7Cz8@{H1y(GWlct$*beeP4M&XkwWY>7A!UoOB_|gbB1p)gwfP9R&5!rN> z^cpW=*2KPyIoR8UYXjpr(0~RPdxNMVviB|f47^km4*qO>2W)}ZNN2STiZtxywty@f zm*t&&IY;`Gy$>TSWL$^sALSe3NHB;#q zDfy{&CUw9Z#cydHmG%K3<2$)ICNny-Jq7j~e5P%47rDYiE)k#_>bU=$#GHZibpC-A z!ABM(&7TP6iaxE@IgW=Za;%Cl!Tnb#@U9F5&IuG$|8mki)(-N?<$U3M#u1xk%WS_+ zvH0`;5&lj@2^Qy)9sDyn2eng=ac{acbFBmGvFfSPz^`GjI;9(a*j&!I1-np3+gm&q zV?U#nCp%Dye#6?CVfCh2uU$1G)!#d72eV**(#E7POk{y;g_NLs#ZFq_*u+eK2Q}!H zy|-*HEtgdEnpgZUt6sn?R(kywogk-1Hy(lRp$?2o?aGn z?HIoHatjptD%Bp(Yt~o=qjoW!#5hU)xtU;?VlkBN?xt{!XRE>5oVW83+Bcy*Kczg% zoz0HHaE$(M5A4XE?V;j;w=%_!4i-*Bv!d?r$6Ijf><%{be8Dq5SRJUGGc#{kx4w^_HMGm3ET-fs7`Y_Rkb1@LQ6}FhAy>$0XYL6h92p$kUpv z?p%EtzUNu1NOsrVQFNA~%Vwi%>0bf?&?KaSb_^>EXbQG^W5yF1UZ}R>(|`xPtsINw zqrWNm{^FOhQq|@h3$2SRgri<`@x#p|Up~3|cac@6t|WonU~E%nn;Rd6HCbp<$7VxE z5N{0hcu^~JSIIF{-3KQS(>-xkZv)B6QN90R%;?-PvmJl2Z=v9~gYlUArFuZT$5P|z zI)41L>sOJ+4|OzObG$VF2dNiQ%8+lcJ8=~=$wvhDfQuLF^|)_M`SD7iH6t}_eY1XAgQ$Y zmfAM;bi7ESofUfna1u~SSRejeMvA1!yOVki9bpYy^6)mTEg-QRPC1x5)oi_%NH<|p z@RAUR>&hGV1Vn0XZ60Uzdol4|l~H-q}Ie6sIsqjYDZ>7~&qWfbL~=HC>U#jZ`fD-tDj{l;@a-c_*1*>GyV22h3wSH<&LDTUH$(+QC0?^_ z;$OuAWQItK9T{09-v*ORX%_@HeZ_8#n^UCP6O9G?N(J|fNZ0FKYab~o8y{IS-NWzL zHgz_3k*=u^N&tBdB402DnHIzVigpR@l}t^`s-DUK)x}h0u6v(Ll5DHMi9yJ>VUdAu zkA9CWqqD|z(oa3AFL<%rjzYl<)j*RinhsuP5U<#AB%k@xQPd)@DaYE%ji=*yJJ!B& zW@#Wj*D1;DVfw=5uOQqT7$epYZ#TJh#bS6a;(vUsqoe_--wExj9XqY0BVT#Kdd1XC z&FExADF=TS=P0dDMAagzM5{M~W68e(`jks!e3x9ApN6kBB3|rX7nPbT%Xrq8m=90RzRh$ zIYmz?g5UQ>R0Jia?dZg%A`^g%zP(MMeb2M86`EV?7bZYlI}c5sLM61oO-;fyoY%LE z43rl5RFK^%15c_x-eiV*Llztn+)@fR8G^t) zb!ypf#GsylPQLC(D@STYmM6I%nhrly<3o`UzYyMV}UnkgOsJVGc8j zB{gAioFDl2NMIT+EgGKB1SdTt+8;fure7~er%XeAg&wa#308Et;<7b>X$+U66#Nn; zB0i*4?Q?U5#e;8!qx0cOoKa=6QZf;W;LA7a2f(>2NkPbqn(5w#APe&kB44$)kv%NF zN35x@KRTkXP)$Lzxo?Q`;?Vid>o&A|6jNkvKxvGz?dQv|6&Nre5y20+J%UIQz+3ia z2YtGF@Mc$f*%wr050~i?OGNJ-+j9!+wSq;Obv82#ZB8`uKCY)lWiBnKb*I$H) zMF@jr8uu+j6_wkRb|@=15o`&dHqqyC%3vZQTo=95eNsrcX=%OfUZ=&~bGSzivb3KI zh@Kih9lECQj>}6DV?7yuak7EVN;edDF4k}QbQ`;6R%&(tN&9CC%*YprlMvNPUZqm8 zed>4j9EV@X0=2O;?V+2P87?a3_@}zAL#~?0SMv62d5LQcB_veZa)+$20@!>4kZfen zlJ`2@MeHfF?ot#}4LvyBQtQMTdmJG27_Pfb@9;|zrS_>{<%^$-=~nZ1Fx*5S%m|N^ zKOCFD#)6%|aXTwd%jX`_Q#G3P!~I(7a=Y`WH&*ok@=SdoCf}^-dJs&G_Kf#PcK#h> zMqn%1x}ZNLUPU|Xn{cj;DPyxi98*8sT>_VbJwsU9GQ7gVjp|YudM}K3dUF8h(Adm@ zbRzYb7tdkhi4e@LTyliAq!LieIHI(Pkrf~JHI0JsX@TH(%XcbupG%{J&AFw+r-#;d zs&#QX*~=6Lo@|o81fgpa82;TBO&SK?XPODfh_a_S&38m(zwau#QWl5`x7F#@&m{AJ zvCSe@TM4Y~R*WI-hOV99`wX&)ibK8-XmB|vAGX77Zo!Dip6;$ZvQznmR8eN-{hYch zcEv!9N{WhENmv`Fdx%qt{qSi$z42RcO}-HW(LWmCAz5mS$^=uCsOtq=!QbX1&i^b? zNpmV}wkKW-q6ZhawQL^7g@n|j?-Edc^cvJ0@Q!p^iMd32AKWtPv}&HmQLzKtydE2O zZ$Lz*!sD~vuo^2I-eI-#{`B3e_pNXNqtG;9kZy_8cNDfUmRB47HMuECyzy=Sm1#jY z0`E&wfPnxpc{MTlGHDALFO1{Hs4bzeUzKjB&(3``fOHAxEY(|n>f!yi*fUWx3K+I; zi54kVS9k$Wm(LquR+nT;?KrQ^TF|*Kb6~W*M?FZNQ?XZaU|7ibklv_@L@G~UvGG7u z;?c|+>=PAc&HZC+{=@_fkX}U8Dg^#*1zZcUtE3ijm_`4)t2Yh{hK#|#5wwy z=3=c~zpB$Ci^(QG9Isv2=hji2Lw+R`HwC{a5&uKwP7lmCHip4eVNRZ{lZ(`Wy|N?^ zo<>_7@=6F5Qucvb$eHB}H4>taB&sOVVIo`~wqizWTECaZFJCg(k^LFXNN&MvFdn7m zpGvn(&f_C<$zvy_L;3Tc|8k+PFO>T$h`ocX;jCZrVbHj>&KNj+m{_SNjXg%?rq6$V`w`}N0gBReZA1S$BujdrT$ZvJ8Q*&W`4bcqC=`IdU%a#jFkMJ+eE zk%)CSg}nODMQ21o_^~_)#@{&n#twf^%=v8Se}7)WE_#$l2$fU-+CeIiy+;$nu9^f_ z`bbWPj}z~R(#X90p}ShN@klT5rgh#57K7B=H=p<8u@|G$wd9P@WW``wYeAUD4gT;* z`ArS9b4M9)DNm%cJGsc#g2IlWwa*Vkuz5Zogg0j_qOjr;D1R+SXIDp9dONl-PM9cZ z4nl3gyS768&{Lbrt{|wM*YFLyWB~RDy%VJx=OO0u@)a~OxFnPWE2z;zlHYc%Wf#Y1 zcT1WRIFy0CAqNJ#W`x+E&Y)&4c8E-0T?2{(buDma(l1V zO+}Fr)Dx1eAMO@IYP@Z~vh{6UKzC1%vtq1CH;1iE#=ZAqA@jghH(!kmcv~ZS(=I6>p z8TZGx`iS3syiVp~V`diY&|n%@DO;3wknPH}clK@`h$qv7AfR`HyTyV8y=o#;T5(AX zgKG>b ztNdo05E?QGY;gOl@b+?V12-ct(DKSyWPr!df=;eJwnBLqmfiluW&D=mhQxqxZF*VmMxHlr&Ycs2DOBq` z?LFGog9|^eR-pHebqs5K`O%&yE6t0+0Fl%qF1fbfY2aMPm<1+z^nc3IIJOK7309YS zZ@rg|TJ_or+-SPX-J)4kB$8XHzEP00f1mQ;hc@?{kUd~lYJHzr-hk0uJ@CTDF)-v( zSrP5*ljuRv=XAn%++@e7-tt+Mm9>{tyulLs!W)zVj*KBgdI|iq%V*S7MXuU%(3c=_qOxPUxsWgk7;)G4c)O0VOezH-(lVaq0bC6Rc~)5gg=o(V79a!t|+9jqG>A}i@=F|=2k>c+^?fNW=TQ%?XpJUw< zHLX%g7va8ud}QNdV}0bL+rN&uX7SUst|?d$#!g;(D^qkx;YsoTC8&BAG%sF)iMrIBuAX%p)I+v!?2nj_oHBFy-P#vu5hes&SJbuDDB}g zDL(m19XeWc@0&0v-pRKhREPU;wLRSrE7cL+_hPx#5W}%L<>gj@@m$ zwr@F#UJrB!hNvNFQGdy(vtKX_Sc{<;S?Z*8qIWL`ZMltFy#;F}GTFRB2YodVorB4V z=+=@Nq=Lp423oL#Izd_e)$oGxX$uwa#$z*jM2T{Sf=q#5L~GbS$cJuhLB(9UJwmq&-)kQe}_Q)(@kjzTNTu}ep_y{lhk+qZT3Q$ z52>M>Kxi=McgXw-!*#sL(yBm89`vuSE`QtJL*7i~mR)B+%d6=@XyWSPf3GjIqOcsc zIlkwbo?=R2eqQc7JHnvxLiSdI5I_J+CUYMg-ATs4zV!m6P>Us5aqB+4KSR#5gLC)^ z<YV@!n!pv@iBw_V9%7n$6L4e08litS$qa6b9hxx;H zd6I=wsnzXY)4L?)PV@$WMe%G-ia?YO8n+|9`7kvbq8~DB0S#6Ig}_^?!)$>p@h=1y zP>MfG))Nm%R<>PdcY7-t*DHfW$^>NkVMI8n$Q2rgOo#grKz8TDrhOxen!W0_FEhwjRxf5~rDC|@C1GvQp(0pau_i-LGa5F-~mT~0g9 z>}**ReI?7#ZWYRn`NXR1v-nD~bjrBVi^d7MMpKDXVhz3Qe!Mm9-WFcG=FI41zqR(> zHqaDaE2S0W<7XhXM(z@*M62{tyvxOW3+{6(z+`lZggNdZO?<#0w=|R;JXX%f$ew+p zfZK5Za81WD5p9Z5xO@}GgL-rVCiwb_5N*joQ>c9x}%-lH&`UxF{ zC?QcZSk;>v4faqj9sn`ie`_ihz`juUSNQn_<%CIq*~fdPn6EWJH>^N@4>;T*b|+Eb z_Iu}eL|@%`;Y8=bQERQ?d3qb(T;TSaMODdq+jJ~hE@21nGCoF-ndgr=Y7T@0%;Drz z8}6Luc#qX7LOM1=t&bZ&u+m_s@se&LFc}qT95O7g-iRmb$CIFk9;9wTxKktZuq(mj z0TWk}Be^;Nl?G;{K`g-iA-?ZGIo1(;k}w@vAS1auGhqmXke|RnkVnqE8tYr}E{lpb z-8AOs^E-LILlrLZ!n88`2d}y+9=K+xu0z5VYpFYImR;qv*=m9~U6oa<_rD-{Kb{j8Ua_*5 z-!L&V1cs*3I_M#qUJIbr1zMYVpOXDX#|hWME?)7hlLjiUIPzmj`E_SU^gO`AwN<;sfV&0~>Y2bo zb0sEVQHv`-fVpa700yju#56;Y6zBHhr_}0#lb3fKtjwT?}|-#@Og|mV#)gESY?n>-&?+FjbDt4lg0)H~neE%)G4Uo5=s#&S71)1^l)xQOff>_pe z<7cn&O_iopWE94s#0x7)^T5eL900}bC!ZnSNe?t(+!N1>^9HZ^S1*ilOGXPe{zWMSZ@24<6I5=3v>e84Y73RWsxezAGcw)`-rC#K*VBlis?^2*wtFQJVeUV+o z$|l{3Ho%{4hUHf35-GqMI(K&s|d7L@yM&xQSlst z3FhHB1oMvbWsZVElX752e`Su(eX!@JxgR(X%aZ9NlBp|ykNXtEcJZ}hr8bpgvPaok zX}Ow-XHW-2bIVm4DQhn$J_idJj#D+6BbYgmfcrP+Eb!I3_|v}(UVOvCKvoN7>Nf`i zWa9wqas9^r#3A=pta}okPEiu9Iiiog9wz_E#24?zzMW}$c?Eb^h{B86m;l%w79+fT zgoqt~^2--n&|1^Xip?Uf?Z|iWVaYi=zMHUlBRNKF2%klEC4yf|O;fe@ z$YK+##;2Qglqq&O)5q5!rQc2 zA;PGvr|<~boBH&iHpP@fgwKKwW@jQJsX;qE|MrtO;#v_vCDLkVv+meP0vi9cdq9+~2M*NR<@nM#75FueceRd=;(egt zz!ib+*V{x8j)p^xxYxoe zuhhVk;8j8Uj!eVIx6CzXCPGI6u>R?A%R-;dLhu$XFqz@#zv?l=!sthP&awP+^2LWy z<58mhPhE~~n`W7Y*XJq?=f{Cw$W?+*+4GsWzg7_fsB+O&sj2 z1`@7w-T0LZ+{^OUAgczM5EK%6ZC9A+-4*63kj}l7n5Ks7Ypeg#oM%jZg{x+_f$kd> zp`G!PdlyZpyzA29i$c--o)Kg>*di5Ui7`Uwl9obOcn;Ix@NY0j@F?jh3u%sF4`$*v^u^;n1Hpa9YSF?gVmu9S3JdT64nPFt46yD32xQ zbI^B6q|Vc<+5Vx`>LvG}Vz1wuy?l|c+}t1eD!YNXZV#dKhMQyBHIDCypLsqn)eg|<1CE-CtL1`4kiy2 ztD+ZIz45XW0ds1Z8DDgUxfr@cg4OW0$XylU4W#tQ_zq7UqL}j{;tga1pL7(w2XfvZ z!W%2BwXD@@FYkNx>I~bGqL{fyc>g30n?xoMkU$*@;iSB=ywU{yM15}g;VxRjq8FTq zs2MI!>)&%cY^w6#!%`f*G3pgim0*@NPT8+tI;<q+*JSjKq>-9fGwM6+(~LhIPYng?Le%-1#1UBMxpl|3{{7*V3Io}O zg@4wE%_q-%!>g3AT*{*R`AEv9p|Og9Kc5%cuCZ9hMdGB^-&>=a z5whsG7@ja-Di3vXhN<0GFpqv?RK37>YhK)BgvI~Sp@;L%KF;XxLiHn(E_OQBNEJS@ zctUx7c9_o^EDGlfiM6BO41f4ig@>`l^Ol~$Er^9qV+vY#LEA8i3k4*OWFO=HP-afZ zF7^*>=?JELokwqHJhYJgv80xd+yIxCX%i)^!sobv8+Tl@I8spYPh9=ntS0iuV2J53 znC$rR)zGmsrxh9;Q&UeX_CPXJ?6l-IEW zZk${_T0&>z?p>7{V@7lItk-btk=%phyE~@nJTf=7uObD#!*~>r?r*@-6>SLO3^D%P zLDw-NNF2$B#j+DZc=wfJm_8FP)83l$#%h(+Qgr0u;2gPVAQ#-!hjwjS)Z%sW$hL8Z z^SoYfEBhTr3qPaQ_hmHZW6*yJzsX8oIF8Y!?U?ih*N|3I{9r7eu!A2fKJqyj#)?W|g(dsdsG)Yma-SLiG zlfpFMZ!P@dt3Pg;7HRAMduj`6B zwE$Z*(=18$jLIn{m^TAAmqfkY+hbhLTCq{xH)7pvPavt*`XC3?T;Rq@|IrZ65%=F3 zX^2KYfaTwQ$1N49+Zl3e{P1-7)cB#j35#L7QE>7h_X!<`K?Y?XHGVD@F_aU-)OgbmwvJNbT0R{b_o;}cr=d2W0O!EEIReU{SADoZBzdW zI;u^HBqMxxm+K7#fo`vn9k-=Z7gZj}+XxhXCHVVmpAecK=a=~Vq)K1pjifiSc_MvKrN?RB_3ExJ`eH-|x=<^lRXF(0;%e5EaPgd+$=n4-l`!YJXbq9=8ga!J$)M95rlwihoJ!XIKy96 z-yI_30-Ub6I7R+F_Xae*&h6gioUbptp0!<^dXF}l_Fe$>zgcJK5w&a(PN|3?lp{7n z-JAFJd}?aegyn#xy~FIRgy5t^&d z#Pd72H(nLS8sPRhX&lISWwF^$$KpB0`KkTnhu(*~$Ec8qR7iuYi(w(KuKj{k0Q z!pP^J;odk^n4HABBjn8Iear}7{db1B8h1LU)gBeD7bQ?aEFum6p|s|Ay;{vLRFx+2Cgo|NZ4r<)c+c7Ik8Q#v9$|b zGgMs)57+1(@h~O$>s_Htq}07yBMiOn4RnmcC*9is-9m%h6`m+485MBJYs2Kv3bmHH zu0Du^mFUeBj!g~eswj`Am@`f03bUgmp0Bsmc+rV7^2Dn#wJ9+x-z>LVmR-Ng6+0&3 zRFo?b#3jhe$n zl@G9YYrXG1-%Ts&;H3}y!SUtVO`sL^ivZ(&zvP5`fN2;X<9ccu>(C)&%1X?W^97<( zhL&Reqas*OOl7=5J4oB@s%xrlI|PX4#%K%VPc`<4dtD7?gWEDf{QsE{6j{25$3kYj zqASBI@hx=JhB$kYntwN-x0&i zu=yH%fPifoDCvNy5n7j`t`>oE{ji|KDjAsmCi6taA}pGPX@A0HmX57xK{}d89GIQJ zr#0PsDMx@p<6=|q?Bg%T+f2b$HYQ>n{}MQ2d(1#!y3ya7^xlypnascMu|xANhb_w1 zxGRy#T8!@O3FUFotxAXG+-NP1UYSFU7F(L1C*t#HjVhtItd8viBg1~!gJ%?bFF|nD z&ZgqeXTtKDfybMR+|cbWEq{(a>1Zv%w{(VurfhhlF6i}?P<#*g!ShDkQ0|yUDNH$l zpIfkd-HPIyemk$pBeyhhO)n=tcpxpw+J|%w%yNa$7XcdxoKd!e+=y%na3bXUvk@LQ zJcZG9WS|d;wffdg!y|KnyM+Z>lCqb`BI!e2mDRjgvCz7y&FWxTu7j8FkMS)#8fRFq~C5CaW$$~w>7{To~&4ow2B zU%zQh^1k01NL>yT-e}FhVob45Qfo6ozZ4oBWBcQd8mit0ruhI-ng7L|e=f6vxug>$o+ zt7b=CREl2dXtYqJm005|V0J-H&q8pbaae@LQHdFA#a8g6*5tD&<=k6Uy0=y`7VGDK z{67GyKvlo~qEvFjBHMl0!`81Q;dFED z>aj!Fbs3G(?Bg0^Y>Pb78@xja*<1nhu^W`siaOnZP{*O3k)aRzkx|0qf#9|o^zAw_>(ZG;NVpPzXxq|2XG#O^VaMdB(#2gq(k43U!65E& z^XAQv5m{`vTPnFabF)b|2zydCt;Ho)hd!1~!@MMmqRF=scvuh!1Oo9DuS>u-a%*B` z=j2_(STtV*tJ6)I&m#n}eCx8c3qpf?@a(OH7ldWI;N*KS+1s>~j z54OtuMsm(g$Jz(qcQ5^IN4bsYM2?d)1&J~jadac-liI)PF|!7EI1mT~0`V22ex3AR z{c*dyY#7}d+)-q^`vLWUY>RVSa*s_V&7jAQdqld+f%Uo+dBA_qBRX~CMQzo?7IMnF z9pWA!B;93@blHydv2`p?`bLfgDIk0A+aK34-!jH9VUW|!j1F0mmt`~r*%<%%1cZ{6hsjg4{}!e2kQr#~7eJ9Md@$__(dY9!nqQ&4jx} zDL9%gQ9}Nd6K`PwxAar!hfzvWaCHM?H^S38I8;aZDFT5&Anx;aSl|i5uYb}`iLbwq z6(UC7T9=B>n>Urx1Kd8WE0of;@u&wsk={eaJ9Nfn{At4OwZW~&b&(4|ytF+_Ho5!6 zq4bxZSO3lR`^Rx&WpN>$ivLY!>pwG!pFx*lo#9F<(ov!H1w3d71OkD$f7}Du$HRoL zFq(#dM?&6RY%620UG9mOWXQ@#&>Q~`DK|OAWCrcM`G-q(k1v4d%ZOX{Gkr7}y#XcGtWFH6w0)e=n zC^>}N?%%&}7}=(Z8w?2)u{u$EQ_FIgYAGAXiK=XE-5m}r!!{{nJYIntBQ~CIak>la zW7iLTIF4)4WXY&Fd$%13eNfV@dTHM-H;I=Ar;inP!kiXTjp+<&p&@DzenU!+kfx9}TTjHTX z+U2_IP$y^93*tM7d+c%k?GldV;VdLA4rZgkqsN&1i>$#d6|4n3KnMf^fw&K>17h*U z#fM;l9~dR$sm8y{`*V?&E`F))bv8BUauV)g+n_WZ1mayXzAisbJLLJabu11LaxcKrLC8Ja(WBgIDwuU-r`HYepoAreu;Tb%5 z2*h1auL8@9@Og3UN5;Y;_LW9_y-||#L#zI3sea)<;R;zWzAt;#kF}ILt+w@WswzGnei4Uq5{qJPyCC?+TGl9;rP7N= zZZdO5i6$ELzn3e6$`{76k$31Q3vrMIoE#B|WAP2eDW>v@X@WEpvYlu%jQBcYAiKMP zHAb>%sEek-q@k(f?E56dqGR1$PDDQ74|V*AhR0U~t=Oee?lJb%vdD!p7N;J7Yy4fK zG_;l|9j!glZ4xK9Y~b}fJ@S!bf^U3tV3bNF(|Gjf@z6&{9AQrWEapTw0SIH9H3jWR zapII_&Y=hdVrrBlKD8z*$@DOJxnIr*)P`lZ*>K!u(*^vZ*=#fl<%0x|92(Z>ve|(rZ!r>5fXR`Pqd-fEJF{fVo_Y2@H7jPPl-T0a9Ea~ zGh!z^66?%sAN~o>ck%x!k2Gw%?%dw9+{d7g?aHLymE$-6(x& z$9WB0xAaDYc&w`z^;?%)Rb#kKH`oR#Bn;!VE>^i5LOv2rA~iAaeIMdi;H~b(NFQ-u zgt^Wf5*dej#dz^);*mxIo?w8+Dfelpmd!9=Z$_~gS&?vAI%BlM|N8mvk29ZT-eGLt zQ7LNOBtkc_+FTPKN;AJ1C;v{P=^i*%#vFf21meNHau&eeL0l%ZX!P&&>+0Sl3Al%~ z4@nn6LFm-D$FZGF?eM=}Jv*b$Wkg0CoKNX$$UUy9*W_BGT0QSl4(1@4x_HGG@oJqt z%0~SSePEk8qsj=K9^3HmO5PBgwG>oDp*oP~aU2*l7czEyaWmuY6Z_ET9nDc_t z^W9YXYOSfQig>h9<`ShXx)dqa+lX+Fu>d5`q|)h%JQ0f7em`CAUNjc5=QQGh-4$Q7 z)&v2_R2$8T+HHwdN874H+(QXIAbPlQSk8qXBk!Wv#}w`{7WDux3L4M4NV$hYt;^=+ zZLnJBtXD@%v7_*&r90)2Lhdsnrb0edjME$d`$)LtM)xCj*)Y2h1aZ5M_BgF#`sH42 zn}efT&prM{v6xG~HB6_=8J9J>7iupzn$2b*QyzAKizKqyA2bS?bgG;EX>}oOkL%j*B5&fO>p=Nl+iBwp~J59l^hjuN?2ZA z4CsPc8P+mahh>KyNC)9ya5f-ZuP%#?)%`*($M3(?j)(?+*9*IPVZNgRX4)QI1U&^ccg6wl3NU31cwz*@VM+l_~6ID|*zA0)EbY6bo&_C)ZbxhOVurSFOD*N0Z4Zj=ezxgvg5 z9R6baP<* zSgc~ZOvD3(7t657)6tcug1f53iZ^s|7(JYN5O69z7Cg!82a5X+^H^nOglWO+qSpc|hX2IjZ! ze%GwG%-vT~f9%)($D&KT)uMi@#B0{xHTCt*m2d^Sp)0(Ybxo6yl@&oDsYl;&-A8`e zXf$iN*S_m8_vxykVj;LcKK+r?Uwr=aKR1}TRGz3-bN^mU2=ezA#>HsGJ(wZvu?Fc) z7$+(vAHfz&d~UhT#(&hx>GxB~hr7ui_20Vm^jpdPrEi4;FScld~=R!C!_PP5%F>^6?MA+jvaSzVDktetZOr;DmH=g|O zFOIF4|CKU74fP&!5+=X;P1lwC3DSR;{0isUIZ!H-l|#vg=XqoV{Lf2@hgXQ0EyeKc zx!@Zsh=(}bWKZm|>vHp#9io}r{8${TP)YR5&wkSpXZ%udhFfd`QSxymy!(cZfT*h@ z9K{O>x>&Cli;0BzcyBPM41f2?`c`m>Dlscd=a&rw zLtBV*zYR0Y6xkG4hxHpX6coCadpz!OEb>8kM_fX3x}|>n-{&4JUy9|+J!s6`W7}F6 zFXo9i3zQznpZ}oS{{jbc4qVKT)*;-(i_*QmEOX%;2FP(ezlSj;uNY?X=Ww26$a{E5 z=f27!-#j|F{N0S@cPiS2=-(9Hq1i{2e(db*$V)&5KH$QU%bbegOR<2hqV%vjebX)U zt3gpNj=+hr5D8QbhUKbJ|EN+l6A4IlNhQ;?9q4SL`H(Xjlxcb5DK)GBm; zg0{nm^G`mCN`yEt0wtA^W-;!uZ?!m|($2*T8@jX)AseGne3g^6F7yM7YVIMa$5_fG zjD*m*v6$uX)&Av2R>a*P-y%NZ{4V*&3E%%4-4=aIvNU2^dR=@pe`Bw!;Mz|ViyMs9I#NIHU z6%$!!Q~?pSo-4E5x*hB1GF9&}A}5G@_$}zDG!20~Ksy@u2p7eXdaw?B>;>GzS}Hu8 zzTQzgK0<2fD>f$vENEmqQeqn0CR5o57_B==K|Tl+GBYtLcKiewXZxHHEA{Gk33i;D z6UA=LWvk&~rjzAclTc)x1_o{y5{(SixSX z4)$wYV(i0`p(+|9{Pq;RRlM%Kz4ChD$L|j>g?+jO2T4@3na}#kgi#&h@Yjeez9y#QymV;#ai_9WF-7u1q?+;yi>9=?*S^m;Gk@`<{tsD&pFrB2!u^U)IQ zkBhm#CLYgKK9$KG{y*-jlgi;`a{QRbo2k!S#+^)Zkk8lEcqaam?5E2O7PSH3Ym>$v zo2{`PSnAOeJ1iYA)(Pj9;x0>6Y2MmWb1xso3YkJJ{r6-_dpLim2s3rPhm|jg^NhN+ zDM-0f3KPVo0tbta>&n%1-Mg^bK*;bo$YXbZk4k0?8ZisROGdC0Z2;KC|@74U2*lmDLRcZO3LUU4wF_ zTyD5BM9w$eRPQypfL;79XKroi@|oO&k~SRkW+C%w_nCaYT1_PC(L)Tz9*a?rs~LE) zRIK(cxr+ECaggR6J2`r{p6M5^!-0Ea@MTF+yKMGfYYyeD$aLiq$vr6LlLfYXmNS9Y zv$e^Luwxvp=*1|0&ncw)`I3QcUl8XXFaDCSE1dTX-9|!u9)!N?AMAf%L4;x@h{vB) zYziTM+usAQK*FlI{}fi^jR&U%13BQG%f^$GvrS5GP*TAC+%e|VWwT7?>;V`)s11~3 zZ#xV@$(WOLyuGsGXPpPQ0rRn_)`P#63zimRu%CCcIeCPN$$u#~9dQ<0P`Eymd$3%- zz*wOgSy^tqnH%)pzxpH1_7-D2$27tYFhEEaqqScP#cHnC%jFW{Cna2}j=D_Lp}Y9^ zXPXc;+WgaH<*M}djY?a5iMEzxol>CjSekG&o!qFkK_n-?>}Y%E$#f_Dh4EjO zP9grxDJMqjTeYm_qsTuH=W{`Vsp?&_LkUqv8H%5_1m~lblQ*($M=vrc z=A>fw-Q|Ldbf&TXu=+ww&|C3|*?s2Cf^zE-FS?Iw-tjhcJ+X80y!q;pg0CdmU@Nll zg|0>F^jCvPZ2Y$XNxP0mFsh;|r2`$kU#`^tr0X93h_Q${E2}w!o8$yS3zd&;X_+o8oK8%6r2^V1!&T*LtB-KX=q6xjC*L0fQ{qLka6xI|A?xEk}45C(G^S8+%^m8 zN+*Kj8a{0i%{`ofiM)TVB{3)%EY;?9z#m2Akq~mSmRgnD`)=&T)X!zXgx!Ih zi|ecgl@^^z?$HJ%h}*~}(XxnRG~IoHK<`9+-{{=IYT_B&iGcYr&T zYeNc)ZEdMDgps%8U&s*Ry#4h(zzdpq)CbvAgK-sEcZRuqsg(U;uAjLH^(sK4w?n2e zJ>e2sdO&PMS4Onk(=NIont1S-<39GtV{WtAaNX2L`L})Zb`yQZj(448D{qxAUm#>N z^EptqTe)P$Z3Tt2YcbbD83AdvR)QRfARmFO6ymufWgu{ze&2pC2{FB?nNGzho5^mj zT7R`TY^3wmM73Bf=5xvNLwi0M{Z^rn?$*)t198q!2O}xM>PG0kXnr$jDCgX?KwJUW z9pw`Qq%(hYOQ$3C9&OnnYZam?O86*+SAeggdvOICTG;70xxBv^oZZGkilD2;HI)vEn>+gIqq-Lv=)CR2TiNol%gfW(lnQ777m0d%w8D*rCo?l-L(I>VvN7_( zDEYKxIOMIWiGjv>$w#r-C@N)QS+|z+JkOq2bSg`ZWW@^&;!j|ZWgRe!vXWFNTZ9b1 zj-#Qjn0mIKal{%i95Q*(n!`V(Dz)ZKPC}gky>TNdoj%YmrGB`h6>(Tuin;hr6h6eg zBLb|3?HTE?_wKuce4>a8(Y$yeoi0CBH;kbrm|Hbf_{CmJJJ9kaWq`lA6hHQmi*BvZ z(0ei3Gt<_>(Dppx4)xg%wraMX2B%+?)Y^9+xq9j0d@=FAb)#O)C2OjX+iIq}AOOeO zKg7A%uO;NZsT)qE%Z5=t2>m^*UAhZb98(RUSC-(?@P(s?laKMM%QsP%Gj2dUrj(e; z`P-I{+grEdV^gXrz|tH7e5_RzWt5-)SH5AM&Qetr#hYF@MhIQJ*rAZQ6W&<_jcRIisP zW_#JxvyyeXnIzhtBF@F0%`CtvT~_y8%*&e`i*OIHS6qUklL$Ak;}@K_GI#Q2B#6b1 z6b(Rc7e2kb-P7h0OTMG&9W6ew)^9M%yQWc3=CG;KvBvpRLdt5Q%{gT4Sc*6pZ851? zbXzwR(d(#gghokUws8Lz*{FZLjw;;LE5lm(a=P$D@+p|}zf@$w6C9 zF6Xo;If$)Wqs=*%uupQ8@KxlS42;ioW(LOmJBgdP{v}+<2dmxNj`EcXatcc zN7#p&>Du<;Rnp>t;#^plMHrCyYVESH0-De|bmPntQvJG&izc*VK`-HN8c;k9c79a6Zydl*-E$D z8&oR21iE`n$J@!;8%3?lP1ec-ax~r6tQ|z)>AU-jUe+PWps{GM#&H5 zdYpEu#^TrGc#0!hy-*PI{zKXPAP-@MJoIh}Nk@=UiSrJAG&(T`qE;zS8{1C-(;aPh zf?j4Tlv?GtDuX(@?;U}QPu!^`doRk%P8-={Ks4@VHWy`L;t-O zO9Do3Eu6a!As@C>1nY_Q**>FpAnUaYe8U$?O0x>`q>M$Cs->^R(S$HhuCcY+__UH! z!KCMFO>4#PE*4=Mk!S}$HvEwR$0|0Rcu)!vs4IeaT%lKXA_@{&9^p3LH0!0o07=N$ z2>Q46)Gz_xyqbNw@j6|Ls&E3{A@6A|jitoks^~=1#L(N@_J{|2Gmm)l5{k}r(VRUe z{SZ{sZPNHW>o$h{f%28Za2MhXqYE3`eKXc0piCXhy1lPE+4|gr+aXt&SuA#V-GtZ^ z@GELMw&UGfVsoyib#}XZ0r%LmcF52ea=J0BLtkkexMPO6#OJC@_6G)V4_WdOYe#&D z*u(F8%hP`?lQpJnvS3P9m7;XrV%xkB#8`C+eijok09f(J-)_gXR$X!(TzL2@8Y#5ld+`TfU@9>#= z`$(!mqFQeC8ER}v*i4D~CKHjJFAM5icA{#KE4xZ*!ucTh`o{wc<7E)BfmsFx-HYQrl2Nd z#@|Nk+N0> zJFa-5L|u`#?|n00i!$9!i8Ed3a!4CTbt!TRZQR$Tr@CdWS`_cTqHGvb0t%N6{&L9hQ3 z(+ii(OVU^Y?eTIf&~QhuSRM}oCHAaT=p8b(BZStG3;Vi_@TL&+f=k z^WzN0D$C;3C0jAmt5P9zE8e8*~h)^yTW-Jlr^EA)SZ`~z_ow{b-a zE~K~oJ97hZe|IDcTMx9C6vQ9JD&tsV`?NU%AG|%rFjoA@+4g@pv&@jH78uabMQp9< zw;nh8Ftt0syoxE8lOjin3sxUSNwCd?3*qCVQ!n9^%BfS>Cdy|&Y%wg!$90QppO|$2 zfxK2AUy&GGZn*C}QR(JD+G3U}@5pj-%66&W>QpUT8~g+q$qF(h$+q?F$Ud~sx{eaY zD`418RQn;lPkn5N%lL_0Nxq-Oujh3Mr z5Q`HAOhabE=#`1a?wzpC-D!RfZ(#B3bQPJp`D7*2d})}?-;yD$0@Fq;v18SmXv?1+s_L-qk)L5EBX3NK+UA}&(j=r!$XxOexgoG;HKkMXEOACy zpEY%W`6C0BABeMdL6*|MJ*>Q5&dn-(zRImot550Ds&q7`@yqeh6$^?t`S_JF>hKP= zz^wF|6nAyvy&q!^A2Q($WfXU`-owcoeP>hfAWnus2QS2N$w#q4h?@{!{By1(6EF05 zoj0Kfig91`L3gbP`B>HFrUUPw{$O1u3x=7`C(?xc`cu`qrkYJ&b%?41AFrUb?GuuY zXi#zN@*!I25s^WTD4#ve01cR^82<9*N*y$|IBg=%4hG=Rv2@7~!xka5{4Xnh+fCI{b9awTC_WBd zuEg{kzn(_wI_-Fr9bCJkZPo1&S6B2z;#-?ZN2+WOHZ%D$Taj7yf0V?=9j~Gjvd!Ke zVOgM>MKC~ooRQ--{vJVpW7S>IZ!9MrP9^zpR7k*dN#X%IWKxotahwkdsa_FOyYKZ2 zH-SCtjw(0qD(XST$%i+Z6*h!+?OZjQqmx(S`15uSt*czV3|G%Ns`h z&uel!XEE*OCzTg$bw2W8hYg{_YffGzL~BjO^RB8U)ACVkW7_?IsziIqU3aXE7Q1f8^Anftt%^CWzEY;&e@A@O|vplW-h(oTb4d(;FJd8J! za+CasWK^$K%23+EH&=t;;N4|eh)jGPow5vBhm3x#9W!J#CPI+=;^wake@=CK)#8Kf zeX2VCr6ErBSQk1+JeS#2XR< zE}wyO^AT8IbTpZ%N1(nAUu6!r>y+bpi{*tRBCR;ZjbDZWd zHOxPVXS_HA6DjGz)lPjZMlkUsSLa&fVc2X1yn{q4i|moC=Cj94M3v^WEh}7jCpJpn z6tzZs6i>Uf$5YcFS=F|vP$<*x#GYcL#K!hvX9qbv@X>6zF0{wnTT^erY78N7_zmPA zh_C$G%)-UQbcWs>KqP*^0ylG6=fbw6q12Y*1!TJ7BXI1P7RA>cmsH$CtXJ>^wjW7e ziN&npic>{z)bg9!?K^bsv1aoZ6gn8BO2*ewrhht+E*up~YVx}mTru2V{Ni}358H!) z$I?V>N`1+{l+T1jww&-Z}{EXpVPzg8^5G4KaghZe|SrhN7Bq1Mk)D{%ZZ#`R-glpJ_1pdj_;so z2P?Zu!?Z_j9lafSdc^!#$3$ajuN`9{Jgl6ReO!nZb=a~Dw>_oMr5*F~u#fAv9<@KU z`qg~?seJB*@~R?8RxOz@(D)Sb)nP&QrYOl;%g_BY5pKTo4!!O84j+_nsd^W++0|2* zDtDjEUaBS_dM_B=EGrom*TpN8#La=nt6aF|9yb;F5F71>ven@oMpya%=cZv|*zhg} z-2{`9%Ifn2n?f1E&(Aq5_`zr=es@wAd- zE))AS=o4K(Ca1NFIS#rh_fN$D~-S#Nw~~@WvEbstaLGl+_~-Ss}&{aOQA9)TFpWHs`n}Nm^_eeMdKbe z6sEPsv+Qj%Ybz2RS<-@!CI3o+){cAy`dC=EHTQ66CSeTR14fDUCNlQB9`r_y{6qEppX*}1%`o|^nI3otagV({a5im6c8Du$;AE^+r##5ph^s|O zJ)E14MKf<3gMH4nIISS{xcfmb)d+uAep>;7sCg+QA9MBL6w@%cw8+_b*II`&WZUv9 zZe>uVo-l@womU6%MMcZ2-2yO=w3I03%aAx{?8cSDQ!Sp?o-^KI$Bp>fWNH%g)X^r> zR05k++ka$+$<({b#Y;V1J!zdTJG_j7SOyg8ic>`XwpM-kv$89_LWR89+|%gH)>z!8)2S@203yd0N}j*_>Sy6ohT4&;)P; zApg@g$fM3!(~029&=%^HNqqp7o;`MW#cXT}0O4@$+7hOO>zbCd}U1(~@AAa!r zmfaWfQU8q8V0p=Lk`Yv)qNMj8Q@TZRIG zb_O~K<;pJg-=@E8`J6)>E>Bv|OGmxATDKfQK02du6K(JGgCMgcin^BxAyzY;1LcQV zhneB2i1>cX z4&2UdpIAuJ(FqJnWgi&Nmx9Cur)tpKr$IhwGMh{dpH7y4ZK)lDlc@~q2Ks#`JJF>j_7!Nj~86wfooJ+`=V0-3yGI<^NM zN)lV^ntj~d+Rq!s6u4TELTMRm)K3L3@EbkIusuP(RW*##`&@?OW&gOjbOVvlS0wat zMNaQzuxLWp-0S4ab4WeJr$M?QlaZN9-58|G7V%rfO(a~}AView%G|wMc(g!sda3%U z^cOqPa<#D`*oRJ;vSwk}lbM&&AUQZkW4Nre9{r|l<=`|LO;?=Wo6{TpDXk8i(NdKG z3ST`+f`N3Tg}RJZmUqR45`?%gxA*OBYYs&cZ^8bsO|)# z3EZfooewU*KXBuw^;>tl3 z?*c4oAUsD`p*H#ooiK(~!`LQ4vno#qwmgsU_^^%+mwR;lQ34V(Hf-&-V)Y|!pC}_N zqmkw^w%vh0HnQ98QM4CIn*bSo4-yb54*D6WpWY_iNGCVbdbH)4C2!|3()Dj&$-_oHQMo zO!1)VML_0yH2KhyTdDij&Y+EgQ z%#|Z)o{Nc1FzPhKt9Jg>Bmt+0IVcll?$g)MMm_ zD%ug=sG7mF<0C40hxiosrj=roHuSg+9@UQVn3)_j#-wIEMqQM3Q*}v%F9+QViC%Uf z9YAnfhq#~DsL|uCC9a!s7)I_PX!KF$0rwDW!P;Yc(#bI@{01%`G0EZW_*51Pd?-7= zw$$sbvjf)hJH1RHA99Xg5}#I>b+8Va6Tx~eEMLr6mY6GkRYdM_ih-}ova#)gkr)nO z-OXFau=>!`+!XS$3jq+z_v&ww-g!DGgJjJmpn=LHi^fl%rH8H2e(pb{AlF5goMtv#PNLdpO&`lUWbUw!-kob7oA(g;NWRSreEMZ z8#$t-XOHPK7I`>ld(mQB%i6R`ntW8w4;3%{i&6=YX2mqJ8QEVbEO3}eN{nn3{E%Od z#tT{Eu3{&l267!!ZOiNv^*cQ&`RJ%FkfV+l(e}V+TJD{T8qIo{Gs>MzgUZ5j-&P}{ z##DXcY?Tn{5FYM_ddPavz3BJIUxM zTnPm2W{qp^u`d77Jr?gbJK|%}NKT1k&E7Zpw~|R%j7+qDiS)Cj%I|c|PxkCH`sDIr zcaz?rgjJDyoGSUqJLHeDgf&oLEgd zE9w#41Az}t*ZCY$w^rDyjK6Wq=&>b6$wtq36vymT_lFrWR56c||2_9b`*Su3v9&ru ztl8@+)v$t6#!3Gi%Fk9uYJ}j)$E0I4f?`b1;*0#vzGuh^(3}vB${H% zYH@!EgQhEXB!?n4T_f3-)>Cfj9o-*Jwsj%Vz7Z!L%C*VX|Mx9dWw{ zmvGxJK=Uudh&8m}9z%=7jKw&Knc_=fKEg3e%2n=<7F5oId?)wVx+9&wNBqoNT#I;E^Jbcqs^V3*~Mv+bvskL)_Wu zOG}7SBG;E1T=E|Y<7{1z3kw00tp1wNs7BbA1&`GXLClxfY9A#SS6gZ5W8tdfJJH6- zN4woojDdSn`8EP!X}irw@nTwO*AAZiGT+h(w8mkojgPy%OoWU>i#R6dSl&qYF^hsY ztJ^&joE`)+x6BCnDDGI!2VskJRX7AAtngG+0mpN$n|YQEuf4?C7M>_i=XPrh1> zri401%02URF`81YH05v5{lYMr{J|q&kZ{ge(joR#2JwU?|^ z^L1n3Ob|nvBW%aW2Upu7TXnqjIuXC+@j2?ao-Fp%%3EbA25oM|+$q1Z$4sHY4Gbud za&WYd8?|at5X-HAhVO}fYMA=BpWqyaIEx!T-OW}2WSpiEIL-9A3y}|KDR&dd2L~#x z1Ik*J6|d%McRo#7T-pOFVR52-S(fU*?M@z#BQK)uh>x94pdDklY*nAE%u6Gr4#cKyDItYWp(p$2Dj|_{|L}-^ zipl>TpBhEcy>Vltgiqy14Qy45IJ3|aB=fs6@L}AF#NMB~_JQLF>ftyaNTabm%63PA zWZ!R9psyQ+=0i|DJG~Ul)>kmKt~*;1?m@;aen7_Rsq(i#I>6`!qx#8?m{nMv1$9yuNhy)rAKc2>w1-%fEz<@Wu|OsA?OHb=C@Y7@lf9C)tPi&&x)! z$z6xjta!zX$UaVWVYNeUACCT3*ZR1Y??c? zau$mtB>k>-tw2%8HzfPmp-XF<_bHMdvL!c7o)M7fS?jlK3RAz`c29#{$KTClK>4#9y%=|PPAbZeBf`tAemB> zd<>W@=$LZ@9*I^{ARp`6W=xFq?iS;&tcduA@lCRtIE$BnVP?y2XqP6)F5l#IV{@!_ zr9-r-FNhQ6(jpst;O{iK!o;gO$3CcZ57bW>e6g*NOe$ADI$UawokTKAVArN0RN@Y;lk$t@@Ep@Ag@fr<@hsCy{gdr0Bh+YWp1(*AZs2P(U zjYU0TPN_t7iRpBL3z6@t_NeQWW{n|noDR+5SluK3`M(9?f^*w~Pd>ys5x2%_PsvHg z;>)(*zg4jg&UNTR3?YBbST^c;;{qpX^Gv<-1@UseOj^Ji!rD?cxkk$%hp#1-ITpY8 zBtoFYxogo=+%Au1aSrU&}0%N{>uiYIE}M-UT=iRas=!aYVhP{lhP*%gq#;>Rv z#eBs)X?MzfiaMHTGz0H>gU3_fmeok7a=C0S5uWonMpdD1387Rb`k%d<_O(3vd<{Gzv z@6pU{_PO+cwl?RztItzhw$hJtM8)acS7EI{qnD^bs=ch8ByP0cQKRm8!2oGMmcJA5cu?%{WS;-S{c^#5y$O0fp9)jL zo$n5^m2TcoG$IgZBkD|LshwVTVDoDfoxmj1+l)RHb-@{i2b11$f7Q7tf8;WwFw|%E^+oJxxhF z>Vz>nuFqmyFXXo3i;+MFpM!!NM|0y_l}d|K@K3evPB^}rlZ@pyy>ZJGJ2YCK^&%86 zp|x`P)0|mPR1^8Z;Hm5@!zZrR{v(qrG#PO>#i>5b<*GR4ASB=-wvhJ46% zbu^V)j2VTe|H(w5ac`=2Op$7zJccs1Ii7lz z%0}-?as{J=m6N^vd-bz_-pWmUz9GvzHaPL7Qb$#6qKZLA>O=R)(Q{h6GkGT8jVsG2 z97Hiaj)G!Z5|)Ljyo<_fb|y{x;^Tkx(94(2(!D7`4fCRDTrB2$|N3s_?=P1N)av&J zb)4}KX90P6g?^x2g3P@5BD)q)55`*2SoCP3o47pl*-Pv;_46=oGHc4C7Mpc#!wRRH zPDZUwne&X1{2!;bXc)*n?&T!@lhQ)54lA3=w7>(IvzC0vc*`nI)B zzku{c)-ZCZGo|@Rq|zB4Qje9urWzW4dANQho|#Gx~r`nKN~_%TYkjr z5>M+iYB@id7{!=!XOO&<%&a#b$0-l-)o&ZjGMw5=U4IK)F^oscBuKif(jfcYmTfHp zJy+1TMf{}MWX{a`LhXpU1g0JQkjS%5#<<72wQW_5T=Rblc>|@|_xM~es_*`@p(-im zf$oRoLpG&Q)qF>a3Ut0~cbAa8K(kEpV%BrY;(2RlXU|ov7OQU?6(YIE=H|+#G^TE8 znXNjR;f(KuagR>Cb&E8pjI;=`??uDeyK?nVWjRqZ%(x&iA_nJtX=$WYiVR%k7hUIINh-M*s^{Kv5$6mWZNO_vx%=FQrVW^4~60$ zMH5Gpajwo0Y-dz1zB+Y(CTpdQuxSP$k^Dgwg&&BomV1D}Bd3gbeeN+7(@m*C19$9T z|DX-@h;Jkfu1Z{Q->in^(nGk1@-~epT_#sAokNErP3h^@A9Nvd1?-Iy6&(1&=KZZn*%PI8>Yd2f1vDSv|_K3H& zub3US__%uq(^E$%mu!c3MK3_ToE`d_#U)BDhph#!Af%AX4WBrpDgpCF!+1V3Hj8wk zO?mZbwUye1hn}O6fPxn%ADz3irPXffKyf@0skpI~D>Q_cAj%{|9pWJ!Tk5p+--M>O z_Tjgas~XFbGMNj^;I;sNJyPcQF1aAL^Qu$`P=YiR3z zUEB&?TbtHg%b9i2j`UU%C|Uev_)iB)kFlu8 zM}EAfseP!~2OlRNG(tX@1-s{F{tS^VKfFW6dK&t1jS=ztkhNjTml2Sl&3xG5<*w+* zh);>sAC;hKN8NxU$G;PmE5;gsXlW&U?vPl0Ei84MSgE30PuH4z zbkAb&9MH(Rk?dDWXK(frTctjD;gMR`8DFOLoW+SOPUW%VYfm|E=W9G{AD)uYuBaWm z!%5hp1ystCxp!pMizho@DL;ZX)V9coqV1Cpd69WD<0<}m=S7@7r&=Pf*R*Zl9pukBA>Rj-OxtD>DM5^##&-gZD@Hrc4`N#d{Se>KE2My}8L-OHt zVDs!|&cwVYUceW1nQ$CjfW|FkTtyuak`dRfzHHwIf{?L##}kkbdm8y@&!Hn2ala{A zM=qDM=zhCH?C~G*h(v|+O}av5l!v$%DjyA=`_9kccwE%^m3sZvVlJEeYpycIG>zMY9~CuQ@_$nz%4dpfpm?hrqRj~q{Xo*QYvEsmbo`m!G!=ET~ho{{_ z!YI{HL{GVS8mr50TZOQIF30o|R;wut(G{-4h$b_{UO3y&FTA|JD z$vRwZ+&2-N86#S>kg7mC+p%?PAu3QTRtLTRGyIT~-PGBkAElvsYt5WdEkq8b_6eF& zbsRrP(HvTAt8^Dew7!Rk6b;FknWv&vHVNc%Tsf=qX)JV-bEp_s@cOi{ryUO95~piR zoM*tn6z539xxzqBVMBT1)?LD%FpNZVSGzM%KF#+r493grWy38vA3B}M;=P#K)N)?G z&Bv5+(=IwNK^1@cfZef1g}O0t$P#HMah&cw4=od(jOu#DcJc(fKyA??K2~`o??NE$ zQnwmrjx@eP^}w=V*gcofRFZzy>dKyUl$eV{0XugZg@P<~8C!(B=uVM35V?&^+C1=6vbE8vO4SPPv8TnRZo*g= z+iyw=Xo+)gCv(X{uWRz*FD*s)#N@+bcVs8RfPDOqBp*hhW)>at{8#r@7vY2_jbXjm z{EWu=G~r`f4&EWr{zYNof`3X=a<~EMjATn&S!l;;f^QB29r|=apd))m0|l~mWW)BW zR)C?%#df3%JmT`wXvC`BiSFm81bLkF=ZVE5*n}ShDfS)uxp4+WJFi~02wxkmjXoGW zpQceB7=%6Kx~@vYI~_h@F7Ma=M5?r`Ia4l&NK?h%^P>B&HkheLV-}KeNLK-P0VB^p z1=>d>GsD11Xju}$l9)EHYL18#8sdE5J$dEU)M@LG)rw)fHj;@C2%FRBG!^NW(Doe- z#JtN2g>N<4SpL-Z%W?fXne~|EZ@xNX*Oe{jd8q=I-CuNp1if5J7%zwk!O3Hx?LD2# z<5KX zZJm`?-U@UzsB~d}d^l6DHwlM^cjz#7&&h`veZlgg7WRXn-RGPuEtC(6Ge(gQ3r-yf zg1~^@wzyOaJZB1q`<0N7WqAfA9MYAu^Ydi9ic2a3{d{^PN}#OONBjhK>7)7bE+lR( z5}K=cu}iO`cK}4~rAK=0@}h*lJ$11RR3tpcKY)O^o4@)3^j^m)Wxx2pUt#D9MzQ)* z;EZN`W&+X|Bi@v$NT)f(W4pu4$CUgdq8p{bEvM5?D zzQV{GFCND{7@Gf7ze1z9Wz#5CEb&fkX&=-ga@(V(qxNJytt}nON6{E;==4gp;D+y7 zjGkP>)7D;P<7bHU^RQJkYeand5oTE?U+rjg_^C49Gnt3dQ|Z#HOlb*wB!}}Q;w&#X za>nV&bNETQ-K~g|Ib#_0CY9Fe;m&Yeq!v5>3yo(jy0Q}b7L8A>>O%h(8*8MXnp}s8 zS1%wRw}E>&bXY1G6-r6rpK-MA{i$FK!~i+f$U3y3$OnO0UN)WR%oTXHc}PB%e6RKG zZHtKKHh#QWHxjMOU(p-Q{jr>p)AE}si?n#m%#_5$9YIxyr;0UC$}>iXJB&#hKPBuj z9ts&t$3X036mIf$9Dfv%JaqUp?xD;(dA#0*6cRyBWlofeU*WlGl+wDAryZY@Y;I3o zusfacx)%9^HD6rHE!S~4xf^GEJ5sx6Yfl(I<`ErL&z6phZ4$M2Ikdi}J(k3oWgzW~ z`|0bB^@-Ey|KDM@@&!(9h%>z6nD4_mEBl>8Z(Gu;7>h~O*5%5S3dHv0_P`o8zqb*Y zxZ6{?2e+J1@)GSYW zmVq>*6O1IK6CRBuvO^QpW7M8#@DgJmf@zMt*{nazYc~s-rduB52l+RP)h7Ga{=n#^ zQ@3z_L!8m=E{H(eLz(F>ev^>b4deS3g+f<0)8Zq3@;m7ayB^`*Q%(U86Fpt+ACtI}$1;Gc7);*up#fGv>2>VE#7qZ^P42?cwquH506WUSoVKL=U zr^tuoA_SB>M&qqg$#LrUc}%6+L%hGVEYi%9h~C3fc@0nchuITvcd~}-bht;T;_#an zc#(e5G!8zdwhE0{$J{$+=7dJ=pr;9s_-}=A6Q`R?S+sJNPg5z{d37M|#N1S)J;i!R z83>IIlZe{Hi%er4wAnshVe~ZPmJy#wYE2H{27J}>1s_s2>Um*ztmFRSXlRYO>Fo1G z(<~fwB6&>t>CVc<4W1&O!0iJzt&;^FPb<+CZ`b?R5!!#BXon zyJ_+``QXu#rNF6$DZ!~F$%kd>$j2M7^5?oG<8q^Z-w9=@_YUEIf^A^^!cvRIj6I|s zRA*wt$;qTnfN*}-3`94~?Wp)WY|MjIYlTk3$~1%F@KS91QWZ!LX?>{;aREE@)RdlN zv(~jGW;N9cY$bcyY_D1u^mFk{o}_QTvMHEHc{nh|%+(sNRsxq~aP{IxMCKxe$AsTy zR7(b~I^!9ZR*SY^1_cXys!z9og^-Xf*`7|Sd0xz*U|bD!NKZ$%@p3X3$%8E#LEW@j z!paxKnPeY}eq6mK!_sDwKs>y79o7xDOIPM2AGJ^U5*fcg%$=(loH~KxqpeHqr{rfT z4atXlqfq+tbwUb7taQ0wGke`_z~|S(87oVs4*clwEm_ODBO@PTPw8>#lMBPjo3fCm zWE#cPeIy?$R-gYT@j4s8J*pYP>6F!cs(OX<_#2!W44GGiD$N~6HrLjdww97k4|YVT z#|obVozRJ7(nCxpOs9FV`p%mkTF4Nv>sH73&=h0$MpW_#U!+L$-AM=X@&63 zpx$);*;u-K0QnGOFG&d7ljOrRE@n%HQUCAzIi66SkrmvRyE((S*mDS_qe(tJEn}f* zLVVABSZ|vtNy(^*Y3$EQ4j#%Drqd4jX_N9J=tubMvZ$le(FvS(XYzWTMU13ugcA1$ z-CVv*`er_xI9sQu;2x!%LkRt&Ah1T6kSPqZBU`!I6N#3IcPcfZRGiy)=}jByD!T?_ zxamhX#Lbc-BJ!56Y{Z$O67s~8G)m;}!`Di&Rq^GL>V62POKWLGpBggfT?gJ#dJ$(x z#Ccn9%7nH^L4KWJ;P$at%8V?14a^`PF~0++`-+_Q+T;7f&@a*>v2GbNw~cm7h36G` z(x{55CW!?8{*ezAr7d-XN?3Cknc|NzEARQ%V$=gY-@f>2?=}Tl^P4RB6?m&>+oVNa z`dF-9nJJ5w(qH`ckUj|9d~39(I#2r5+cnSdF+DO3qwI12YA~@uZB=6@oG$y_}Ey z_>by999FT$k3i5-mJ6QX%@x&{#XRhoJeV$R=s9yUHl|!hGRCOx1nW?3pm&4cYw2GC zlC*8P1vhv++uGWKrj3L)hE?n(hd8ImwU-2=mNpv3GlEH!7LB^Y#YG^l%vswlC<_Qm z_-O6&>(QXKsti!%qs_G)*afcf&kLRN|*bYcd7QrYAB!fmul}=2+u==Qy&pt+TZ+XvcGwcRxFmN#Sh0D<*2PUtGvujjlyL0f5So4xG8|iM47(=AjYv*SYimft`yQ^lx4466+opzf9xd9vR}|aCEAn~# ze$j*%vdB6R=XbRkk{wPQHOuq~`G@h1KlGPmolCgk5_^S>@x7Mq=T)uut@!4^R+-6I zv^Q*09eLg$$Zq9QO8Sr8bnHbkfB` zTpk-MGq^@1;-QwaHDAIwrYn#+N=Y=v*@wV2MmLxxd*TJ9rRquTs69M$hDEa^V4B}3 zRdWH|DAmu@x+eGbrOQ;T`Ob5&Ph!5n*^eW5-l!8E+~^2I$8$-p+VZQT8py%v(bC5$ zrf_Pv+ac>|tpwxNk_ULH)sjQA(Sp%iTM1$yt+8&&V<8W~E>$sQ$fq#3T*)S%?)IvR z94=?Yo-q6kO7}C}NFM|Q;=Cc@h#evQk^H*okmlPE&eVb4*33Y!>}jP5gfqO(_!K=? zG&K`W_#G%oYfqK-kzfnAErp8zFcR+&-jA(>hPi=!Y~OF+UZr`4jiC_l%3ZZ89O&@N_hR^OiW(mYzhZ&x!m}>P>&}SJjxUOFKt7Ke9%qmip*l zQ~g0b%Dl{6d9%G61WGt}Q+Y!xO3i8!XD`ILih0PX1!@_{H&qpDj*zrr)Lk;o--FDk zbP;lZbSdr5uF1G{NP(u zPdu_Ld4(RX!u5hO?4T;o_Twz=P+$r}xTZCx5$++m#foGfaq>7Zz%8zGESx%-a(dX$ zU5s6m+Jw54;zT~}CWWXpb%*(|+e9ggYu_xKbJ}sAw$`Y}lmo0LS`@%iMfxaNNdDeRo@?nC+ zPpr`1%qT~Dw&vqNiB2g|u5ot+`RM%6C|z}7uFT&DHKTkV^}d+5m6exN1M0K86P(OE zUg2`Q>W67s54$4^D(sNsv?Jk2Y1H2*nPjh6{-5+O$c&xPNSUV0(u(R+ z6%sVIeMHcMvfV8zlV#9hC-VD|9&Wmv7GfN91!`KTrX94^T7eK-tL4v~ns?k_@d1V> zrXPIs*Uj26S$S`abcAo+sMp96)3PAWStD7McbAI!D$b3FbGh1>MwJmt$e&c!#UhOa zh(OpBJ78rIFs|kw*`qb5L64ZQC+BBQ{JgAuYCTOeYtOHdU>g-9@tM7o#Y&g^lyiZz z;i)~bx!eEmh^vYT=K~Mq4-+MfHR-nn_j`yK7>ad?vFm*8YG%-0g(Wov#e!|eE50~BAI!Vc=!-USdb1| zmXk5J*=W>~`C>8G%e_~B?>#9N=uy>N=fDq(KojZ<)o5Df(Ykr&&&^_k6yQ}3UcT*7 zHby>p(6M&9&2q?2WaPs;qAQ}bsUv<^yWFnm^?h@1AQ8k#;$Ojk^dv?3s=>(gJ z6)By&23mcGzf=@2grxDhx}Ot#4<_8^SfZ}D z?FOuki}#vb=A`rVx+;GdV;p+@YR^7_j}V#iiI|@U8|4`#Vt!pqMCY+d*Vc}%vISkK z%CKA$*T!R#bBL>Cn`vRV(XJyjiUZ4ZDJqYg6Bx@)0>uK(G4CeYw;!|JLA&dz?lQ0A1hi9;zbGPjVmg$ zD+d+M%6&cYE~?phacaOv4B=l~|1FC@Bnw(G>|9fW><5=W)PRoVp>tLOZ#Jx>2`ekl(e!xc@yvz0xFB zW^k)QHf%E0u_kghA7`QBQ~ksyidrU?sf}@NaX9zb5+A#iZ82H933-?6;tGKl1nY7k z<5uR0e&xMVe7#Zw_zkgTt~lx%-IC;EpHZ@!0fnhp=^&baZi4nX3uvpN!ee3CQCs;L z@<0S1`iMBi7~$_qUK(!0BGoQh zcxlh$EFP3yFz&4}MLopwN1iu~mnHdVlA`>x%lGR2h))*_#2P|mxp9^3kPwy>6bLlxB~Uf}9H=hZNfmi6I>ME%xFq z0Z(98y2I!-rJRWtI(fu9!qRXnN1H&?&EnIXV_8$F--}BVSt+ zG?lZr{_s&YTU**LeE0V_Wg*TrE@q2WZ7^meW!5E27~9fU%F@(6R%1&~ra9eLiSP;X z(IK5S>FCU?ANPoO6e@otW;wK0uZoL~{nWsIa`zLZde4z+Q0Ne$chhDnFc~BEkxt!H z$cMGd>0Vgw^03&<$rSf5h}?pk_spokG|WEl%SzIGgK#p-FmGyuSaMi!#~x|J^!V|Z z^6XwnJz8`rT2Ona{DUbs4x2fTSkBc{w)fP(mr56l|69!^`#=5tATb`Zno7|J?}$;* zYvPXhdk4;E=>$B!_!Fa4ES`&$3%s>u!@Nezb)y8WASTRdy|DPij%HzwYmyFYyb5{v z&F)8#Zy{uMFw6HiXV!HGc5I=XG#qu`pGEf^X#68rii8@EIDd`A`)$HjefZTNQWyuze`U3mO@frGZ;xvw%VzpzszNi+@U!d5XoB=Yy z-@T1xw)Yz;OPB3ceS`IGNIs5sSdTc7E1z13_H(M4h+{dMFZ<(J)8ykGzL`X=C;!4T zHwm?)zSdsbrya8L5@exXAVc&H6C}#`&xok>BcEg*HWYkL+Z;og%gP!JBOMzX8#8qt zkhXIFTu$ZkKTBuo&-ZfqT%~qX-rr0FgkyHVUJ$xhE1WPL#Drg5Eo46y^m6c2<%>k= ze4UeK?ow8Mk!O<}GLV~gBK+~VVGr4VD4ITQ%jg!L$hXjl`}tPjt8)FeW3dS{{7p{R zXb?xCg>*TYH|A#zi-wWALwI<`aMonR>3@mD1Mz@F+cU2EBJY8pm+^P9wKCaL!X`5s zMX*aBPU|l{PCml>I-RhuciZn+uCDNdeYHY4+YdvIm(XXhneBZ)9sY^t4H;{ye>_e; zY)wJDLmWQ%n7_ItA5@W#eIOsqft3$Fo=e~BHL(7jq72}C&PiyNp*zoaqM-`Uj=m|+ zJF0uBlnz9$1z%zcr4iHj$x>XpvNF?5EYK^;@2p0qpD#frWjARNzZvu{bN{JQoF`Z$ zE}3E)YT&mR-Pxfd!XL{3mrVSnx#qrm-Y%%(6JlaoHjRbLocNCNL0qY=N7N3uhdnD` zHQT9$?m#aqRSV-sJ*KNW;D|<;M_}r9z;@{t5EH*RI+#G^M7Li{J)>CRTnB$)LH5zi zQc`Hh@Cn^vOXONITT9*tofHCbU)CBU(Y&N|6+eu&XLKVtjqSjE*WX1$qk#GL%Aq}WH16R= z`r=M2b&)dD6)L&M$~5+|A}=^tx|EzUE$CS_`{}n>kiv4C<>X*~dFZP-2YQ$=B}UjU zU%n-n$K#iswdT9^^XAB%a7kABwaA`wWYqC{1b6f#G8*Zc=R?gqyjh%b3C>bJ9xj=x zD`h%`rK(ogy0vaW1#{4o1$wz?dPD=!>W%*?^glLqF9UmS&$%9HFuWtd{ z{=WFcVIs~yZkqLb8~Di5=0F-TC2C|R8pV^OW90XsSM6r!(+EVnBSw@=lRDN;rycIi zHNOBKs?C){R32a#&Yi|8x7dwx&C$ifmmw-s(>aaO}x6ukFpEB_jyRQJX;4 zEu6^OBN^fwjhD1A8JyZ?>p(ihFRrhz>)tvvjE$(`=p}g#xV3ajT9zJj69o=TP4dlt z3QmKiMuF1iyNiZ_c8iDyhkKZ2R|Y=7@PlQ=O*UL<=tP+B{rLk2x(E#cz&l{0?tS9Lc)ev8)42 zl^3eiIP4Tj!awzH-NTvG%(8MF-pL^25LwSUW|`;bUHsEOX@>#@NQ?7a&`?492AGm22a%afc1iq*YxHdeSJN#}}w}d->_*U!!E&9eEe+^S?v)lczLUtLg#1Icy z;A7B!Lis?JNg2umWL@QqN?Q`|o1lZxQ(PV+yOH+csze$1kXJjkKCrZRbUL#^sj?J8 z+{bf4o)68-G0rD;U{;iTP(EiNL7PRbzv+(pmRY<|G8Pwoz2rT6H}!H?npym$8C^ui z&Sh1(WlJUPT->7*%QMM7w|)cn+4T^7Qr)o`xAG7V+;YoFsG5aziLCw=7ewI)*>6NB z#k}EqGhZNlga$GcNv#5LT9y@4T^j(|CqBp!|%MO#{W z%JgG0CF4ok6fPrIS_mM zs@YpcHjC2};(^0*nm;cWf&3=F0R0nWM_W4C-K8^{W-aYc>SI6Tog)^ecAxZ_AO0q?McP$<5)tBwSkdMjr;;2-|cFGdu-Avjl@=D++%Zd zrM1%9gpyj$+*(#p?OwN1<^+1aajP(_$a2cX#p7HCAZPr;TX12rrnr_q$)v0Kq;tCg zj;4=(;~d89U)!ReO9t$a4H_XIqiKdh$8^S*Cx#fnPMaLYJ)$uWC&oUcqRF@I7dI=~ zZ;?8+%A3pL6g<%Zmjv=+f&BV)@w{$Vb+*EE3*tcwv>SQyE5lqi!Q{jGZ;+o_x|D2+ z7s6!I$0hO$H)`}~A6kPcs~S80<80|HseD65L7A=Nu)f&kv?wW;P}F^Y&xK^IZWJq^ zlQ5&~BR3H?u;(hZrB*OmQ{RV4OxMII=^#sjIQ4sIa|M6o`R3G!gcK+SXX_l)!=A>t zjxe5@(LioVH6znoY9Jc>=|Li&|GZN351iAupnV*Uy>1z$3X^P#H7RkD^?ZYWa_Kw9 z`3u?0Y7ZkvN0%k{SR-R;Gw?_51llq%8XF%SZw~6wp4Ryx*224`8tjY(Jp%S2+qbBq z7ONn2I=1yI-Lda3F2%(spySqRBPlx_AoV~zh@ti&`J-VjnnpcCTyPNVX_t?QzFVE~ z(4@?4vKrIdz3~FuvG3c`ag295x`(Z;CVd+^Vo72G>Mcn=?oWC?5MXs;*h_lSM>*i~hEMJ1)e)i)^(J)TvZ)4V$mx6biAksquO3M7C-SOhH(i=_vHKs>OhatD+Zrcrcd4>vPSw5zk+mIWq#vKLF7 zdx(2IC&|b>D^gq-5)tnCVm(`|RD0_nIdv>&hcin023~phmwa4oH0z~H>4ZG$3!xuD za-4j4M;d_28>*8oI`q+k$_sXbk<5$wiR+Xn?&*6PFmH8pvOAIPe|iG@?Xk+*;JlAk zB6ns`k5+3+zc}tDjAE{!t|xK83MvtGQqpZ26;O=O74hK=UsM5)^Li1PvdeZ!O->Pa z59KGu{b(xpt!Ag5i}pll!`5RX&f`v;ctnP^6$blSzQ)wYzI8L;9=cZxYu3^k*7>Ay zDPi253x^ct6f;m9CVk0aQJ zM|^7pJE$!P*92xs@s_n`?ZY0KxJs^tBXqy8Z2WsOWmGt;s0e*Hez zD)O()A>Y@IyeKegGUAK$}mvoScZ8Rc}W$Ym6SXlzwF&QBm0h*6J`-x|@5 z3r#1)9<8Xchgh=Q%DS^37hgfTJ|6H88zd>B-csHkR-@l5 zJ0S}{UWf-7r3`se20p%1AZ}f-?#U2)Y~mifglT#X5rDt3 zXsaiI+7{h*EBfrpq=)U%w<_y|ani-Xx!?G*S2t^fB*)|d=64An=ZbR#2W%cmyGYT8 z7~w07?eW!O5O>SntJxLS+yM~j%@&=JF0y6v&*sM`AHkWct;QmqMZ7~YE=#^u#0|0S zZd13}Y&Htl)pf-_91iX()Tby*;^*QpcmLCME*s~+Ftgqyr4>G{p!;(Hs#tVe}N?bVK`Q}XWAxje_a|jcoI(Xckw|P@r zmc)75o>2FLl4S>ar^slbo@a!SMiGbSE5LtRgen`wdewITs}~3-^OFzXTh0#I$GWm$ zqH?RqC>h+B_fp+gR=pALjj=xIw(ZT|sb;LPoOhV$lpYRVE2 zotrPPtx}c|Qp?sa_eHACIcUSw;aB~ob)3acCt)~gu9r}JP=X!2}rT0Rc&@T)l&%?~FmI`y9 zShVA&vvGbXPSZ|%jDL)#oW1d(i;rPc?7_5)x@s@W*(X>3{zBC>elmPEcY5dYcgn=- zVY(UdU~>;B;Hoh4geD)KWWF$zw(!UbLK&UZN{wSo-x2SRu(O<&k@?p;f9E};FMjA& zG2i)BpijulN)B3S_~auWEfJYJ?IIPYOf{C1nQ`Ki4^FE7pL?}_&-Tsv#|S^NMu(qV zb2=;Vv2-}|kVm0V$vvGZ>_N7r*}rJqb)PVE8EPx?F5x$O;9z?GFP&uw$`X<^jaycD z*2&fmn)QWt>C?~0SrmEFfyj$kiA9qq%t`0q+|B)_R65Obxc)3vw!8?$ z1I<2QpSz*76^SO4wn~RFJ`WtF)vsA({)iS#;J5Dg=eS`^4PF0-~EHIZ!S{OCOM;2 zZjX(l><q6>S#)8^}ddj|0T+}z%>MFBH zAG%0`;se{+eieAZaek`zU_p2yOU4RH!y!C8{X#9(a!XFzjBQE@$hNh{KfcHBV$pc} zcM%pH7V6CRx{oRu4>C(f=Udj+=o$rqsT3zRhrclgmSW;=xqG)&nNchxt~a|SWAT9@ z?9f<}CKA6RWNMkTFDN~%1NC zY8qI6d~wgu?KIh(N}a<(ar^E#NX!&sR&A}a#@tzz@1JEZ7wgYec4e>ALU!>KnFqA2 z?bXkBS?$)CXxIk@MI+g+#n;`8$2Mk%=Kg>7{>HJb;z}RK=gN9@=S9dW zcN|Fu31nrj)HFr4BZ1s|YeCznyNjUP;6MZG0Htm%K8A&|4R-0$Qc9r-Eh$@e_xt-> ze{*K$zUjrW6I(GbhcuNXfCvB%703utW#9r9FV?JXj`)6;8pbfVbW$~Yv9z=?fuWu3rr?QnbgY-M(wR2XAA3T~|+AvC6RCgfqc@G7i z!8JC&a2pxlFB2wCA|AuI@x1&jgQ2S&>R>`@q#12l5fOTY!5rQHD$aE1ZD|xN3wChY zY_+60f;eQf12QC%!`0a1p+8$Ve zE--(0c9uC|-WocQdT0|SOrXLOm@FV!Q}RDp_Hj$%t?9f+pT~MwGa^4+esi`T(@3rG zVe>AooK43XyhvB-0DPpa&%kQBV~CHrFZY(h9O>;}i%%A#;A7nLmgx1pH8$vztG+xw z((9D&U1Ph1x&S`Ja!zRC6yFAz_DcFCvJdtB<1TL9oxTGMBEkl$M`As8cj3HD_g7_8 z5~yuyBrE3Re53&1bC08OGVBw2Jb8xhh2;P!$e3C4m~NU?R3;I1dvhPAY!3+-F$@K2jK0QK2#3e!S18 zrd@Q_CA}uO^$Bn77L?AnqCDudaz{JpkkRK6BLwlkjA1wL3-ck9?aP74WM< zy+Cvv^t0gMhHlShKKO>~e((XX*Lx+0?2@ztq7S-9NMNs?J5l+^|K%)Hua5hB*a3<@ zQVH#pFAm$cn$tjs5>8#qr!M?=gG-H6#vqR)#G;&V1y$m*OvblU`x7yiVh= zMH<_ZarC$e#kB{K-Yq`ofq8x*VTR6xiIa^-nKBX;D|Q-hb|F_jjI{~x2X|?F1@=7o zqvXVxhxlewcK0q1o%i+xvV3I^mcjtB*8~9Sq8H_GH%A}gWNk{ zkM^W+03dXxNN@|f|JO8 z2S?@EE##(F*2-`_kE$p8@Y0gmzK#JtP{LPKg#Y;qiT zX(2&=a6d#Je6;R$6A$Os5@zg7m^e9lQy#*S7^k!sHOIHIr~@}=n@@1e?XjD>MPxap z_rwf-+77WtU*iuxu|-Ac)JSaC8&U#vw zWdeK<7X+r#>O-Ipx8!nJ{(-wn(klK^hxarLx!3Y0v1u{4mzr6|aCmhK;ZygpIJti~ z_VA6=K&|MVb97T&*V2suq4ccaKo8IvQc+nJAG*UwVdcZGLya z=$_~K4dm#q7~G%yQoNvg=5sSDCQO_d^iae?SuBqKqHcKsL%e!XcL5z=Y$xt!$|U=I znLzD5pY2xN3KU>)|NCF5wIFJS$w{rY47elxEAav{W`O3tP?t9OW>pO2*yl#6ZN1?i}gLmNgQo}!{EeS z-r|lDgxw3`QxKNM~z`zwr)+BiuTIRsLuKdx!zu zqzBsCLrhX#XWQIK)(!h=!o=y2o6&2OK}yT zi86g?@k33S?7p_N=F^VM%cLonZk&ASIZQfcc;+4{-}I|KX~1C(Fl`3AZL>*c?cClw`d*7L70)$ES1%7`MvvU$-asyF;=v z0f>qC?~Nl5tgy#THt16ExwITLyVvotM}0$|S=zF3Z9hh<`l|KT6ynY1cc^8WG;dy3 zau0e-%92)B74#6$T4kfn@R=}i3g}}ICB=%%B;8&tVbVU25^SXJO}|XmaVJcf#P2Ln zSlUNU8mm%Vfjs!=2n{4P0b<*ByfKKbpuqW+3^ByVeTZD%M|{Oe9^zs;kZ{&W)MM<< zRtkg@-=bQKF!SDYn`DCvCr2*k;c z&2oEo3%TZW(nHy&%ab$snbK0l%&NPI70b%Ub1n9Gf!wqqyyNQA@3;7P&ZS9%PKS_e zk@g-`X^qJP#%RcdiBmga6#pF)Jp2s40Dljhvfhsr3fPbUs6bc0LggyG(vK?%(`!mJ zUXtyl{mKB_KHS1-6lQH=1&!eGp&CZwjMc!}+}p%Fqw@oe_^j@v;HF0uanP3O7E;q+ z-r19j!-Ez0cvFH8@kwB0>p%PJy?Y;SC7He<%fzFFRWbfUSv*W;ia7Q1V*X>Q*4>tYx6b-C_?5 zH59zCV;;+x2T5Fea&&Bb2fYV8fz0gk5J-xlI{>SHAAKm^10H<-Su+?WOq^!?H{6qX zd84gipfDz|$Mm2XCHV+th<@ide#Ew1QB6WHSe5>Eoou5$5-j^()6L(O0Udmv|}M~zVN?m~L%q70sL{Lz)SwtWOq z=`0eC&|M-mBtah+#%}7awGx5s$vQ6g=Vf#HF=66#V*%GdSfxG%`We(4VQbp4p0?p~ z@JLy5@J;SX3-|0U6o`D|sMqoAY6y8;u)Y{WaY@=wgJwxyj6p06^I6@ED zn58NF_*Pl6R;Iw#go)Dy9|RLA`GCrL*|d|-GBk+Bl?4S)sH>S0d&10T`T{Yd7C~SS zmuV6O55&E{WN!ZX(j9AlhNVzWXd>ZT>48Rp#Xre`>&rnC3wTW*_op;4=aGqEtDh;~ zguM+=NI=z#tR~oH@Mm6s6#mr5xNxs0W(}WtwBK8MR>DQna~hYB)osog=7)46vvCML zYBBJkX?zJmxVSoA+H`NZNAR&|p#+T^(yCtCTpQ#o$?0)h*>at7i2xd^L>|!q;g0vT z83hw2PCcOSIBuwuZf}~W57(PZKh`D#)3P|6jK~4c6HKP}eL5uLq7%CQnl1@ZaU!Ne zX*{UqrUrY=HA;==^=B8gk+g*}ANmwjjs{5==x8hV;IK7uwDCrq6ITNaOZLbJCxAGWA|3wq&E8(8&ev(9Ny^zwjj!Hz0C2r<=qV4qgIRMTF5%=h#;1h`Ig@o z4f42m_<_3PjVyU6Hr4g~Eqq+;!Ix|LDO-xnrMi0y-B7i)z#HT870Io1{{d@(yXg{jD$!?Ndv?1g-`{jbQw=zG_^Zr$bL-DNe)g}yM*grB-PM;Q zKqzD4Co%N4D>mMCt8M!^c8+IR-11$jv+2v=zvVp$3;r&pq)`lnrmS&K;6t%96;~4< zBraBL9kweG*WGvM(c~VRG3ZeXWTvXLHk~l#EhiHfd@YVfj-v_w>UgZjgxfymp|yvi zJzzY=!y2!kMS~tqn3zXgf?G4CJDGynSkDeJE&iQq2bK20k&*r$7?U;=>w~zFM2vatN zJ|K>3>>AyL^4bTh)#^Ey3GlJUQ>t~HwTS*s()YG&s}c!c#6fVt)3v4L_UwEhr!I44 zv$=l%n7l_=;X-iRTc{i8aY9k2QSM4#|IxT_zkPi4p^a%_wTbFHuF|Vi7D&4tsPr`h zV8X;a;txLf0RL?4R?xSxmUa2jikhAJk$yu<#tHU2h5D`K_z@jG;-rXD2dXWsWW0Uu zTUaRJm16B|<>&Rhucl}Q#0Qb2LVLuOV;qmkiKC5yR%L4!2B%B*X~}!UY21PgyCS$O z^zEOai{9h+{=)yV=|#k0wma<3@-3tnw;&dt~GnT};+cg^g+U zh&QERU^R0|t?SE>k|F)E0?UaMyREx4geIxua7OnjgCu=FYuruef7*l|Z@_h+$MYQ& zY5gua5R{`bmod~ym*r(1c-mqf!ySBl7I3;nrH_KxruQTWd8*1}rS13CepBwD;=i4M zoBj*<@cwaA&&ou+wmTTL#&{0}zLxpOhB6r{A=s{yGZX0K)+E%K7{j=VS<)a!1|Kb7 zEk7iZ#f_$1l>bcQL-AZJV;N@;6DHXUFt??bsUMYK=9?bt#qynxEe`1q1UwaDu0)r9LgzV;3Ln4pvY{ddW%r z0Vn^>AqiXBw#N2`IP)Pj5zK`em%K+^<~c0ixC&`@E)7m|@W(Rb-kYFUS8!9-e!s(^ zsjWS$9s9WFCFMtw3rME)kG!@N>(3mJ$TD*$^@nOZ)goJB z@{VjZAz6SvsQipzlK)&TI%e51VPbCJL)^O!dCT4YBlZd?qa90YwVG1yk!c2zuO_7f zahtTmbj#!te|U@AiAHseUA5?3lCN#i4AI=C!XoPWBRF?6$efr@C>F(SzlbuvLrcFuRi)Fq zL-lm*u`R!}WlQzmX~DorXR+%7dTfhnxh}r_hJ_67FkxbT*h6kAZOFR7uCs>mL-m5^ z7Yu07!B)vI=pP;+2TC=#;AE^D*NiUfcUmiKv1z;pk8ENmVHWc_FZt-dfcQ|*!>U^o zya@WP!XCb_dT11>eQM=KZ%5i}*m~P;%X20Hi!mmC-Ss@zeY`Bo8~KOuhrac*Y_^C} zI3o)j?*)83rajYLSsC6RR~Sv@J!Er$Bb7-I=w<^2;Y9kFfrxgG5_~heVv1`|cu`8W zRi5OqQ8~KORH6^Cz1J%mV2@k3D5#F8J4ia~7;j%Pf*lhk=6T2vcUuo?R;senA$OJV zcj^l`INdg3xy_eJEDaO0Diy$E1e%Xl)CY2MVQ5WTNcwROg!BERqqc}OgjSZ!N-)ng zAN}7y2VW$e!o-gY4NRMnj;=BA(f8?XFl|xk4rpy`+hNNd%5EybsQ@1y%`7mecHwy# zPgG%f37bxSSn6 z^8Rc}TuvN(I6?i?43Kej=%FVe39yHljn`o+LVYbcNOm{H+^F6*SKfq)d4rENxRuu= zzCJ;8YJf4k@jc?)+RjY3NjRL=sNGGUon&C zL}LX8GC`Dw=`o!=W`GX~6?X#OgQy&!q~3@tM?Y!S8xtnxe#($5wgMjsPwX%GUdraR zXm5;PJ-rdHe(8r4HYJ!)c|Ng2IY$(HwD5Gbdff0spF*o?_24yRm=^)0o2L}cCf1gdN^6* zq<$KaYC+|8{19VDSBhgdvXzC=0zAUVT@RF|vX|i1YS~&eE#yp?m^b*aehOV$I>=f< zIe{d|q!r*THrCs^kAu2ekBBoRcKOWIdP^+-_N1e=Zo?h{B9MD;DB@$-GY64*N17#q z&r6=);U$p`%sxs{07^(L+IT}Y8Wls@lGA5WEfFmCo6=pur75e-wsys%p<(Vyk-b$! z6<)ILZ6c$JY74-LOCxkzD>8eR>3G!^Wt`s_9tJ)DQIVLbnle-0!Pm-W-keV46)>EF zGSq0cj|D!Y2^_DfDZ8n84>=#*eU4W%=6ahjG4B9b#qEYzp!a2=?dyA(L`+6Qot;<% zMqyV^C;{jzuTx&7SnM|x&$K-TsB)MOp&fK#2VtW6e7|DA$Gl!blJ$3OL zx$loRNp5p~Y+H4z+8GXY&c!dWJ#Zbyp@*EIu1uJ?51S6`Ds5bq>dt?HQ^FYXXyZ1w zM{#6fD>D;3bQJ4<$MLjoq-h%qpBFZ-7 zdXLQ-50fnc3K^?=@?nWy@Wt^{fDiB*OBFt$U|B|f2Y;r+DgyHG-o0^n=t(Iz&+kgN(dapG&zg1Y+86|H=1{jfPdKK8&cfHfuE zA-Z#|^c6ejZDD%hSyNYM!o=KTQC8YkG2ZTIy(unrq6b;H&)Jiushz^OsviIfpkL9&WUy! zbk7GLyMR4BwuZh9ZC*IElC#hylDvpMIk-22Q`whD{^@k(KSBGdUcfRBUIum2GJ)8K zmu(BsJAw?&Ti#3(f1;O*Y(GTlRkA)P7*mMTiz~{-uz<2m`4WaB67!b1Gw$#wAor7H zP-S~?6=*ou<@i_Tm}A1keTgLvK1dlPAJzbqA6hXpQ?OmP&QCuX0$HKTVaU369K^c& zAkU|2I1Cy=svXP)oD4)@-Se3d6 z@Ua2d!(*SlRHa*F6{n=J)8jYNMZ}zY>}iX->aTsH;Gdl1CNk7Zd%=sfeVed9UD5As zCiHWp}CaFGqZxcD;$iKGTLE_a;^i}4}Ye@TCEL}7Ge2|l;lit0Nb9T^1PbFQz z+k+Bg3UQjTh(3~FFe^U)>yET@i)GM`k#G?Mt>A{Lb^02`3Qpi?D2BTaTid^V_@^KAphbE$sWq~tHpbf zZ(69MRHo?_B)Piw*lTdl{es4NeZc$pFqIG9On-*6sRABK@IepQ7Fjd1j%eGG#8O5!%$a+9HlO0`uEc;Ll>u z>Qj73w+3yk8xS8mbZd($vl&h^CUIuM#C?t2242Q#nQl*9<7L^JD}EElI)1h$!H4td zFt#vEtPi7EIT+plLw^as-?F*dkj%O;$CKuo^R8A;ipzeXi>wtDazB7(a}_V{GN+pj zV#$bywql#ph!0)eDAxQ9O7{VLcqNo|!DyY6Uy8q2ck}LT)Wsj&zCqCVCyJKqRdoc{Dumr&8N2_0%uMxuC%Q&Hab3BoF9jaS9jfk>whCh1Mi zTgPxVv6SqpqT5}3{c&VuJ0?urZ{}kYKPK<|Bo@bki`7F453v;LVICI% zFui`Oa@kQFe6&?P?F<;w=61aEoY>8}%3|3ZE$0^h@DmA(7W!`wvR)zh5V3+P*D#4@ zTeM|le-yRI=WJTmMG*$>J^+xt>#hVJ1GIJxzz0r(-qc!1J(#9-Sum@EdJTaB2*zE z^wTWVwBt=5_xsb0O~r`OTYBn7tCqM)otZFkzvCmgvj;v5SpepvJsS1lyC+L*NGM$#_50wI`Oe@&U8Xe-K6DMS_A!x7d%+#`i-d7gKgC#D65wMIb?pj5 z7op^;8&`bz-G}+n6dww1&~2GFi-HgA_RPgLVd8#oJta)~>OA)-!yjZ(cFF;wjXB0+ zP7bXgSN?=5&h<~g{E#k`(u!=%05y(7IR1fJ+YR=Z7xu{Lu7ZjPD|IFxlVf`2-fU_I zT!}sUjoE&6}X#OX!d#XdI3V;*#b;>Yy(5KxoQph_u* zJsJgMm{k)d?)To4!URK8aD<-0*n4}LMS{$l=p?%2Fzi-4NUD$U&slV>pCt){-)yyU zGzl}^iOlrNm@oDyHgFcehn0Y>wL6WEPGY~Uy}?{Jjwo!g8zd3W(e*26*sEE#B~MsputP?T`#@#G@u+eY?UZQJqy9VG*f0S;Dh?L z-U&BUiS@bP)o<3ph2#EYFI#`Estn8yXiXb+<4tSA#2JV##@^rIlZ?1we~*fxooP#z z1W*@G90XO7itGdDe4CBk@}tAfBkd?P-;S2P=mjKY7KV9(4|LnXYrdBlx}fWxB99RN zF5sxn)K9wbctVXR;$u4apwbysfDiX&$NeFCx5o%rjy)vDy6fbCV6WWU`zYhQJ}+A( zrPJ`S1{k`#?u6(2aw9!UJTTVY$X4IVSjLcQ9`U&9ZVdl4R3|yVLCf))x-_FrGL^~4 zDxsWZ%_TNr;tWKgfw3!_$R-60=%Rlm@m^tktkc}Y){^(4Yr-_6>eiSg`wV||B{v z!hM2_fsb}nCD!%}GVPG`;8QxqR%sK_bvhkd8Ppc2I=ibC*etDACo?a zduoJ}n)t8D`6h3M1(0&oZ>p>dZ;ll(HKD?mK*b9by}aqJ6%&kq(vS)esV}kI1u@=* zX5${syE^}nS(hX(TMbOfX27?*?|9D7y$Km?<1M#81AO!+IY0cQnJV**mwFa@Dl#m) zWQ)(JrL)@+#}9j&dMCslDNXp9Fk#~Uf)DExahIl$f+1IA!6I)*!ABa^tHD8XTJNoW z*Bv{A#8{4YJ~fiz)MyJ3LGewzn5I7NKuKBCNJJ(O#va!ed!Dc>%jMbyjRE?DSi_+DL~lr|PU z#o~`A-q{_WYx!(?MlZ5aK>am|?{A7rX0psJl;2BzaIxsbawtH2^pDjp zJK%5$*_Pmg6G@MmPPQgY+<)d{Ahw9AJPIW7CklMTn2$WFKY?S?yZBP=dU+ZrK4wTd z{5F%e?H^xSu?O@qcei2pTQcBdZgW5k`W3j?e_MdAw$+E~lgGl2uP7ao;SkgwH8IBG zbG=0q4sKm!Z=dj}TtZS^>dd)8cZmWXF7s&DN|D6tJJ9V5|7JzJf^Id-a;Ph<9ZtYl zuFDb?CSDcU)Z5OhjtFm@wd1d)>CF8qP(8thSF5Q;%f@+Tp5S8%S(T#Ih*dfiYp?els5^w~uk-pJBtv;xycn-LVd0BTDfhiqri@;~?HdjQg!VVmKuZTGZ3n zEk5pcdhT;%>KW$|%9qPZm8q~1_K1b*;RLHw`?_8D2?*CK)D1M)6}#MKZo zJ)yiOwIO+Q?S~%>_aylEz-9SC+Vv7Bzso42n;G%W`XJ=8 z!X7vYjf>1snlN$S!AG`+@hxcZh!$Mw_>{*J^(}!2Wb)=FpT3;miWl16p{h1g@6wV_ z9n0W$(25zE`GJol#>z~+P(&A>!Vf*Ff21ChC`bcb9`vRjPa0^C!`S)~g4??I-2G~V~=#v7>t=PaW=q*xFPqYp3qyab?Dl;#EOVRysKb0qx24z14c%T)#)?mYs5U8f z%;uv;!ULuJu*(9uDUV`K|3TNOf*&`j`&9np9C~0!AdwG<6mb?&MQjM);j-A}-nMsZ zMdtDaevb4)b|w&h{SLL5CZ*mKj=A5!X?bcSNAvekF=Sqz%m5!p>OQHST5k*IJ~zWM&lNt8 znKrUsqhcI>QV-6a#YiPK50Vg|H3bRg_!J?G?amtSpvn>aC0)m%57kkXu&a!5a4TO+ zTd7hJIk;rqGx$K303Xt_mE(3>8Do-1pqGq0Hi?PbJd$2Ovw3*44h>gLqvbh+4-2YY zxa>7dj@46cY$R=%xtHMy(v|@qCQO`#8yvmvVy@~ddj$VGC=fyBF_v}l+s#h9uOG@+ ziR3uiQgqG_2OqXQnTxT55`#@AVMb++Q6_5W*B){xCfM~mYM{cOVIzn6@w7O5_Wk() z9v_4>x%O8NwI9@FoKNp5sFN>E!`_ShnW7lHB#2JVssAZ^etQswK<;Nby@$wVyQan5FB7Qj) zYdaV5Ip*X1hJDD=(3ZfZY`hfaf;#2t&&p%n$fe`9_z3e%>~y~$0x)HspEVT95 zcn4m#e7t>&|IqmE-Usl}=?8*QCc#Hr(NnR(w2wH7vO;&KY_6>d6KCNT2QzgLVIeSA zPp^RFqd9TU&T34#7v8AAUNqajP|ZZLlfNm?4?p%AUlU_&{071EiJCV@1Ux zXdF~;tQ1L-r0Rzs}5gI7h)1CytFOnw_a&hM5-q-+h+Xu{G zZ~EbfbZi1s_t*#L#^Yw*%zcVhNU*l3YN~eY5FNXH6a+#$=Hi+#aTWqjwrTm<8v7?C zlP@z00H$p$j`-n2QScGX%gXe5i{FU~4MC2_t3@*+b74N9jK#z5(-MI8&dCuds})~i z52^mtr7nSChj!d*O7H=`pUco}Zk18&qmRiU25pCIDJQ^3<4?|w0YW)fff0p#9`owx z6@qgoAOu|UovDIes8aIr;mg#Hd-GC;k4xdVlV;w`8GHz2+Q5^N_pynldOmQS&OID} zfObSuABMy-Vd6eVv5L8BwNxzO??dtBbVt(Z=z}ys(Z^RE0ktTKDeAB(r9AjlTnRuzK!#A!Edj=QJo%yg< zei3Ru_@ONv+5kRAhuMv(c|7uR>gmlTHeura26T3j!oR=CqL;!?X0Q`>D_E}Kq@mXG zrn78cZ-|B5?%VxHabk!kTKI_AL;WT4x*3rE1MUt}W1b4(=zh}9R1|J0#`L zElY0G&%?79je6LGiTk?;L7F8GtNsN{%E&6@$B%^L%{sI(DVGfjB5Oy)E0pSu{pRzRp|byVR;x*pZ~!l~1O>g#2$S&xXyW0T0HDQa#25Scnx zq&Wy-%Gy+=UL1#{5K6f2HdO2;ljUUPQ<=A3FV5l(R99`;%@%cU$+OF?1vId2uN~I2yE?3vR;1JnwIn z)n^?b-&5GDAnVzmPVmt@iW%ZA2;5`1-RCp84EvC;r1*R^>f74-g9A@~-Yf#A9ZP^Q zEL6pq{T88e2mQMoj>hK`2TxRZ3zOOe(-BxE$W6Q*0UyDh&>XGm2iakkYm=56Rh@8M^T!EsNPe2n>nQmnNGo(HaFFvV;JgWb8)lba(NxbrbVmVs+^-+rBf<@cL$D}?$?n2XLfjYjmu*#|Pt4l>qAw>?*CQf#y z_AK;i(SmYDH*}u{NfMmD&2rzLvH+jV0CP^E`LaEaaz6e8>x&a4~-C zbFes7mma76D_;n8m9M*;st&fKR*MiH(b*ueM}OKjpv9>Bt}CGj2v1$_S{b1Xtv1B3 z;Zo5;Yp>U7*ZL7TNz^Go%x|~+dKchjcBpb#Y3N9IK{aZe-i6W}8(WIDFXhu@!0L2ANpbRT%^g@tnUgW)Rm@`G$_ zX*Ac~go)DxA5i0h`6cuc`V8Z5h(kbUyscc6Z=aGs#eB3*@QB}8QEG>(FFPp2jY&&r zvTknsxlkXFbRlA`eb@E%lv&M)Wb%Qe z`8uHoUof|TtUSp(;yIwuHnEZD;4Jz+9wtr(d_Xr;lo&Yv4#k;E2!%$x6AjsqxM}%7 z{IaSu#_e_SkJD`o@u(&Ki0AQ5>ZZFnvuB+=K?mT&hZ+LmwjylRap_h&-fCId^U_NQ z6^sAZ>$(a~Hd3W@K3^&|N|}OxrzVoWn)Wi4q3F`U$GY*D5YthXIPR!QKZuC*Uw zOF22bO+Y4o`?%qREhuDNZpfqyCqu?QW>xXDjCleP^atYae>-oLYK3PR{(bRez=v|C z@^Bw8!%$$3edTVZkb@mh`}L13QdBOkL05Lnnd4GL-ZOOtsn_jwvUM}HPLQDkLg_-# zUrMhWtyT-)YiP$BLN0qr*-Wbbvy?*ut7Z8Jx7sO2K#&O&CQcT6Sm4L>VFDG=Gq3}x zwsLXigKp34YfGTuML`UHq;}Uz6<|**!R0dRV`3h0sfKY0Og21y@wbCM<5m=*KpQ#O z!z2A%$j}F)+Oo+f6a>x~>nO-&KU)Dj4w%e)h)*}msMr87uuE{+dI|Ls7CFDv#rV?F ziGdIK%Kew?zTj|1>1v1@W+LN5xsQIhVUb!>zj;{*v>fb?;z!J>cFb0FGNI(3e_t0s za@>#Qq`=3nm=bi~NlAm}9(yYDhw7^lcRcqOQsiU8go%>}ABz%vI0doiT*5zx8||NP zl=>iT@`JAb#pGR2qsD>!D2?Q7zr#y(@ z1pZ+~%4}EE4*odhs?-J84YDjji0muZRxIo+UAYD%>9 z)GeSaac{~j$h#6LK~eW2MP&D{obZVSI|V_;Iw+?GStbCTr?$ z0{t*eshO0lnPw+8T`g23xPPql%F)2bDyWcm>6Vz+aEN00!P3*L^a)`t` z->V0&#)JtICj~yF6LlW^q}B)+DCJz-{Qv&HDD&ZZ{aJ10I0+LfcqaH5U*p?+9FhRA z5q}_S66UAAm`i%$PncybROm9&Q1FrVB9~r2sK;_GEh|Oe5sxJJ9hqoBPTDF`>=wpYm%D$50HXeC2WIeYW6#gJgw)5~ z9iE3|EOY^otqVE(fYbh1wt{PDrt`gyW)am1KKT%nV|$zIMiXgRoUJ%@)0cYnf>eN9 zzi?rpv-bXDgY%`q+Fy#=_t$j2G-2X|4#E$EyZU2*LT+aO;4h5pO*x+Jh|rGR&eI>$ zik7&v#(hJAhN!+*MqpcPgb5#~Ax=&Y`%wWij-v?K7P6%^2U1z4ty(a&juk45OZ25u@~o$iPoTEGv2^YsYq zlkL1D@xdc*s?@-2R9j(#FsV?bW-Xy!O}&nCz9zn6oS03RxJU5ei978x z5O<|y+N1dU$Q>?k#$=teXXs72OAcW^0J5~E*4<9l?Dm2Ac+@Z-r@feq>w7_#wt&=_ zONhD251!U@K{|L!_wW_j@+VU6As~bXAH?6q;d4rZWDD^VE&xmVLB~0|r$ix;VqgCM zS+Bda!J6VpeqI!R97;J;G`|?5v*f3% z%xg6A`E)+-t~OH1g;XO?sk4wVLukUp-AAE;M+aE}KC&E`2UK_>cDxYxpf@1;_Ma4f z)%<(3KNWnm+pR;=HFgx@05VCvhfGTKREZC<=l#xwCN3)$S_{TT34J>~znv{WlU~4f zw>63w>LT0WFetPoWEB)2JVKB}-S=yhXlg`CLMZ;OWu*mRg%utTtQAxs!!HUbv2k)) z7eBt0m*9i1la~9g08(UDz1Fd9d3mi?i=hvl>7cqzfl*6;%o(uA|%dNp;YDyr|6H zpt+gh`ew)9V&t19+|;sU-xcVH4UB>swI=XaL(o$X36ExCxNRTiU9=DVnUPg2DxHzB z+c#n2xZnd=cVrE~WZgnJI&M=Lx%tPtRrjN(;|+d@;v@E3Jj5QhPVmTEx_Z%!$EngD zfGVzF_AY$PF`s~XPT3h0V(EcDK=W}9^(-xb9!j$rm4Ha>A-><#6v%pPa}SA+Evonu z${7C(df4+`R+~0RTrbdb@4SafoE1@~ce3v_<*QC=_*YiW39Rx?K&!}Wq&7|Z(eLwk z4>Z2ao63oPyj3G%jfJ{3F*+v3;@Ou~sY`zxgXkVF!9nK80+AHVe%NnlLdlDjvpFBzbCSvOWnuBGH;)JtOP|BX>3# zn@*VeZ9-DU=i`*YhlTzLde@^Bbo*SOBksf(N%^oW35+Er^w?UBb(WJgt6~%0r3A*1 zdT{n1Me(KBhb8u4`qwrE_^73eJ@%Z$G5ir2>(Wo3$)JC^jJpU`Gbj6IvqK+!aQumQ zJN&M|M}HRlsKwz2h;9LUv?IwE03YjwG@Hv{1+u;jV6GjKL)>-p>FQ(uQ_fcEMYV(Z z9EhPpf~Zbei?CQ~IL0S|B>gAdB%FsCHA!6cLpOIQDj)e1e>3nWgXw+C{V+d(Arzxm zzOqoR=F|VyDHMy5yUCzR6DFn;n|m0i#K#`R-k$+{h+W5ys7nb88n48;WIJ}=5R1D@ zCfUgd4d`a;H*+P`aX zlqXH-KrES$CJY_(#=85+m76lk4pdha$iA?f-Y5U#HM**B&mJ`~rrcxg~4%pYDj~XsV)VNVymAEoDT+g`@Gbb~9mYT0W zYsa->Dm?0w5ceuQ)r}tXOo>ktJ{jRd=whYQ+SG|RD5RBr2I&Byhv-|zPiU5&-*_Xsp6eA%8@B4jNM6nvUE z-N-pRAn;fLdv&QD6(2G&^8(q{6Z9ayf4YJm+pw;ZVQnY@2vL*>=sD#0F?ZVbOb-}X zkOQZ^Ii%FRS}m6O!a#~tX+pAXJcl}rr!CY?pAhRMckP_(?;P@+y2l9J13OFE9PUJn zBJ9XUL}k%Se@vvX(~&QAt%dxd3kI%i?Btcy0+HoRVsztlewb*UcS~u9fX5p z97jv~ak%WHBs_6aW!ZObiTq#`=Fnn@^YRYa5%5E%BWugP|GpAn2fyuAAN&4Cm7-OY zDsEk-Yfz;L!@|SA;4$WX524?AECby=zKx^0K^t?29<6STdE_W-HlES{RD9!$gz@k> z-6-Z2?}4(bSn4@&8z$l1bD87*I@zVyuQP%4-25LdsLGhH?`Ea;=`4{n zTAWe+;1_g;1isz6OX%SbX>+_ND$abweCBo)3eos8xKV%)X@;vPp`PQieQ)9Mu;|(# z5EBM`petbiBo4ni4QsT6fr2Yxs;ID(o>Y((x+z=xD~v?f~Gsz3Ey-LTE4#&by$ z``ZF)z*mWPU@UFWhigC&G0Aal}*BmsF1&SVtgLF)iTz+jch&RR@2Ty9usKjmV6(0 znt1xIHmzm3>Bzk&qIprq>mdg+k)csJm}YZXmg)M}Xc=@Pwypc!aq>aF+Aa78X7sf? zGi#P0A37lSTcb8_!-?qAPY-G*NPUR4Xw+|q0~Vbef%tSX^)eY^BJ9NKWg=|Yfk(Hi z*|p@)3P##y!hjDE1Hk4Pu^*-KAo*Jy;LUis;B$8X9}?e-JMs&!dGv$ESbA20kAFOC zz{e?q4-1v4!X8DrpyRc!xav=e?=J!N2&RRc6M72lFvg@uDUB|%06uIf1|c(4#bW>D z;#XIR-suH2^_+J~sfK%b7k^H7|@@>kN0bi?zY zyG($H+V@J->zzr$k5v-WaY(*CqJQy0M+iS83lcCQind=T%Ya9kkzLiR{%3maS>L$z z>jgm6d+m;EFNnCZ*Q(EXbT~Y@w2NMZY>X#Zu~C1v^yBhu91`;k;W(A86v~54Ax-n1 z>-_tI>X^G|s+>%GoxumktcOqs<1~EzZtU1$oI429p}WHB4OEUel)C7w%kt#Bkfve+ zvA{7EDofpmJjZ$J{f1(v*X0YzbJzOjJN)vCXr+4lgx_r?ACZPq0Y093DxZJq%}s%& zwlybyQqt4)8A{fea)8SW%hX*;W00U27|LeivI8%fDWYDvQYj#<2>x2!CF)HU-AUyq z#;(AU?nw!F##g8IR6&TmAvR-`)a20MJi>r5rF=68C z1wKIY!72#-?Yb;_K^JhWCXp{x+(V?|s`$Ot=9qX#NxR7Nro=0)3Gm@acXeaAbXwS> zNYkJwmT7b;H!YXxLy1YITTTgCS_s}8GBy~EgAZK=Lqe=EwpL@#HdM!QnUuS6<5dAZ zGT-`z%HXg+i$9jwU(Q%*LP`kLe|_Tbw&FzUQrvW@T0LKK#C|1!)D}5Wv7)L4yW>7M zld<3Q56bIPjXdQSB;S2=D6X5A>eQpOz}F$3S&pNRw!A(}T#PsA=4qgh8EVwA==&&f z2K3maq#31aZ0!!LMtd1Il&ZLp`PtWQL`@j%;e(I-nmADvKBfN;NzbuOzqnntJFR5# zEPlG*w}Y;5oE(Mu5RV*1ntzN`&PD_s%WyH7h4bE1fH z8yM2-QSiZ7*n~@A4@k7_Qa+Qv<}Un--bQPbxvsbG7H+$Ql5NT*$Cl))#gDM;DQBJh z)Gk&- z#jk@vJ3UE!NKMQ&_Xaz9%iF_>_3j>sU_SQE&8YD$m!(e2WY~{xwRk z6LP=6N9g@Jrc;zf5;PJ-!I9-iNrxTHy) z5v`0FjZO-IjC})7w1FNUWhh(Ug27!Ln}Vd&DTLG4kRT?$`ru@UZaQ{j=du4 zbgYwo!|cSJueQ?OcOZxz6R6)FO$tUPfvCv{@5kEySr1=i(`j>!WyOW zyAcsrArN7PAX6ZP=6 zHDThbyD5o(uHdu;+~4|8+H9|^#c%X;$m%ee)So!Sc@Rk^b&!(K4vzkeUgBlypx`g{+NPKLMjk_{8^;~vCmX$Pz;P)ZG z$3_QbJ=NJh4RGjvmO*7+!)42&g;G)rXjVrzCBg!-F9OlF15W00@FcBt;IKY#gn-3 zWxHSvv;+@qWeNl*Rvy8v{flUTA@g#Api{rAa+LZI`;<$aJfZ9wqp)Kw-*@^W$U)XL zpHz#xSH;vJTdQ_F16`Bd@(2;{&C4$oVoaV16JIsvqpJGK`KxxqQ}we!o-~bm{h+?A zJu{!m!SQ%%--L;ZTJeKGbs7a93t!E%+gTXtD!!oAq@9Bn9we6P4UALPlpXsG$j1B- z6+8@PU?K5QQyNHhKvVUriuh>7OI^5xDAzpK-Jrg`7=-7RmQZylp$pjfTNiN2LN3QY zM3wdbwa{sF02OmNlCL0QpW23#GW#??WFFNPB<G+qXWyJ^T{RJx!|h7FeChJ% zm69J7tgjYpuQ2JKrd_jDn3_(5sq*BrhdwZ$ehoEOkTOGzLj;G=IVrJeLr7r(HsNf7vw)lrTq-lT)96?6{g&?}_Pil`(xuhSU# zGUlOa4JTrErXT0`Nj}wZKBl4n(-~kua8Ly{u~BW&of!JqivPH&^EN>-jFT>1_;L2x zuhzX(pp)BrpNNUo$mbhwtfBImg&?s`$Z`~SwzhV4I>zsyv;$p`Wmh1T{A7;jHU?|u zoH?19_^NGAsNet#ZlPTMqX2xgqg@@D%bWa;eVq7>Bl&y;jpWqxwVbim7`gwfp%yVn7<7qcY)p(c%lDT8I)}Q^pE>mn!hVRYl8) z^T_5Y0SEO}tK#!l#eeT3tE!;DISZ|zCpj&m{3=hP;!VkUo&3OqO}v`JBiT`z(>ERW z+J{dy&UudaoU=vfNp~l^H>dvbyaRxbe9r!U|!d4&zh0i z3*w|Q0D(Y$zr|o!zXH+mB|1UPk61gLhWoLj&_}!o?~LVNz>{Efh&}u6?snu}Q~HnL zG6_4>al)!=Ig^7i@zvUy9!^8;frS!}W#Pk*8Zzw?sa}tzM*36S8`T}pJm(1Dqviht z2j)mSYw>*B6$3s_WrQoFB-K3P|9{|^zKhUrD8Aa8*qAKqrGFPI{9A9MHGv<IP9t62C1(kH2=Eb@_D$cW=<3#L0SsPh9;iLxv z0QvII;-oHPjb1W0?=i9NG$wjq+GmaZfOWG!>H|v0k%8R}|K0KjGw#^FBlDX|i<&NH zI;t*x$p8=&U;0=?i@DyjGVOAy2RoFNQs5)B6O7jR#U$PF+x^-s@L|VImSp1(@h5EG zzo4a`nk5YQIE_`i=#^B%zW31k95=GXBDjnxk#X3|RtAWTy&S4LcrT_fs7c~uxu(eA zzQ7)kiQ&+{h4R1`rjG;SgWaU+qzc{TB>Jd|XI0>XLY?gb=hgR~lI*}=T}nVyPuvM4BK9k~MaR@2 zF@Xq?`&FYfxRCg=ADC66V(9@einq7@Apg`k&-D(`x}O1PY5Q^%P2GfMAkAns(=KFP z=rTd?Qg`WlW)n_n=8ILUC1SgU8368593D>RPYt5P@ z!a#|tD+6I1q0=aCw*z+&b^|bp+U})lb>H25!CLbqP{DcN*GLP0R3zA~qmMW#oF??j zNBg~rH`r)k?p=9o;VFlxB29i4^#b+`L+=;_QSy&5@Uf%Ys>-kBXt~MW_w;Zteku1W z1)Lt|ctY{cS^BXn4OhI~@pVQTAc{G8h@fY5KP9TM6P_$wUsaauvA7)NAL-8W^18g~ zyi!K>`7!vz#FzYVEGO_c3q??t7ps_zH<82>U}4J5tGY6i4ScUJtP7&D11Ss zH7z0iXwz`zZK@l`${LIUH{ySBHmI*B8c%%$3TdlK%J`@i!20z-9=@?3UM^yFy%VNvg*-;1R%Tf~3 z=eOKOX<^|%vWYM8iP=J#Xn89!AA`f1i zY;WulRX`H6nARQT=r-}YUdWA6JW;-Y{tgcwa_rPCt3vp4s&EeD9$LUSacb{grp9ll zF%B$yIl*3{u(r@Gd9K^I32p3E!7Z58w9gv-(GO@wABNc4!FzeyR^_uFyJTlK{N@hz zvo_4l|KQT+R(Rm}GR2aG%FRjeu|v;&XD#Ug8lF~R(w4$h&42V~WMSqjP_<`R%|XlD z=?&_};yUy#P^B=9RHhI;L7Fh}<%)V}=xd=IiJ!JG%_OJYvXf~SXA1bRXPN*8i5wdg zAn;$EL=KY{qRE?wJvYrvm9KXne9N^J7ueq{vVgeKuM63;nI-I(Hj)TI^z^|f90v|HlE6Vh?{G@$=7F^y{Ice zzIZO#>t&5gfr&5Y1|_%sZ+@gcq(V`-JiWTN7p4%EvPd=>%ib|cZFwuABC!?4+&19j z^mbsea{m}RIpy@h7sS^~Xl49yoi}>o!{0rA?N*3AD5F6)TWv5#bkao=AFbGC0F^Ml z;S1kVPvkmpS+_T3@A%d`@TVT&_%)Qm_yzO|Ur(Iw+XsY|p;7dK-G33^UMUtnO1f0i zG<|tSZl7uJ(UzN}9VC#ZqmQZXsNvSNLxAunu2U-4(U(nyDqra@n`7Jtpbu#!9~6&s-Ew`@=`>Ch^l)EJcTtKf5c2>`xK(UFgIrEuM30T~ zi|91mO{3rop`M4Ov{aQCwAl|{=*gL%BtbFPB)UF}C7aRW&8a#8=^6nDWI6@`m8zob zy>zl7nU62eekGyOKXF}FrD9!zVQ|p(d}|rtI$DwiQB^~2xmHb#G1Q>g5d(m+t83%= z2}JBMvpI5p$;{9y9DY;Hx z@*422_;fGcvsebxo{%>9rrb5nO&zvjMMUJ%CgZjA0|g(To%vW)Lz$XvOF1O;=Et7n zu;2}X*KQvy*LfeebYc+l8}0V^k~E4kUhNQkX!tS0a|9vLJ4wkASMU%PD^2^HokRLh2=R+Af^Bl&7I5-a3)?th6DHiHYh${jU;H;VB!? zY@PL4LM1`^CG;WY&E_4z2RueYM6dfyulS|duQd25I@6kB6UrRN)wVMn{Jg~aG#d4J zODaBq3F%9HrySN%-wtS41x@-bJI;Z$HO%Xe<~!uJZ-_Lt&Clj|GR+@U>9a5I%ErI- zER%pS@#TmmIZHEK(((0AW8kBOSp_BB>6%ehw<7I>F>!(UII^YBNY=Zw0!stLfFr@7162=&X5rmK%nQS9a7$q&9w5i@NF7J!0GLYQ^HpmtoUNr15n4K?!4i{nf}H z!V%O?uzFUXGN1Ss!;|VozLIcoeCge2XTRZQ{&F&Q0nQ zBDed2bAz}i&!gh^Cs${%xAbvDTYO4fc69I&F>minh|i(k_A`UmPvzKep&WQ=^se-( zn6Hhq>{j7f3%#4I!{h4dsJ$3CJJU@*l=6X^?li#OUn9uA+5#Ky-A)#*+WZh#hmBhdh_a$O~(3mAOX`%J@;#E4fr^LNLHfw10gqUp%+U( z_okbvhzDeI683dlgs%G7V>gm=|i2&rIu{?$PSdOM>TEQ-UkpDv#c;((~2n8Ft*S5@lI)>Tud#B27H_pj_k$^%L{|lMf6hj+YX*u z=(2?VxmS=EK1=z*mfv42&1Zw7f4|G0N{-G=or@-ZyI4{N*) z1uwGr*6*hso}lcBg00El*7eQ&{$*l#sQFmGgO*3*5A`ohE;rRP3#*B<9glw`Kd4gM zcHrY7Pl-n`8DlOz?B|E9#haQct=7M+%_q)MEQt+1b`94&Ca^{IR-WL}vq394uozpC z!gy46FD-)br{LgF@Ubeu$M))~u5%f}x(C=}RUMVZa5Jo>eR_4&6jsYGbx~%}>{aL1 z8)Yipub_#Gm4*j31_ZC6_x5pm{-a$GP@2;{Xxh7B&-SR!-{k>^)V&)J0 zh|wRNMCwKvi$^P44%w(Cw%v7=%3w}1akg`ynS3oMOCeMWoF^*q;#OYDpe^XstuUe; zdaq;M_W^#;ZjHoe0<4VezHgPPNd+$Z4=bZ1Wt+<9P>~&uBwr6QXOS_TGSOh9*O%cZ z?9+v;lvWw}hlw*8J@+5-V+Z?utQ{UK?z{xg0w1l>ofl)ZAdbkpr(O8))khvHD-+*y zamGTW{eN7>siG=8U5a6qV!A3b{lyX=D|7Mf1c*FtMYN2ZUuN+>gFY7VPyGse?9pr9 zxrQr+fZ_>K2t6YOtJM^L$3g?l3iG}|pe`v4#7>f|BdcEN4DuTsg9)er9~;sn6LWrC zGTxp+e#ld{&5sqwOUWD=?o5IY+?vQ&s9l+>Hf`Sj{Q69vmkWPmeyttzIc#t_6w6&JycYdYwDC$m;>jE^3#uu1BzG0`%hbQrpTVTu)37!p zmVfav1sz^&z2ecUXMCeB)A7S zL&{Ym_n?2sp^Zzu@(Wvvft#AQ(!*-^BdQ4hTqIlI@<{dux79X|`)xfUqrUIJudiL3 zM9tnWu5 zg4P+>$K9&@s?8dy#ogos0D>oUsOs)?tL2Ml^t`+xMseUZrQQhBPsGc-{oC*VBEm<& zShZBUxqwsZ2k$rVSdW+=`s)?|k-n~6jq614)N7>_LjFTQ_tfg^InvgIg!*$_QxqqP zL26nJq6c-#OlpZY3XPj_eyw96qdqlpmcWOFlDM6ON%@Q&^cIh$gWHF%$h&*f(=P2P za;*3r9iBthRIgPtB6k}_CtZ(kvh~kV{lRnrIZkfI@BBz&k7AX(K`+}|L9s2Mjv?7n z&1|Kcky@+WS7X4Fgl9i!q(S^A^1MgtJ$hYrbxDJl3_PuuXRlf4pD<5Z_iI~|s+V4> zjBaP^$dUrxVy4{d4AO7vSqmsjycwmR9dR7=WtU&udRLh#GKkOhQ9Hh0O{-XFhGyBm zcO{?jkct5QAz#-5H^o3W777hJ>q`EL*ipa- z-H3vZ@YZTiIjGri7QxZfb4%J*J#E0py)DL1xz9(wDu_+>^CHTZis+~5&nK3fV!=Xz zpF@{Wc3riTgJ!ndl&+d4uVE4Y(b4tL0-Y#b!4!%TEgWAorD5nwU+M}>K03WS8pH6Wk!x-&Q zx)V6M?a=9Q)n}nJIO*S`2dh10=R2%Q6~61Ob>2Oj@I#=;!gs0mCCU!~VZUU(on2^1 zOw6YydfSsSozaXd<#!Ee`5X~^?Bg-;p|76ZQtpdkPR<7C5otrrC#5L;{)w_6So79C zeiAU*9!-=1G=Lv9=)=TWIYd|`$vmJQ$6?8u+)GLxZt^>Ubx;?Q$gMC8WFj`6DaTV- zyrnV7BZ)6rkMFYqeFovjl2V=~Jq%h$ z6XJ1OWEw>E9xC|*RlOEOK9A)HNYds^`U zVpCOwxJ%?lG}a1*QyLjhvEXa$;XUFt+$)c92|a2N4V1srVe_F|D7G%l6{J z?;@EheVvNAQm&HAWjiSWze973P#O^ZMk~l)w3J>{cTbI}uE*d96)=Ko?6I{q9eGH4 zjscG?_}{W7KA>wHxhyv+>e`X@ ztR=?1A5p$>PTf}}_VB#M6Yr#NswJ0muZS*S_hUvH)n?j4-{N?1mUzF|SBsL)*GZv8 zv58^7$QXP7`BuDn^Hl57R_Kkxr#@H;Ja!4W6YrstGweFpwK29a`BQyn=Ju)fmeD)o z$4My`IBUHhWoIDCekcw@`=mjuDbMlJ3j+pZ9Bpc6`DGG0_uR>d!^TSW!*$mb+1IGW zXF14*)##yk=dzz=lN8oLICfjJ+x?v&4zca2qC1SQFQ~=etd=J3EBLUW@hKm`R7^ZL z1{>I=ysgZmLO>xM{|*Nq{E&on+QC(*lvJ+u$s zV9z5|#k_E~ub$jzzX?af+*6=tf&(mmtx_*kvYkva_1LF`?=~k|tMJ+~*&H6SgN$!l z;WeL%K6d?wu-MiW10W=7(Q#@<6Y}jiW$P?%SHRe!%EE)htxd~n$O@)rXkFVnY@;8u zdFz8(IJ8$EO_VN0v4JWgm-UtGzi z)+}_fbYaFL>iMn($NURiI)C}x$10=&;8X_Y>Uu?lMRXYsio~O_o`TxiI1>E<%M7eh#6PGdkEW))n{&E>te_QwMf1oDR8?LZ>58 z$XYi~z!;YBLu$IFexJnA$7~ivoSZL*+K(9wNi&+q1ZKT|!tR=WfoeL7&SLUK9$FIF zT&LuQFLu&mg*x7r(xXk~8(KIfDfazZl-k3_5e>(5_#v69U8&|#crqkCU>vvPFdo8k zP31uDiPCBvN@a<~eNZ<`rHT6tJ__P2T9W7G{|)Qe74z|YF@5LrRFg%)2W}E_c&{v_ zB7sirO|l9mW_CL#!G}Q~Cvg;9LYbGo$w_H3AtyopO-|%iRf?cuP4FGDQ zvzlVF;-ATX5)F(=o20T&7wWOiw~+1hdcAD6)5(TR}}h`ok4<9za;DRvcexhnNo8Y;2N~|ybd$kCb>%chn4=L^gd-Z6oEg^g+UlO_q4r?{3 zy_4zJ^F>|tYvSHFPwV!j??4sDrE2H!3t9$m&+#R2*O!~BLmsTB^8B~Af#cRnzV{NZ zQHeb_74~4R<39Ch+GTVLDl~>pF^S#AL+*7-oWF<{$34lioq2grQQshdJ{IJjM)w=} zq*ZyQ@FR6u$KHZfuNRAj%Im%CU%Q{Au2dUNTq1(?W>t%^^>^5kb~Q?o*kf-3dibR< zbY|1IlVm?Y)7d+l%2T~~Sg$Xns%bGB_o!}2UkeBe@3m^To2M?FfDl8e2nnPc(%B6{VWAB!KQ z(}^j+kzJ_!FeS(E!Q}C4SNV%6Z4cxdI0e5g%A{N;qHYYFKL|UJ#E0A>UDw@Xjr7N^ zD&-)gkrMyU%ddckxm2or>FyDPUSAvhrzH3CR;G5&OAi)$w~M+)cRFUaik~McorT9r z>Bh^1-*Q=u4_Vipe-F#KgmBQ8EYca^L!v%1o=#|;3jCnm;+d6asaI93X9wM0FF&ii zb^JO(H42%rNJT8vd9*#wL|0&5Yx-_+WM|jU!w{LuRJL)H-4S_gumd^DQ?#fyKOu{D zX<*{NbBxa`9kEgRo479r2FqGl#xx5MxJPhQ4+?qik1)}095dlZn^M;e#p8q@0zU8r zYpI;MS;7#2$Bh*M4L`XZe0fo#k@RN>J(fl2cOLFZHYt9bFJI0V^`XAd;Or`muZiM} zM#On-s2g_5(j{r$OePu(hP9`VI@1m1pw{J0uQOQn;Az3HY@@-sC%@w7WD4V-zl3)Q znBUd2osY7e1S+H{yx)BK7eHDozl8eQLN3!y{fEXQMGGzYyogmSBs!ViySZ$6t(#1h zN)90hG~&{xL4+3F1X$$q7Lf{^U9!3@_pXEKs#8Vk%RTF=B&@(_3jRMj4eo<)V*I~# z^zfOzSHqW8$o%!k$zL@~-0ODJ>9tI`M7@SbH>1_L)FqMA7u0t_vwBJ2 zj;0ho#ocO&BtL=#%q%+>^)XNvZ^)G8aH8wri4J8Ox5OK0^w8N&f|~fMgAY^&(cHgC zNA7&A-z83o-NL;i^C$Kl2|n5Zxy=B282iTRm$JQg$ampD(O^kshQS#&(GA z2h7Pr0c1UywbZXl=>{D?dD)X{VxJLQo|1`~=3}dzf#JWV&I5&Z#i z&&2@kfv(i0)0>s+f?Me{N5Et35y$%#O6v7dqACdWp&c5K&9uKe1RWU#dTyE`y1mPR^{1r3kEg;q?po^p(8lkuhCJY{%Nt zloZ*To_sk7pvU#diT&g-hpoE4w1SnPl*{DK{O!6J3|GC-Ns7pm7-`3e5`<`}2NowN z&voezWtXpO)ispJ67r8+p>7pX{ZY8fa+%E99~z)@%m2d3=XuN{b>vgIftmf$;70&H z*fkalG3d1j5#6`#d#!=7p=X{pI2*NE7*a3$Ue&-46ZZ#vNWNnY7SKW?-W=`?akQ=+ z6MSF|K4Rv9JUlMMX%C;H#NKT)8pn%4BVw0f1sq87f`BFaEE`E0DDYvS+%LKaE&N=r zqA5Nz2_5Zb4EhgD9=tYzJ!<0H8?iwbi>T{)j$3*(MP0c^uEKX$flt0pcuM@$Eap|~ zOJ7p0pv2O2h@vSbm36UliRr%$535V;ST9=N`gNtV_S1B}`bj$I4$a9fU6pl6TdO{Y zB(L$t)d~1lq;A5?R(Yjdn_)MpB__(`8j|4xi z#}G#xfJER2_@>{Z0f-%I7uwhT61<*SPfg7K-h}-M6WrC{gGX)-d z@1={QHHksvUD%7T6Ur1LMJ zRqVH=pIM{+rAd>nfbwZ&Nw*I~4_C6~wM-_nkj|&QzzNh(D#6Yy*#-eWzzra_hz+Up z$8@*6kWGq9!M>l#=B&?qnG0$4h;+G}EIn3IIUc_m66P9l>gBa4?{P^(x5QdbY-82I?P)OcL%e1I2O|FY1e58N70viU zr-%=Cn%GnxnZnutSU)|_@toiO&T&1lWI~Y!mwV+kwnuqMyoT>%{D}3H1s`|0H7;o; z1zHg!Y4BbwJl#p=p-@+*wBTZ^(Yme$A&2y$+t}D+t4i50ug(*4whXR^Qh+gcTFkbJMugT8jZ z?Ut%}SQK3W!QH*U{zCu|J$j%VX6!nP6}m|Du@4Aj5`)n3;+K11KBk}#uMjyB>NruKj{vG`@G%O@#3H4eT zscirskaTf=kI;a)vO-k%kiRM52W0{(;R%XYfe z2i<(yC4s77U4f5Pu%TUzImBJRF1D$Sh+$?>vU$?*qtEfJ&(N2&BZ5}ogj2B4>s5+Y zqW8DnGk?95&6Shg3u_CdQgTpASJUaAG(4BN?hyB9Tu17adgTr28OlCLcQfxvUJ|<9 zdCrwf8F#2^ZIw;GEbN`Mjoa9uiuu@|&VB&?;5<@*dv}SKexzo)-;Wd$uj4#2eZ@`O z2k_COZGt_Sf_`I+`e^LW0w3+D=A+@oBp_5VAG)^yl!*1mIKPpv#oE%~lihZLld1x#y-3ADqNo zn3@Ez$IFiMVGng2<|^JpG9uej2MKOQk6`6dZmk&Xad<37_5iUfCd$ME3)PZeY=Hr} zugaR33GQB1FZo?nednx`1s`B@%l}c=p!Q3Ctq=LxvzGPJ#TP5NUM|-uXENpPAeBs3 z)9_#3Yb5_9K*^g-+%gZKZ2A|DUIX1mDfJ)!mrGU;c;C%eq5lzqJY?P*ZW5pJ)x&lD z`ays~W~N?T*)vJN4^XHq4^O~)UDmqv!&c1@@4si9mQ2hSe89gI4-4?|Yxp`T_nBZ~ zf7qQ^wnl9Z{T|zq9}uU(;+@vPyrbPdH0c;PJVJ(b3tupUamB6Jkzy)ey`<~}K z;k{sWJ?3i1O?bqcWJoFYiqO8WO$%n+?jjNk%z3R^3xGmo&37+O#Q2|3R;SgJJRNB6(25I*2Tozs3<^5rPurIGk>MF9tzP+4PPSZ6X`{AFNrI!^9Zj_e?$RB7Cr;rz_V=Lx#@*i+ z=;J1%v0k`$&3pjv=*N|Od~<};M)qN1t~;2#*^0l%Vt)Y9MQ=xLG<_d8FlV|)9*!+$ z#B&-O(Ff4+?k*9Ro|YDU1mbT1AG>(L4949>_hx2Eguou@_t8shFZ|$pOL6j4xlXtk z|BtG9>8uLuvAR7~^U?OT96>i*>^W1i-#n5*Q!W)U>2j`AU*p%`)EYUMDb$m82^}%X z!~-*Cxb9|etQT^bwS{W_O0rXV{`uUa*4x?dUn%98Uz)3|$@aqC>%dnk#_`7qD?hN8 z-%YNduRM)qg)#Fn@iOYfE6>R6*~LyTSE*z>V(i5FSS`hy?UGHMLg6-Wj$0u7h!Y>s zBHDGYxqh(S2>iGk@Zrnu6zyRLkVF;H(2YP7qE7fI$E1;49OP(qFp!N zh^0ZvI8ED+{$5+{SQ>mtsR7QL7K?WkxA!hsk_WNQ4^S?h`sFkx+(NH=51voR&w6`& zV|q8$)uAe|Rc(itVL|E(U^#9trVWoG;6t9iUDt6Mze~`YP-eSTQ+?@Ll#3Z9OQ}A> z_%$zZW+}GJ0(6?}j zqm!QX1i&h>{|C57%PZj(hCrcUt|!@8lZ zz!YMbE|XbZxwR-2+p2RX^E~e#KYEJZfPN#sZdG=K!M}nf`QI`9-inc$-t{)8_ONXC zu|GWJ)mpD*&V39c1D4?!nhs-J+oE?sA14Vvd}eH5#^!Kp86y08(YpP&Y$sFhe##E= zY)UaR7^_0b^bI!}`;r6sKw6(h3SaEwlOBO$IBLo&CXm!IW7p(GP0TqiK85*uSur1& zo@-&+*uE3}5zYD&;-wlf#c33Iv?7LMu_{hogeJkqKMdt}H}U%Zvubnt?wUZ3yoXfH z#Ms45{3qUCgCbj0d4x0HjmkH#lA6=4TBrpEGevTm>v@M0zblGE#}s;4}Wy!!DuV#wsd-q2?Qnrhl=+yOOt%mW(T9C^g!=p#@Y^XdXLg)}Y^M~uaIrY6zrLF1S~-etOnK~zaa z^%%04oM-pm4L>w#8Lh~c;#Y2DStjNSJ`$cl66BW%6}}??I$2V9Rl{izGG#FYw zq_V;B8^FdSlE%m7L?MVSR6|7|9$x9br6_!X_T*loT_dDoF@iq8wv(SM_<*N7mqo@P z;`ks0S&@?JV&yNnXBHL~^0nyo#o(WFlSR=7ID*i-1Rt$H_A&B1NAfTw2lIw+%bFKM zP@0(2ZGfx+O!ox=L)I|f?)9Vwsox*9`rKZ3uH(`4#YfkQ^EP4LU_hd^wiDV^5XI?- ztCO{2KEy+Jm3lGttQmiodR%J;^ri)#9|C=>i+gRT`^}w9mzNNF zi2vPs)c9lGJDa7ipjE6_)=CYRM_bhKm=B0cgQ6GR@ZxyfM|3UL;A35DPid!u43TAG zZU<^hR-m5;4!4U1_D$k31weap(Xs={X&T(K2`yGv?2-} zs9_?C*`0CV9TK{u&Rt|*<)qWOjI+>99037ifuoF&V?5;WE;3Fu6m?*x5?*d_$??$8{{g}~556rNxz95Qiz0$m6{j@39ru*v3Y+ z#cl2~HEiuEyAGkNu;@wcuvX+dPO6Y5;O`+ZVi{i>FK)a_i(HS8BL4z1Gb)LrYtFpwWk7w}QbO^=-R<3<8A5 zzz4k?bq_JBQxo$;A1~%H)SHO);{pyld9;GrIc?zztF@r{x0|d+4cE!EQ&OMDraY8; zZb@;X>`;c^`5eH9LETfLzOXP}fnR)DI-|UDAg*IqTPzmG&QL|kVU?^U3-vras}-tp zi{lZm0nZ_Q*_&q~-v)k~RQGkkoNDZmchdh5>mgf}=ds}snvQG>RO7rYUrBF>t6+Ix zwx@ZVoTY}K(5*@XR7?-JD#ATc@DbM8t3&e;Ged2iI0YgGvi^Fu4n3@|IEY;y zH=)sm4e@m=3O>a2O_icHW3>tJ;oIts&3K>jgLU$0WQdQcQ7kWvUl%JYv0{&65|+mm z$CfXY5$jMxJkTmrfjurq+mLPTYF|@DJOwsztyX)#!Q|++Cif|_z3Tr0#+%H&#%{dn zdiiA66KAoFP;V-p_~sUUSG}rzOuna_4$M%_W!ox#6Chv772}luap(Ja@bvThi40Ew zeDE>w0mp}u8QfDi73%vKp@$#80>ep$FqVw5TeP;ktgd{^_e{S#@{0IwgG8Zg=Dtw3Tl4^>K^?!*!g)PxX)aOIR zWk20G#3@sbIXx1OPAp5A--)HE@Z%cyNU45tWg7TE=%aNptZ$2Tq|5n%zs79&RkjNI zY4jKwup7`kRoeiJDcO`Gt#7ifByf~H_g3C>UuGK{QbDrin@udQsaGL@Z3+d&87Ag* zZbm5AO;bCcvCyTwF2jY}Y`u2x=%YV@J}}Lit9~j2>5nF=tPNa(NjkrWxw>(QDxK~h zd;D4v%Y$8}8!f16TU8y<0r9%IT}_<+I%UBLn!gWUl_#7{Ii`6M(YEVmL^1F|c1b=8 zKKva@J%L!N0!nZKd~Eq@IB{PYVZdQ0plI~KG%WWPUM>Iq$-?(;Ta!zc1=TPZH=u~9 z3kn;^g^;an-GzNM)FHNb413UTFg6wKE<{Dhu-6~K zV#R-SnuCVidDg@=XP-kKTSAyVpzf*?+gLl7ehhmM$CZxw(`Z_iAXE0t5_?=@uG_u% znCp4&J~Wi0vYiMO0OtnDYwGrbITYW=Qw93nf4KDDI>_pE^L|666S6tA{YfF256`p( znG2j8{O_Y;l^)!P`@G$~YIsvONbrf!rh2}2&Gj}h7x01PDVaWr7E%2zS(=%Qk?oya zwCvW06>64p0+?fY*(&Xt1PT5ob=h0GQ(%^ovKg`acXNxG@a->f>7v-T{+mg@{)Cth9_d2@g%{=U zfNtW{@CQPjOd(faSztBHBj>!ka5?oyPZqF=MVMaoy#vK!ect3;Ow0*Tql#FVUVtyl z7(cgya=TIGMzykmx%M0z=|)yj<^x)KvviubIG<4$a~SyWkKhESjp*Y@Ass)uxcW9K zFMn9Etd$jOT&tVS11#){&wj?Xm^#&L(LfO@r8aWeYR7nw<~gr9OD*4|LAf;09@ku# zd5-5Y=6oT|J`N5x7_CW8%XKf*RkoI)AIF66{uX!7Gk3SNkhM>X|v zD;u0-Oq?qG_|^rl(Wriu*D~T`pbu!~G8%7T2VQ}DdLfp~rA);dBFn_wCUqBM4^s14 z4)VZa6&MeHRyPu92_8nl#BKY&W479l#F~~*(Wsu3N4-EI$7^4|N_>~i?a%`Wn=|r} z$&bOo`{-g4rweFlaWQNnCuNOFBIoE6Ss}zyNzdr{FB5E{lQ>2*4gb=7^qx ziRY22)?#s$n(DPFutzG-yjMN%3)lU^g@&7A9BV+Uc)zOG%Py%45F|^u&7O4s;fIcd zgHHy0VE4mST{of0H2kJ%;4?4sqwvBmextrXpfwW#>*&#u3_eufNa#o2kFCbF1GPMC zK;`@m*$|QzeBR82iPMf}F#fJsJbG9P1b^h<5HNg#a#Ie((peq%M_l^lQFoA!fe#*T zZEC{DyhC`4hmsG;d=Qm)v7pzC38<#+&HPz~ZYQk44z5lqBe9miGpYwYx}|1Ilf+~nCQdiR0plfcs%T&@QC3Z){li_m-#=oV z%eVpLD&LgL!!>!TVBo=DLCE+nnV3(=L#n{kPhfHhfjh&dLJqAFb_zK@zA4$-nQG)q zKipK6<8~nFP}^H8QsFXAefVc_*sqqwFRT;nK5b@vuw7i7{GN8|%6V=FU1~dn=f{>M zWh0t<3*#pC-bT4b6WVdpF@AS&B`}E3#OY%M}NleA+{~bHG=$ z)&Foh@t`cW9j89*(CHM@w08Pv>jHEh7n~jfK8SYL+mh6WneotzW%ds8e1`5P5X!9O zrksf^R9_%+IR1hP?r5L+o#fa-RNmW~JOl~s;gU&U#T58p-eUrMD1UV@`Cwwj zlAW(y@1e&&!Tq#&v0_T44fZ%o@pKxORU65BKpkyW$3{F4=*+Of4X=LSPZgD!vsjS(AxWjiA>n==!k9Nf91O9Cc+!&wN8mo61H~I)WyUWG`vP&b$8t{Qo{jH;YKGxJ0 z@1!Ts!+O5!e+hR=jp$E@e7w6$toB8skD#+E9V+?{UkJK`e~k|{g$cK{qP`|?;6Vwq z40^nAK3Ey*;iH$3B?qogo1=z#A z1*sjGbYXA0H}h{enB|c4?C**XE5`ca>`W~Sxp)nE_h>IBkI!7rBs=N=bl!lE`9>mH zDRZig502Q=7T6CSSW(NedvO4)x?DPbP>0q7V@!Drd`uM~ zsvq=KS*^ehUizttzH?)lmcZ0k=UuiUJ0cKqQ&wvjT^I4YAN)qGYC4@eLN^r^|AfXjn z;>E#-Y`|>uCLc-g(Ma=Y7KqWp+_Ah%*x+SXvbf?l%9x>;{gXVQVu62nfN2jN7F!y? zXsiPS)sW-VGY%$foA^Ck#;^yNd$h)}N1M;qd&ut+S&FAs9u5GLKy1H259Yf2kaVF3 zR8_h#*IOuy9qAw9)zurA{Ta#X8xv;+dswJgZXC3+-)Z_TYi{Ll)3ghBGk9`0<=uiM*0B0|j;F#g!seKTRjy*QP)`Q>$D~)LcePBlk16@D4cT6v86LUe)iwb?bFZPS4DHi8z zYXS3U$x5R-rCvPr^bjAsbi+A}rseTpgzmTz_(5dCK&)RT?-E8msCrpKD3NB}1bP7D zd_t}8T28UFB#j6YX{@T|25%7N#u6DU7SY- ze9W2tK>zH`;y$K-+m3jvOWYyj2JXEsjSrw%^)<$}z;4>y!6xPcqQ!r&D_e#P=bwSk zdQ8EwP#8zhK864e7V<7`zR}>*xxe@-$Adzd3F_nP+uHVGLLM4d0W5u3{J)n&oCGb8(*wDN?K0xYcVMz-XO-dtRU4~ z(TzfZi0YuHtC$a_ja)s6F=>L&b^aXQgG|WvF`4NWsp$k*D=O@;m#G{)Zeu>H&_ygq zs{(->0OR4k`GxrB9oJdwb=-pw4(QGfV2_~|sxf!y~}?se7VB@%BHizVzc_OM)yI81-@nFhP7A1Zn3s!2i zn&;+<{ZT;CTdmYT4Lw-wU|AI z%Jx9Ev-O2r1m{qLi~CuF50W$B!^9jHrtf0+_7ZyD<=;c7vg^;+ra0j|iBKXUQ;VB< zEK6Gu0_6`J&uA|oU`qhQM*@7bT8hz+=3V4BzJAtvRxUfKk0@T!dXE)oVwu9uB{1y* zF;48_h|ibM>#h=oLb>bmbZ-x7;{ohOivtDXm(@162-t&hS%owmd+ZBv0UDA3dwAYM zPQy8n?Q$U>L#QfTg1ig4EG0Wh%sS?FIT3cCRF@|C1gm#|hq5s?AvGeq1jpj?&JH2VJhYbO?Vt=v zpb|#)kEX6w!)tpjPH#w8Qy+VH-Y*=-dB@!cxvA=BDy`f11dO=^X}bk%8l0YK@KJQ| z-Br0LMpMarYEa!$xCr$wZRilPMQeOPf)8_Co@XpXtPE`X&SU6%;>)9jf*yO6?vR5V z>MElTI7Pb9XUm{S6Y~Sn4gB+h*bNUpco$u~5)o*$YL~!xJpdnLbDU6_K)lH`hu@!A z+WJ%4(!qX7$EXi+p2F$+*UKc)I{aIO_sIZR z8RL?yu+2;ULWV3t*wPg)`pRx^Nn^3LvUmfWA^UPjAR<7?_8!4ArKX(Ioe^v`?lrRQ z`Ymi9Ip^udF21^CRs7La%Bbq?QDFFyggE}1^Y57jAI=?m7f+uJw)~ww4*F3O{8|Ea zcKywdZ~!017IS_>3Afm<-LQP{h~BgcM~;CH!Yc@UNXUV54|Iw9yt%|C=7~P4?(5<} zy@0!LfNi(?QeaA&;$(dR71II6=5~LQ`Vip5y+L*Pt&gwo06xe#^)ciGKa?;BXC3u4 z&i7D;VNBD{N^_5umFTsp?8jW5sKy>-H88FxgwF_Q$IX=RZ2Ce)=nz8ZKF3rVz>i*MpRil{#N{;^9valm~LUGzzG=aR1h)GHjm zNr?5OD$XOf2VnA+Ray@?>;xCb>QTH)qOnWG|J1RRZqrp|dOZd@bee@QDo1N(o>-PK zP&KGZ1Ajw&?v$MUhZG8-bi)T8ViCiQi}1?+ib+S3@8)(oqk9%KQaC>N2sSuX+9b{8 zfQ)-F4d7!_FA^2l5)J1yKk)G=iAXq(NPO_f@q&Rl;D)%Bc~U&(xBZg&s|=g8i-|eT zWpQHpf7mG^l;ba;dKE`b&Ek`kbwz=XX*9k329r#@Ur26;4r5bJQ5d&c8hmVP7MJcR z3}3^qeg3sTAGzF^xMi^tH&a$8p`d?Lv)iN~r=w*Umu<&dpl z#c8*qyvMbd-xSzmR_1@iciAfVmb!1ksIoVK>u_In*@cR?FIf-)JPr=z9s~y^)=bOA zs>1O<3~zO&@AIN_SH0wdf+#NCYyo@X{faEB){}3W%cQNropZw;;LS9dbm@+3L_#1W%bNishX!}ucxe3+P1sKSZ`%u`}lW4{MmE8ygn%A*M<<>V8ATxq(MFXUae zD48|c`P8B>zdmCJ+6*Y_1B7d6W$Ej(h{?BU!L43Q#{6Bg9;OZvIAD~nTS19!u>f)p zvG(NlaV_ZS6$(zp<=omLR4G8h9GE|L*uU(q#|UrDq&)<9S%z#2fDU@#KJt(jdgQCn z-(_E{PZ~6eQ?M9!{&VSRTKEP2-zCGlpXu2)h>mmXI24GjnGatn;HC;u@Nrq16dLd` zpOE4j3$iYf%M9B@;(ot>ls*?e_z-cGZRU&UXME=xk-+jQWw!T!<{F!rC-~@H!*t>H z?NSo_)yY*aA{Y=q*qXgkag}%RD8Dr}*{2rUV!Q8ykIQ2o>mX$NU+XKqh!tbz<3MN> zvso+1RcMd(9>6&PEAZvt$J#8&6G^>}pvZAkUN7EUC$a;}s#JOGLN7TWl}OZ>MXO9D z{1C8$y2{{V#&GUZK!NO$FSPzlme{(lzU(pJJs3M!B|c#V`w;%{b9hyWG=6MJgxP-1 zD$KP|J$5>1A6cmwCgUX6#jbG&-2VZ5tddqz~_X5Q$sgYn)5W4vlvMJUgws%f$SA5PJLk9kHt zAIk7#8QYx(bG)%ru<$nDs-rGRyCeV~%rrI3m07XJBH%;7kJ%?8 z-n7M324_4@X3OQHe6P|z)|wG-3dWRW0L50?jF}%2Rd01+l3yMm)pZ<`R0H;D8A`w%Am;o9?Q6 zRgC)Yl7+WDOyxIr3FXd313u;%1+O13X1jxP?f4DvgAYckg_qFn1@xFrH{^fJHq|aB z=7>Jv-{0U}>=io=p!8_fQ;SqvO;|cQ1boPy&fR}?$QhXmKibpoiq^O>76GSl@dOKB z+4Z7vIUDFq7sY>%^L9Fcieh7krdGN-PnCZi)yIw?g-q^ol=ub)O@^d5hGYv2KK%Z& z+Vmq{nB+Iwf!Y?%ZZdakf`g6J*b+&7__ei=cKOhA{^&UGcrSbI4aT;K@AW`e=|*b^ zMAZuPBCMMG=xj#?ddju&v3k4M@=)CxJ1g(;PteopzxjEp z#tLuO{iI97>ZCHCy@;x|F4AZCyJi?o%r`EkF=0LHanOHor`)a55MNZ&cS18|5`ND^HAs`g~>r2;Im2><(Lx6$*fXDy{GT|$Ys@Fw9Syj!)9 zRfw+wmBu?+l%s*Q7?&7i3miQzOCYDRE5eB>l@re(% z?|tlgp40H0RNi$wFmoYPmbq*Zg%?vrx#1-8SB%v3Y{$bMUKf+XKJs>@WTti?Sq^Si zMz;P5eQV*ngR5LX-(5+#nXb0;jTh6HhR6d_s<>|-rWTIZy6C~Y&KS?21I)J)#j7@@ z3Vz^@X$)y%&XL2lQ3=uk=;B8}yuIQD<(TQ-A(9W}GbA>vA@`2K=(fj<#M!sN-pL6p^qla*R4b z!~NunUiW=0A`YOdyQ?Aim~ijtlk0>s%584*SsgD0q`2v7+T)rkba5Q#WhayHnDeT8 zgNdDIPx*_%Xyf#IifS(|{KmARI^*%Thy(Ev_p4E~7b*cO?!7$;KJo>$hSRVsc zY6lWI^0 zzOJAk>ta5O&1qL!dd~tM{ip^+n_k5wr~a~-|7w^9sCTe{@e`dmlK4}8Qcr$y&BivY zDKuG}SjY=$UKSfjI_P4n%4x@N$56FxnZB=3SNzu=A01yI%tvDU2mwb^tu+;&cprO? z^WdBNYgy0r+KPsQ-F>(JOG>wN@G7f7?od6VF`kY$YZ=M}GC8&i)SiTMcEg~+-~eumO`lmE%e zw3fHjQ3n6qXopSAdx=^Bm(%xQL+N1IC<+z4c=Iui@p!ISAQO3dTq2P^ra_AxUw?T}WypvFW@QAYtvrUpxh()6pI8Qbn3(rYSuA1fz_d$%Wz$7`4t<35Gtl6He;E zf+Vqr%RYV?pvOLyRv+HWj_0MT0)jl`N`EokgPSseJv`ZfxNwE64~hnRob7m=j3fW{ z1dZ9BrZd&(BRC|;DZslZ=i>cJW!ta2;;pWn0!H_9+6P2&l`{w9!n)aYF0I&L1}BcK zKsuZ(dSE;FxaEnlTovGBi|`&Yg-a&p7;w;D`DT~HGV+pT{ncHNtBJMde7Yy6_bhiJ zIAp6#GTD=og7%%vih{+@ck_;e51CWIFMLI>^RsIYOo1Mqw7ful{OU8vDpX>7`O2pDB3H^da! zb$h6b`(8c40`S4t4E~%GiFFB&2oL-6w2tJD&m)hltp@$XS-X_lB&40U>a?xE2L&Y; z><266YMYoJsFrCK>=l7NwbW_0I3Q1@eP&~SJawWN{ysQ%=rkhXhdGh;C&7n3A^TXD z;DbK-m0B?lJ<3!h^bl8sTq&Y4p(!d>D$tjs(8V!7Ls%vPtts90``GgMqu^^`rkHbM ziUSJ?sSx;Grs`ZIw;@0CTrdCBe^&zus{X0ifEaGPEnnRl-aPmA;)*#ao!Pq@yzMZd z$K&aBVWthi+oJ$`KI}fLrA+Ge)SkhIB&r1%=45x{?f)A?*Z7)l{-#6rn@ut8W>cpKv-^ZK$5IK{W zyE~KINb6A12OO#{$I*wPK3Gn^sxRk>x<0NawF{f~;ddCv5WougRH54#;_EAIeCT7D{~ANS(E ze!%v~8p^ad-gjJ28SRoS%pNu1V-6e^DwM)?pdZ)-w(m%ML>iKFzd?dHM)b><?b~#N^u^RAVX!Em^bwSUSdpE&DDD_+dD(|s`~+77Vv{~Pyv$}07ChUDWkA4S;zFI zib0CmwqqviSLu+j4WNmC|D}~ZS(R!zzGxH%6zYiJ9W8}?$P%)iumAQf;<<2PNUAtd zE>K8S0ehh5aM(pkoJDm_oVajX%3l(2AD;+aS4rH4M<<7j(h&ZMrRkch00;3qyS(Yp z(legdfKImJzZ*9M@*p}>%%pI|>aNnRxpU4m;a2R*-A3MfHfT7sfGc9VKP^VwhGLh# zyie_boZQ$DgP*>LO0w#zTpsxrV`*e)`ZuF}CPvW)=FTelCPFEsTL z1t0cd;KOH4c+5Nzo`F-g3HM3)%LzUT*tWsG;F*aM8iH1>cNwr?d< z&dUmW$hf7KrzT&M(!%aF?}MB<@t)z+1ggJ-hlG;jn0rj=cpEt#T&MWEC`)mRV5gYX z8y3eG%ruxobO;W|QVme+PQ7_Fw=!Zi3;<+J*A+tYpz?2DpR=TgQXQ`8)Ll`r3l zW)(kTjnH#z(Lz?`{ZfMv=eO|(7NMlY`e+|7OPS0;a%Bu^S+A`5&tv@xhn?d16zoCB zgw`WsOzBQZ_;XT=e#HdDctpCVQ-Lv{%*AuuMxy>J&u=fMQZ8gz6GtPg=#IZ~$9Y_K zOf|R7nVgGDsQ3+N{T6RP#(n>=L$fYEP2U2^X&_J(z_kBr0;R-{o1A1a0({h<_FJ5t zEmP@o%26zDhN;)~(SRfmwC8>STr|bKC3{%n3zi!$;ha|tkTh{$qMpY1*1KZ*74~m| zk3)y>Bq}({6KpM`*#B9YCK97Qj^uKx@-wxqEw#Qu?I`8^8nk)AP6B;txLoBjURnDF z|4Bh7SJbAwCf;HGmA_bHyfkQf6Dh?Q^-22kfb7t5v5J5Gyk2w`!s3y)Q2<|!yM$M@Hru?;_loM{|FR@FGad*VZa@C>rb06NzB zn?LX;f4kkE0xiTgxHlVpjApKV(m*kkeh_hsv^XE){6(pZ__D0^l`6*PRG-=v1x6Bu zidg^87tj>{rNSpf7MTqDv^?=#7eB?{(O{(V3#@8r`E=SNJkqN3P*ju3cN-2-T`gl= zR4@*G8!yWwi|fAXZa~KtS2uKV8@a?&0+RT&$A%)NI3^bmbh3T;@h6jcbGw}3=~%cx zAuYmf?G&a+Mw{OmdPwx4{d+)Sw7ctziwJ(_^DL1&8eaI3E6*ZLLa|dc7yMM?`81A5 z&h2T`^6ZY|kwqbbJvM4-nQEaJXG#I{fiD^8VdDO*Sg0;`Q1Yau`niiQ)AWZ(iWcOK zMIt9CK0eRwJ_pmh!#xvc`~+6XntxkxDQpF!)4=HS>|eP=YJ_>|J!Dx5c?d94;^c`h z_RGk6NqleY;mtA7h={94_D(ibZW7o*h%i+g*Dt!Z>+X-C-)B?Zan z$rQ*D9XjeVZ+}RkoJARniTKcQKJ==|2J=4n0MN&QPP)LW^>TncjE6-2#1ZZ594y5uFx$KLKIh8x|O}!`nc+RQj!ED`iZv=u5D*M1RkpCV~-87Ut ziyM{n=K*X>BeiLE_=#=b5q8-AV{Dt(AakQ@x(QCAvNk^b)g>za!X}^(e5+@`$0;r@ zxj&G|v9E6*$FC)}G{l=(xUx#F@Ql){6LGR>im^&?uboRZVdm*#^8h_m{qH7%FxeAY0Kr z;+EvYR?ze1j-)^e-w({{*<%$*EGZh*eJd#X=dS1EJ?U)<@B+$hACgIze7Yees5jgQ_E_co!Ri}z zR4f{e>DgvI)*OHygdfvdEW{rHK#3*#b~(>jKM{8`$8YtL+G0#fK8(TsX@shG{aqCY zCzaN*pojRqw$8b=f(|_a0AajMYWRZX^vSXu#+n>URyP;k#QloG+C^lAGq6yy5VVkj zDZCrFNlfdc2)iC-Q^CjKi5Kl}Lny!> zE!~NOkWET_=z$}pcCa7?W`~b79LJN@wYS7|XZw=)`0$BF{!jV9*OY0=DR{V~;D!C| zv7ecnZ2!8GczkD(;ET&iI;EFBD7sD*ND*f}dM?FXI6U zOUH|Aix(|KHW9XIab&8_;J~%K-xS8J~-_xs2`P0yC6>|cB zya%m;ne)aNd0BiVAy0?7rxfJ@VvkRXQoAXCoZPQVzN2tK{$imju5h5~m{nREY1!BB z+gzJgHpwPsv8^Xqykb&e3P9r#T5GDNJT;~~PG9!CM&5hKdsF+4$^V1&gXim@W5oIQ ze9FhfSqk9jtqy2C=GzMmYlSywZ0<=O(yi{v$wRYf4F|IkH!e!>VSK4hcy;Mr z>bmLxGSj8;uz~DPsdU+rb%nb`@nY}%85KRu*D>EDN@j-#=EgR0KhZXKP@z-~$v^SW ze*;Wj$Sfar2go07u!B2LANF+OL>!mi<;XVLg0NHGV0siH9{IJu(%0 zs17c%j+K3tsfTADa?V(DT7S~u>7;9=>v)fN9+OYME6%U7qsyBgEAGR4Y^b&&f-ob(|te3%Q|TphabFk49y1*TQ-Gr4(vPvW4bEp-M}^dQz(Ek zJ=jlvKnrPA1{gq(2=8&E@r*kEsNR6O8ReEFmN9v*uvE;$!`yEK50t$%42(2!pQ2bL z9kB!I#Y8z+CMfTdTpirT`iCm3p+I@d1n$v)~mIDb!E=$Sj2kyrJJjgZ-KLNi^euv4v_p(d)oiX`r#}5kF<3QSdNGh-fR;Oobl}~(6 z_JDgF+)t`?xf{QfO)^-o-78N|Hsh7FN4-lS3oG;K?EIg@d;EtaohbhBarKR2nFd8c zwyHMR_1FJeG~vRh6c51?vpGd**bj^j+q!a>xDDr==gPm;B6O25fieX2a2wr}=j%NH zbwD#)@sG=P+YhB&{0;D4F8<8)Fg8eQaJZl=*L=) zMEDRB;|y`~OH7$49OjRG7hiZ!ysnG&3+E)+K;O4eL=SPX5-7*5HG+9f?*&zPP+VCO zu*5=zwdYa&jRm=#Td#X@NHLak@y|a>IvN`Ybx`Gs*O)pqBwUT$hP&@MZcY4PS)Gbx zN85a^Q>q3^QyK|i zp6(hv=Hnk1>#no`!KK*xWx~Y#qlewMQ8A|{VGnl3VpUA(?^?-2c#BXTiSH?VAHK`t z@2tz_@z|-HjijGv_pCld8vGWw&u#<>D*lFR-75$NcK zwXyQV+>($($pnt0_y|jGCuGiI%WAdS;)!1?JDBiI-l)PKNtqEiLF^&^pM&&S06p+s zF<889NBzZu0n{!Z{Da@YUpoixg}78iKiA1{Nn$M;$%l#iH2-1hb@4xxlO=rhyJX!$ zS&W<5eep*Nr8~5a<4|gG4|x}{xrSX{`kZV-*B9)Z2{+A)$-%1V3YUwIL6iG_{Bp`Q zV^f#Gg%y*r#RxPXz=aSgXy>!+>w}XJ_3{n(s=^CqTC`d64Q9jN zV83!P!7OJ6;)G%mhBV=Oiis=Sk6@4E8O24Q2k;(>x!U#nXYuv-#h-iWEy*mi0($zg zbO^%d4d-FvzJrhYFK9)%e#3rq{`Z#khOX~NC~@s@@X_?#JKrjYJ|eUM<|^|^&w%X1 zO4PF#f>&Xs-Ew!~N7+vpm%{O+N|vsyK+UaH$YtdtL5W&?U|Z$l*VmW%y7Sq4Xi18? z5+(fFvnWw50YrgPnK5Ejkw`(EzCB(8If*V}e%kRC>0#HGHp}N}2Xp-XE34w6Rb(0I@kzytNf&sEVPK}zzANkz)tdHgpZCy7mu<@3C&evXKc}1{ ze_uzA?(<~KO--DENPGv{HOO*|rKL)@mxDCqE~W+XoiZNUv4d56jQVf`n+bk5=%X)t zlN>O%!7j_wJh^%Xz(+UTd0S#LWz6x<=;15+ZSZ$GzDx`LEuu;X?qb z-q2(kc_b1~VW0(DeejM?L+%J!t9*o8VYvboNQHd7Be zYTX6)z|oY;)-DN%4?e zUKKE}+xED7y1Z#3=wr4g-yLo!S@puG_WdP1|LgmDF&3piX|T%vC6ntCrTF(=(6;JJ z+HCzrO92lHt*m6-;Os&qtEu|+{rMft-$3ZSOWrS0z0!RIhus@Op{f485uYk1n~;+d zMyD$a`#6%HanoK+gBl7}_B4V$&Z#<={e4~QEZwtlsgTD6uXioran_Uxk=bqTb4dC1 zV*QO8CUkX&Y%5+pgbMv5mqkqX|AQ&gY)b9}jAQ!JEfW(~YvClyvX&CoPNV zUvmxkFmYDy22_MzB#WT;z@J!Yy!-^E4=qg~S-EP>{>ZOmem#ZN0M(k83KT1gIqn z*u#;~!;v2}_2Kg#;(RMc8x!T_@XSuh+!tp7dcb@ve4j#6Qp}wls?M|;fb0fzS^sE; z5Uo*Uc1bVXX0s`_!5XQ_`tJVj!kWOJn0f?nXS$Gd8Im$eiHY&6CB^WWxQBHX3<@8p zx^l5x_VHuWcUQTK7CkY44-ya_DwQpB=jbQ$soj^*dnnB{)AAcLjwa4V^u$(L&q86w z-x=nE+j-poG*_*HxZzJh5xG6})*z&H1dPG&qzU0tlb~*(nmBl6=6~c4ie-TS%DexY z=J?X>CZ=~&?Mn~Y+y>mget?pzi{(l3~Et>ey;6pA_tE+Sidxf%i53aIo{qIrL+!kkK z!+JVBl$~pLRdtK6&{jnaEt#Ebw~yP0%umooq#k6rOt4e$$U{XF%G;)K&Y}7XJ?U!9t1bF|oVtChCm`3*x)GBxaw7`J}P$A!&jmfDi0DctTeS z;0kMW6Jr3Pmsyi@dht@7A0EDS%(K`-bf8f^rS9aJTnA z6JHe8QVm%)&}`}l_Lcd3E$ZfRXud@gXk&;z zp7is_YoEJ-J(e;1t(6wQdx#qe^oq;z3uY|tJrd>oNUw2`x@JoL|Ly&ae-p>mJ`V5d zWhFT?yBo2I#z-QOVJ)&!sEZ<7qH=d*g)~;a{l+8>F-?Kk2?=f_Zo?fyLNHMJl0s5Q z8%opr?(g&bp64%p=FH5#NwP6u!b|2#@VjMcXJ_V`bFOop1OI%gzr2>D;-oD zzRgVO)#P%x(8F8YgEHJJs?tQRW*E)eiA3ogIPA>gJxqB~R z;#N(=_k8eALy&a2uzR=jo#P8X{_VQ1F7htO$(RU}lps{Ee|$wwipK!?3L9{-tITtz zIPWLQaI|^g_NAr;arbpe+}RXL&Av|b_<3UEd!>cp!=*XOJrHv4$kBM<#U;i3cH))I z%RJo-@yz>)d&HVT=~0kd;8C36Ke~Vu$_yB+*FnLT;UP6SA`*{5EHL4|4sU-369i#& zykwvcPtNSdJw+*pt(wQ~k$qQZ->9P<0SUUua}U0U7tP-EV!RUW?t1l;j;Li}3N2d= zf1mZismA!$z^(jBRn)g3HqvUR33(x9(p6x9^`XK@p~gVMzZ7l5ErsX?A%Ty_R?xpT zJ?uYbP|Iu>yB){T4tqZLpzH&hy8PK#H+1sZ`JCSHT1;bb<^6?}oD`3KR-Qa^ny^Y& z-lciPi}n-?=Ky^ga!;al~LX+5$oJdoalPVz;cd#sDN#~N^tJsa!*^6uPQdlC@YtV6oD zD2GzwF+wgy@6^w63M@~dYs&)0Nu@@@|jkp zqzXA-^gFpPpG}_=0h}%}&*oI_M5tK3jxv&nP?I=VGuXT04FASS2q7iB0#v%{&?XK~ z5*)-m8bLLqe{hW)U&&^hhu{)-U8Jz#RNXKb!_Gs?m<2wnhpV3JbB_y5^>Nd6A?{IB z%9p^vWEZGsQ)vGlIU^qRes#5|v*CliN}t3a4dx*aR!52Z(|BAV_V~L875o-L1<^%_ z)nyJRUBGIGe@~xNPJ9Mhb5v24H$Elc_#(sf_X|jI*lk151remER@eBMMCa6_aev%{ zd5m$JeK3Jx1cb@wFmz?IUS&TzU7};>@%GsWJ!8osk$9Y7LltR>l8+ZP#0)fRdsX#Y z0|In;v%8h|4HSNoA;-?0iGkF#GAlLQ*;m@}*7Ra7!Rtt)E2{dE8#RF}=5{IS9*fT4 zTv@gA!_UI*v~LE<6Nq0FQ$OV4cxYt~DY>(AJ%i|CQD8mbmi+FuBvzV_$ad<2_~kF$ z-GhkeuH!)1quxb>Anq}(8?JlKHNSI>y@Gpu?Rg)9eQ6Zc0W%dKadsf#d)3%u*Ww9X_RqU$|D_hIi53w%t028j2v z1p;Cit2&v5xW~*Tc3d(3KfhO%-?K4aLSKJ5BWa|>V>U&a{I3R>^B&o{ z)e+V)dKiE|`8s3i885jrb?NYEbJf<&P(+lzv$E-Bb|$RR*=o98lK0TsqblX9IoeN) z9b_W&9~#hG;H0j6HgT4Sj`2uomdCYx;D5uS;C)zxd8mL0OjCvjG z)7;&IZ!w^ZLf!4^0-^yk!9AjZk0tgG+QwCoUPB)o$>fzI)5I_ujS@_d6b2hYSsZcC zODda2X@X;?4!x&guxsJxlC3h@ccGLKsVUqPE2}Iw$NtB&Z-G}2h&)IGnORlI(NzJK zgsP=TuNH~N5}ltZyXLsJ2Xwl%4AQd_|K5sx6zFMt{oW_fcE#L!JFhB9`th{~Njm#m z>6z!EUz`v@Q7h2{kp#qAYM7o7b4nJX0Esh7=a0X(vx(tT>5(_J>3E4fG~{GTpxGvpuvf0wWa|A!s@Ze98euV~`vs>CG%hI=kx8$$BoidtK`UUkj$ zmgf7)mJoX3m(1{1u1}AI|EozqTZShmDZ#i{arH{&8x+U`#&mQkjP|P?ip_@!zL+Tl z$1JyNM^33irfRsY+)gMn8gg9&?D16PjGmT)kNX`W%@CP!jC?5%pm&ZUht66vsl&dw+u zz7uzny;dYY%C=*>>5!q>PY~|0Sjx$!OP0W^6$h?CzJ(Ysa_ow}qiiGK>Gyi10A~Cm zQ;!-mY+(h0y{bV+q7YS~v8BijxCii!7hZ4$&RsGLyw>#+Cmdw{mc7I|1S~|ZPLE=z zg8LfU0AYPCq^z2n-;FVv!pp<*jDT`%6*z;4M*#^E~RjDCnA;vmE4~u^Av)r1F zipB}eGK zkT6*@={|R(oyEvVwq3Fo#IW>f2z@lR7dEbw@!UhlzNP89zPbvBjpNv4oN)lwAD2@9 zq#qxlH&fbH+UsRGDiV)1W_I(Vv_&^ub10%)A7ux0RRb5$?QND1fc-p)y2aLLa~)|I z;K-l7cAkB*Cr(?+$+T8sX$)@k1$qqQon-IeE3EIVV*i|;Pf}KVgHY9cHI{&4LgQm~m=Ig%bWYh_c zEfM-XbS0)|jKSEPOVsxkVx2VyCa}i*ly&1{`pL5kE7RZ8uT?cUwIv?!d86d`O|B{G znR)in&5RdMCwB*36zjcOKo3Md2HTl??*4SDbJBmp3=lW~0Du5VL_t)RFODqV<%;fp zACMC(P8_(*N=-du&dq78%!FX^AA9@?JN)O%bM&~EbKKtW86j)3c5bo7!ka6032`dk z6e1W8rRBq@2RpQMyIo-_RtPgAh}pW*S1)2I_gAk>bhrAv=NclpA1L7IQ*!;RbA3tBLPd+i==1h+tj8cj6us_VA1ajKv&KGDf9Jh_~<2-wf&#S`~V=f{`!$ z>a#qWzM>yLuIn2@E-a`=bS$?~w=~kth20#XtvVwgSc8k!gt&+9Y2HVQ^710qe}Jzc z>E9#qc!z*h)jGxT({!FV?YI{K=-DMu8fCpW5D`zj4Pjr&SDnXw>KLjgATj=|o z#v(ik#6>s^ zKgsZ;1jrH zoh4A5eQYaGsrT7JwGChN-1BmOlX$$jM-cij>=gfC>b#m{Q(!KuZPGyVud9L z>7widVh%EIwES~UdG@mRy(u-KpxWo?m$4x4Q#TU}kEyRPwJ)y2{N zJKRU$q6m9X>Txa%dl;?(w8V3c*Kw~|tzG&(#69xwAUE?^%01L%vHX-yH2U_V3cZBDuyFgAvW$GRS$35899Wd#tK7DCHl63!v)cQWhqY75{V=G8Xo z5`HY+qkMGnFR$z95>(eJP4kiET=HiPPs=`eT(bP?1^;4WzC^4SKPo%Kh!M!G(`V!7 ze>YePg@Bclk7e%B&R9)f2Uj@dE0d`~KKV*feoq(kgDn=(I%ND(?r##0GbUI=R!6Xp zUP~k;6xBpx&#Z6eCh%i$kI=WkPxTZ&%&0s*%R?L|?R+9}HStmEQh(iD4?ENQo?i93 zXsy*)IDCYk_3UffVYAmxFzPZP6e8@=QrJvY3}y!zr9aVDG(+t%=>DIW7QA3zMC5!{~=d69omJv9rhxbfj zQ%BQyw*n#eK#`mac(#i@u;ReC-%C*Dq0%$6(2MnyAwV$lf zRG>Xp8izcO1x3x?T)AaN@*>lsn(1Da%y>&EcD`ZsqR(@2%gfV!UJix!(;1x5ne^Cv zkv*-6(hQ$XvtP>HP2w>I*ce)xrd~%ZNsQb-e8=wm?tUwaV(VT^dirofA2H?;xUIqm zH3~Yxy^5=w#j0sKbY~^wewTOgj7(-Tb2U-kqr8zgkk)b~r})mN9cHtzi`AluFbed) zCL`p>?+WVcz5Ez94vrw0#M3FkV|0TD0nurpaCh1!*04=z$+YWUs8%Wch(15o2?QJ7 zZc$#lm$42mHa%__E~zGzrcQ9?iblx`i>upTpyJz)%OcLJi*jF9s+G)BnQvhX&uaCm zO!I?%pD2v*7o{WZw1aD_jCw@rhoNt*M%YKVC6VzbfkKRX)W`XIglbcS(eAGf{eI7$ zx0SCvtT~W#f%s>-^JAZT;OdkQ{L!hVK35gx$x$G&C{|0`V7B#miZzdemeRevl5+^b z!>O}{dq}!ObZ@Z{1Yc7fdKjH~a1VSv5w71qjSLTQ@PR$bz; zo2FVj{nhwYdRWK_81g1oiM40qw~xOVRki+gkjB+%*mdw4hU*%UAEsIz=X#J4f}~6E;{^f) zqv4x$uq#?;62QiA%&5M3m)}jh>JY;-bl36pp$gk$bl1AH`vS|iF!tevQIDH0){`Gq z=oQfJyh@Pw6$^1!AE#zhR{8hMit83z_ER{)CWLug=Mo=YcJDIgf%Jp)1)n+1$)m1s ztj9widKi7Hhn#ij&SbZKJ$6jS;Pg@FlYyC;#!zET4$*W=xpIYWTsJNl)kVbXT$Hze z#Ct--+!D!(`&lZRe{zCdyTpQF9WbIw4?3Rif$Ue7+B!$pSlhSYnBr$$?n9hUCIic4 zCi7SZTlHm#rm(VIRDtPJVRwP{vQ5uXP22i7Beyk)CyIom5M}1D#kVxXdPtO%5?UCW zd+@i(hZXu@Wg;XrDc}KwE*U<}O<`6xi#Z>GpBxP6XMMxHy8<%iR5y-U#ezUYEj zZFX7Vh0z1@G>%aZtgjolbmJQbaKXF4!XKwX@^Nn6P4@IPqIF)HO3uO3P6)`eyWnv>2$qmKFcTdYlK zY?y;vGIW2a*Sr2#qb_(jY`acsW8xmQK9JiFTNc|vOUO(UexbeZ ziRx+yGP7OaF9>Y_$wJtouX=>;{cTsr!^O2&_XQvK%svP=d6^7itji$u@abuvR8+-& z^&+C9svCaapMmyorvY7T5YpkV_9yt@U$+j)gg$~-L9L* zzP{O@7XxZOpSu1sES`3~=uOY+Yh5xq2@whKqC;r+o1F<&O|tTD(dslB^59VqjDs$Q zglv|a952xp!IIIq2d=wSx@-P_o2tUOhuia5<@GKlpZXDVE^01WvP)~#H}kuc#DV|& zM2-8M{Y9<19C!|5oivd9DrIi@wnv$Paco2t#;M0(o8?M_SO%8)u`}|q98cvKc=lOE zIbY??dm3*7m(SbEu6Gi0Gn05?aD^Suz7x0ntI+QQP`$ICpv@y6h&)7(b^70cAaZw1 zV!j8%TdkeXU#bUdHd@g>eJLnrfwk5S7CAd_m$MbugVt@)a5ntSZnujD-N6v`(DmW! zT8MfykjM&kyCjT!aILz}V0bMo8Zb&yh#Y@NygdimihJM{!_Zw%A7WkndAXc=IJ=$Q zy8~NwW@>uONPShr#^Tret9W314}7b90d|{5x+jDG%3CRO_UGwEaUoLWgsMC(?PYjJ z09FZcbl%Uhu#xpj2b_Q3(#}|P_x)7&Eu#eGxaCt1-H5gz3&;nFTHv7Id-ZV|B~ELW zM(jN>fqYLf`%4S@`J}M-*@n=XDnFjpoSoF5R?9U11}x-%oz|`=XKc&4PBpMahikk{ zkgI_`VYxVuxoQW_B@sTkj74){w0)TzU4IIMMLk%d^jaTBsK-2OqOiRB7CfN}zdd%( z&~=w_D?$8!LF!+CyizWj#LYhCdOvUmXz=r|F`fVQoZgs#lFk z9cjNw@w2g|A>$hZlV^X-f@?LAOBvknU3Wjx4E-;qCr1{kW*o4N_0Je}HeoMar-VLT zbqN9Lu^80Ag~cwI_=&N5I)U-1$0VK|dO&@i^|4(9_11|Db0IJ)V0Yx4Rh71vkR2i= zo~Q+r-n#$Md8$JsR0gDrvx>46`@jz?^wEuc5EFYuo`;|gHC}^;Ap#ODR9Q)BZlY0^fCzqI>*{{bmVKB2z^ILi~^K@yMTnvJvBjb5r^?p3|6}wB;>HoZq zt**}|p=OOgjmF>eCnv1aDOGt>-zPnbC7vwm0Z2iaMxF8VI^*}q_@&a^GVxM~wLvPd zK*htg{D_ec5le>mHBzg^eyZW8Q!qO^M4jP--{ehR$XNQr^`gvlW5_|h297_dUJnkM zU8sg3gK_o?AXwRsaVeSFLhM1;nss*`4;_5*68#3&k8`&1VHom&H(>5D`|kI@RFY&# z_q<7jlMvxbe1=f((cNfo=i3eh+`-n<&nr;Q_Co6R(=d%Vp|d(|X9<~a95Dn%AiH~S zQ7-ZdHd0X2k$B$;HHm$FWt4h|BLJMP$H&6N9Pn*CVu6n+F^`8m$gxVZh%cE&iK$U$ zG~)b1pF~=oKBx4BCcmGd86j&Ok`Y`Jha?dSm|$Rk<;@ z-+>jV4<;PU_}qw>E#Z6jBw&|k0kr2+5!ouE9~-(s`Nyh(jVsD!9ga|hc;9|yDQ~+K z@QO^z?M&iHixk6hbQtkI+q&l`j!nfj8k=&Dac)Q50zb{|bh{#=fv1E!^>QCFu+cnx5GabUib5p85{Z4VBny*# z6bglVGBhnLK#+CSh_w+e1ac1^_V96vb&@;hopOzNdZ?r$dzO&ziW~IkeF(-mZz8Z3 zdo-9RC;!c(MtyNYoP}i^r^`>lQBCZiC*J%;U#Nq1zDYeZcSliX-gFz4f5MMsD>rcv zjvtFG%hlL1=D3;6=D&X*%1gdq30&jW zz;94zl}a({LGCTz!Ud!R2f-_SjkR=H*Nu7B!xjP`gqZmv6AevH{_(|=wqiMsr6`Br zd0Xyg5>FZuMMWtS=4XLcJz-M;4$K|0%^s|Uo$PSS`*Jc%0@gZ~`9Ds_YenrUq!_BehC zUOFZtL0PD~GosYP_fx+F1-aue`7yRW02zq~-Er7g% zt-%WD*NE#@y*gjh-nWz&l{XydF8B0$14}&3P+OG8zlr=tD2NN!>iC9|xj*{wz@d*w z^f>PQIFwk8nHY@W9F(-s=}R{}c&sV16mk#$IX1>S3lbt8d@3q-MM1(BT58mJQI1bF z>Rd(YTbYV=r@%!lg~B~Gk%QmCy!?TTn7CqiK||cbJLmqJlaJ$s*=DG1jGsSVZ=f`D zQn>ROkA_VAXjLW5%0p4hKXWHZ#F-wNjKC`+UiK-OJu~G_+Z7TIyf(Q;N6h%5oy}V( zN}7JWZJ$)F%OAKS#+Nz{o4EK*o>5shpE*nd(oWDP2_`pjIWQe*Z6>75EzK+!?VOt^VPG58aJ$kFUK8 zj^ig@u%5D&<{z6M6X<74kamUcJozHgpZ$@G8tvaVi>|LRk{iBhhf-AaDR@t4AVK`Uet%E zhp$2%4gH}@E$ClVGMp@2@E4T~MtvMm>sKC{=yT?psne4Tq$Hv&9=Ywr<2mfRIAyk= z8kqYAk}j9-5d5{)`!-ozMS7)Ut8ctior(`7UI`bf`FZZu64v#IWZ2!Q2WzE0yD-T* zMBsQu)H=7GYp2X2x31O6!nIxb->b?I&=AjkFLN#uPcS+KwnQ}aaxR!G?t$L+n=mq! z!??};zF7#~JlKIj-_@rZ*jDhr z#kwGKgZ|;xW304$feCzIzas?_XqRJEUNt)O#%9!m8GgqJ2!uWMTv1Z^;BB5zcuhx3 z%*P+&HAuNU99Y>3vnv4`;8+9^9Rr!quE%inq1OAwmo#&kMBVC<{!+rWTFJvk1L0oB zR;=VHBBCDgV~{_%8!;{!HfY#}vxl#k$3dY>e;WH~9L8tBCyu>cz{EYIC^=PWrk*}` zV2Phx;KT55e_Z@UxQ%8?+u5-T4dF4~*wQojp2^3i)C2eXeb(uKkqtWkm+>-R09X$u zzYR4ep$pSpp2j9Fs)aEzl1&`11NK2SQIl-5pEhJ%M897Dxle|Dbs6>88&P{)2=t~p zPO3`VIHYPwKenhNw*#5=m!?r82^;2*!aU$@N+&2T2FB6lxLQ`8TvIVswJeL34xupR z0fVI%v#OGGJ7^yU_VOk|`k1(p~4vfJJ^ zgW3*M*crh59B!rC%Ydd-SSe! z<<`^7{h&HpH`YXhVnmK+XP!vT5x!NF#21C2(6up%DN6>zVfWU)sT7aUpUJ($&#As7 zx*s>@k5|`@q^Ksh$ zxyd!mOg<(icKRAwB_nE&<@a@^^qD?MCu2QUq%)MeSlURxV1(0o^-R&7>O1Z1i}cQJ z`4W~eise`TM_aF~iB<{p|EZ52 z>;>urfuPaZ6OtE^q4V0aZURswAvr;q_K5 z&e6v~@?{FMg7e^3z{2_$g>QY8vSHDJ5gjJ8?M&9;wL<*-#AdzIoVn9B3JtBv zxoKE+`1&5Z04cTld*La@xn0r=Ji%EK`QDqJcTgWI)un7(h%?CTG%Pu z4=hfQLuvE=7$1+?RCoy7bg!@9HRge$N6A5qd(_7~SOZR}4`QY^9O)S`GY!r~c=cA? zSIqPFdaU+;h@E)qoCDgNad)$Bvha_~oQdpyyv2d(!Ao)1f+Co%4> zRDb!TrKou(De+N0`@eJ9RF&UaAo}Z1v+x4`OY?-CbZ-_rmhztza|R>&daO2UWt!2C zmFeY`X=skT5>1h%&^!5^y+)93$sC>zYJFL3(l9^OTrT@TlnU*7>@>#ZUe)>94I-r?=0snF zGxt@ZRGnP^>yf;o=CU8PP57ZO&Wcx9oeSXt>PQ?5$Gb*tSsn;C$}$?$r+dUN03p|% zofHGSjFD+6clIb9&&?~h<>n>vgoB4n-C$ZcX7J&1t2!#WAA722K?nA>u#KkC+v)Ej zT37oUSS_5LQ&TL#9e+-|--YPxIgV!xhW~mOjwr&JW2l$czz>1@OsWuJFT6u-q0yiZ z*sb4Bj-@-MoRUPjM-X<0ce6a@;$3idJB|}|7GpKY2qpK>wba2N8vsj7=u@vM2@@TC z`{A$mbXT!UJ(s1b1MyuK;d2$ug+#btrGzSFTYZw|gvGK1nf+B4*Rpof6UOI^4jbQi zRmU@vXFgA+)9pXlb~*Wc-{%dRYn6t~@>ccHDdi7)7z{H6`>v7E9=5D1Pilv;elnfz<6e%^8cuJ6omwWmRY;hzjxz&tnfQdLN6n4_>6y$cI ztGxjc?6shRemJ@zYErxRV65RQL0DaEL|RJM8W!uRH+cQ6Z{S+sQB~fmO@h&S)a&;b&;Nb=Dqg)40bJnNtrCpMTP8`@i&x z|3}FZ{gCp+l=fj=UZq?JJ3njvv+4RvGz-ow z{&^0T%E!KaEnF{nk~3Dhb?traLq@^z?u=boU&WxcnAF{B)%8Bj+@5*S`qC*L$@Hqa zZ}&0M0zG6NLlnd?Hin5ump*z8$Qtq0-hR3A8ZXC<8c~G~5<}Dj^NgE%wpx18M9fnC zM$e0QUbU|<`|zE(RJ)W3MLl>5lc?gApvgCFn+?Ax_%*Vlp^`^5y0%abgB!V80rEkx zU!Y7mhq>X(eB{C4>Imk)o)@#WmKK z2f5ZYqObdHdSG6kOw)VF@tg+e`4oOaPpW2j~Cly6oUKzCj5LuZ71oO2o;hk10AL z-X78Y>K3D8Bxao+v}z7HDC?KXl#RT8f?2*y3bBW;^PY-V($EdG#59O0Vtn3oSSPu% z#~-~8ofL1q#sd~Ra#(2{$h0*272B>tfKw)LW_NSyW?o7Q`Ei1YtLM=2{P%na%-io)fA`Uj^!03+ckF zcg>G`#1k&0u-*C27S=9{(-sPap}0q16uHoY*Oc>#Bl=81*uyzQFT0}b$DgoZ(w;ps z@*(jwP!D<>(1NLf^LdPT?F(`g>;1cDU0@FRQB18&buV~ zll8*A{k|X{g@;K!c%~^vJus7*UWk&93ygiZ^ps4HO8?2dJBT1?)i|*Z3V@=G9a zMXpwu5qwZ3)*wp=Z5%9HNdu!Ufn9nDV|44Q;h4u88b&W9evB1OL^~+su-eJ|%YN^* zMBCJP`&iLxnYCE%Sf6B-d}@9p7=>sy1SB3Sk>=WC{b|W|r#p`oBhnp2JPjvB*Tv9? zALFK)+aP}E3_&M3WuKxn(Z|qBPLb3@;%VU?s$&0dAjrO{?h7VgMNy5rw@C7Jn~g?c zr-K9CSiWTQCiGi}MMl<#n0aYqY?Nm3KsIUjNw$q>v+*9Q+)A4c1Ri+o$u-kwJNAn}v#vR8ucBW&oV-j=oYs-b zIq1FN7xyfTQjbUn0PJ@dV#yX^Lp5As$*$L0P>lkbfOTkz7_V`e;u^*9?h$d1DSj*_ z>BLDkK4~3!J^cdP;Cm$Ohp4x9Y{SaEx5$$$Q&WK-C~|*gDQ7A=_tNKIdnO;QFZ9a2 z*gEPS!}!|641DYf{5ukvRNB<_iltf!!91*1+SLQa*b=K(p(InIx9G32X&S-Uh-IMe z4^Y^_7JN5gY+2JvJyeZud%D-zBGxE?nHd_DnudNxjiQn?rgRogTkj+1D^;0!#a7zr zJ6o`;@^#5SB%TfiqFC8#Q1PN%^$-`>(@Ai7d%*=Fnyqao!!o$1Y|McD-xxp1>w&4r z7U`1)>2?EQX|$51KEg-p^}5fdf;ySO!=oP2dZCD^7+dt*OPqUr7-Js}a1TOyzoo~} ze||9yDSF^lx@|AS71h@>FJ7Q{hU}JrBA_C=mA#Yv9?T9r7(1)taO94Nv-}BlM^~ z164yRZ}?trSD7vsJ;dtoAaj=M%$f9A^`B37@|=pC=)9EL%jG#WqPv>*S7&(^v}ETF zcXFkp9Q(_dN{`tIT6f|@g@>SoQc?^Fs6p%OSprhxdb|Lj(-Z6dtsC`CT zjSGG|WMg9r&sp?kWy`nUYxMZsnNSj#*mB#Fcq%|=sa^HA!L(v)FoWuJr*_Mk+IG95 zabd=`-7gvszKPe#CZ)RD%FIM0u!ZeB4njMlJ0YVjAecp0a5|!I=9zK2=w2I*d>EIG zBkymp)V{Bq&cZC2)o|OcR;#ftxBv@G7hx_P(BtaJBA9&1)zN~ zPC>^u)q)HhJjmBscnwXRyLZ#=7I{Z@;*v8jZ`<@YOA+-!$apoU-bm}=1`DwmHyhfD zB~s>egUuYR9AybRj>Px9V#P5Q=pWM$c5KK`l(WU^cc(G-$8ODa4PAThaPi}xf19ov z&Lvi$#rd7Dk;n(rRO>4&GlGRt%VrDMNIjbBQ2TyRW(R1j(zwkJ;35%D)Eebu)h^AF5^ zF(?_me^?iiO8ITh3{#-DK-D4?Tfg+RAJwNnQrU@22V9w4s^>(lMeqQj3oT1Y@Zs0N znSvK=%(i%j=KI8d{^aNlah)?SKExr;dipFcygzj?nax8nR`QGWpoU%tg25c$C+StH z>y0HU;X{kYDXSHa(1 zbMMgC;uhcjBXZwTmDh?Hx=`!*-@lZ5mc-LRJy`40yx(sC9Xqe68d@L?=*r<4_q^ja z8atY#DD2FS73y30q(y$N!FdU@E9*XB%a*OQ9-*abG{28XUx!-SkbHdYeeF2AFL>;W zlLPQHwKSxEgW3KBY7e?QwBX>IRCeA-ls#So{L@int<+ch1=OFjlowMU#)>}ZPWxx* z!0MFq&2P<$_9xHiB>k&fN&Hw{cH_*6z0V|56~{Beot<@Z(@$5QP1q-Sd_MPq9<&A8 z!~$wI*fjhoPpthA>`lv~4djNs^x1&(wm_Kav~dtE@u^4X;v1U7L|Ez+v4hx zPU%Qbz>&sIW4<)n5^xP~-`SW8R^w{5LZp&DhDjJ|J=u;m>baGp#Og22mgBbGP;65t zbBfYNjx4v8cv`@BthVp!flgbB^&!IO-VDUS21DpVw;duN_dzRSzUC2cvn~&*+)bkq z@j!(_8u}{*raJ9*g;809*{1m%>Os8I3Y+=42aX*A4A#_6_?A<8GSc8jwb) zBjGd`MBfGFT8KzJAmFiXaJW3@0uOr3rykQ$>M<0kBN4?&fwKFqpKb}_`CQX6B?P6B zV(jQ{wT#d+WtDH}ZyePTrWd&iCDs`za+wn3s(5Edq8@7LGaxhz!3{wF`a+wM;Ig^y z_tE43n69?it`ckrcQc`QJ;_fwJ20*jF@Eh=vZ!|MK&9&Sxm6qfP)9D^xARAD>ZCR_ z$)eWGBpz`j!=0W+I@#V!)B`-xN6nan^i&kH3v9gJzp{@G-z0AE7P`(C*Ojc1+NV{@ zc}2+?(Bby;=dy=nV;701iG9GERG{B>^2*Drh>&|d*7Htt+fS?9cZj5pggfcIa2zsf zI4IsVgtoP?b1{zLCpS`-N65IAx~#~BxrouX=R!ku7Ln`s*VaUaovB#*eXeS#!<81! zXX?YglVg9vY8^CB=}RDh-~k){geW;mXY)MZairpS^VpZ$uyP}2ejDyXH4=(U;diHv z4W=^Xfe#$;k!Z6IT_0}q;j@asHjI8gAd%*%aQcmJOHk#qG({o-6JdHvH`r&uMnkpe zoAz#U9jJ6x6*b#44f?3HTF|w2)<|aa;MT>(mn*)t$uS-Y zS|Z^EW4bIJ_IU7djd;V)B-oO5q}Q=>*-US*acqSvJ8HyrE>wC|@8fTalp52WoQRIV zLORp+Yv-cfBw4eCF%xo42j^NnFj>Ecs0UnwsZFRyZMa7j5H<2y&U#a4KV+=a7t%M3 zFO|}Q`}#L5g_)ycu(bNWWofN0@ibD9vjO|?Y$f52Z;N4?fJsbQ(} zbtLA&u}RcJJUdb#BL$*?S1a?Hc_#upWObQJFS9@F(@6Q1NxycrI z*Feuexb-cEMZf8~Ka1S#+w?Gb`HLx}XO)N2yDjrP%kI>8Q*UvgekW@wEl<}u^>0N&kl)tJal=LqB$jy(tXCC#&zhThXc>Qxr}uEs<%R2PiQ4=7Us4 z&(OY?tr*$0}8JoRodOMg6gkMvieGOzS*FDl@8y-gZ%>-;&59TckjpHjStuXI6w<~II@9~4;eEiimH@ab5~6LD+q*(FlEdv#KI6om|@Q0i!W{^r4--zL_Ek=%V`v6~9E zwGBZz;y4DKybXisufT4SF&garPWJ$An{Wdn6K45g+zz?YCpa*g=6zfU!tdWul><6% z{}6gU;!%k|9xl|tI2l)A>>TF^9#Ac3nyIu_bq$~obtcP%y?tF56%X{|Z(50R%1gao zy(oeZwb|gQ;&D6BLf9=mD6Td1MfS6^BxdxndWC!u-aCftL+pnj|_Y1`BT zjY@qYdfk2`Vo0gEtz>m^i-73}zKO~Es#-)BIxNX@eFfIy{x$VUYY#0Uu|4Ds-?q@z zi;8u~McdYW6vU=l2)&ISCI-xugM>~Wn?BKk5TbCe$ViAHsvRjH^sr(zqd^b8Epe$t z+;8dv#KgqJ-9qof zQ4Zi7&0bNfn2vXAdYUZw0g7p8%cn0-vFCK$sXA3k;g$^gW0W8i3L>h(4#o7}WR3sZ z3JrcamI5`%8U{D{MP{zP4rzy5K*S26^WG*Nm{FaF=-iC)^71k?sO8EL2sL4G%Mh+O zp~v|?*l-%9lbl#|iUul{Eo~+9hNXUA?FX4pRuT0eo0Je%l=epQgAk`f?%D4l;nJJO zVO=mcr(jKD=~oxm7S~w1EmE_pdzF@Dmw#s~Cn61w$38#Rx|%Ju>2Ov(=kRx)YZgDP zeC)9Z)-6w5Jy-kS(@Ie*9%%icd??dQ{-S%cV!G_L2ljWm&Wr}Ii*zYUSxOt2BOTof*&?FPzF=hDR{nV~ z%ZruLOn~>Xy+`g*5>KV>Lxsd5ooQfz(bJI$(QCZ@O}5Jj0L*3B*MqHnyAg$*GV>~I z-iYQQG-%lt_2@>ZhaUuqN8(wxcGoYkbpz_b7b?R*OzolMoH#ZnIw`8Te%Qq_yB%?|rp3sK%NGO*o7*aad` zdW_Gv@MvV@{vF)QgpUSMSq6G2own>(HtExpX?D@azt1z9r5cE-T4j)QVdjeRm0)Tw zxxnmkQwmKbo>uY!hp8ik8eD+=2UDUj_> z?!kTYfQMljw!O+)G8Ek%q8@zn0#h;foa=$qgL4nIw(EMGo^N4<-tG4dm!7lN(5Vun zVD_}#NrW^O5}DYs$OrgILhZKTC$hk-}>&4&D_y0XDSVJyk$RV9E{xo=LnZY2}3h5fPD=rTr?da zBfXoy?0%4u8`e-pCcsD*3Bm(RlTZzrXdbTL}2#c}l{pw}u zaJARz907h|tNRgILpl(RpOx5PeB@#{HT4oZnzEFTcE=%(`nz1?3Gb9T^Z zkZnaBL;2;-HlrPJH7%gW8UziMJMe6CW7t&8Z$K|>Jy_xe>RXIshQ0QlR489@3Rtw+I+Swa765kiKYE`S4d;ikQbaI_cs#wvq-hot= z)f%(Vf^WA#|6k+^N01i)?OFSUfsmQ%wNsgovdMN6>LILh;-f<;&7}*wm)z@kbia=~ zJNbeS647}2ZA-%2Z4kE z8r*dUcsFCuz#_OruV*dnvAa0r+!|ao-LK!7@~`$H7rH=_4nh{t*@*p`zE}ISUA8G$ z9c{MNDW&Ez$@D3=Qv9^2Ip@|f^DsdXUNg%cbTXFTjCqyv*p+xi4XAG`uo9Qe$j7*n z+IwDa8j-HW@tlhfWI&(a4rTUm$@YGw%zS|;|9a;u`nt_FynZ!};V-+FCGC)S>XG1< zrcE`4rclLJ)HnT9@;1!F#&j*Y_bGc1$<>|EjyzQQfyR3Z408{r_TXi;FZ`P`5aXr+ zC-l_;>cMuRCSGUTEIrio6pWH_po%fK!|^YAv@PnKMD)pE_xH9kk%qqmJ5P45lUFj{ z0$J0Im9p)-Ll&>#8@JY1 z4ddpY|Gc_Ne?ea*XrQ%IsZ`7UXR@8Qm=KfWYVu$3cli3hXiWJvICnu9^B|;)A~f2k z9*fK3QH0Pk_%U$}f&$L5$rhhXgc&#g8z4bl2?JxntL8snC>%&I!OWf1zwxIn`)ule zI+l_(a7if}LeK1epMTKfG0VO>G1=tOG(mra=u|%SVJNELnuTbRO&^MTgc=B+P)(7k zpkSBLELO|vrx!8$ODpqnOI7T*a^+m&YOa+^S6qD&FM;f$8!a4Rsu`X*+frKN=gwG5 z9ppQx!_bgIVXNTBeMCBj&l=*KF^p;6rA}X`rwC}plrwe2q}ptkos>SBckt;of(fnJA+M!F)6rHn!yU)Rqxmzf7yAN+~ z-+s2{QAa@t8P7ocjEn2;-Rp|D2Rq~&EbC$rk-&e`fd#rjru-fmpg}`!#!`09u$+(n zQJv>4Ak1E}6|3ixuV2kVbE{6mQu1G5*8Xhlsz0>SP6qdZev{LNOGX5%p=spWq8|i+ z*SxxF7@TlGti)KS?{E5fs8yZJP69AKcFe7s?>zgDR;gtRWr%u(y%4*TOtoIiq&)m@ z%4TXf3~q#Zl0M(`HCZ1Vl z&H4frGGo$j8^6-?_ginjUnr z=T%hQ5e?`XFNwML?QifC?G@K+xp>_8DG!eFR&h2rl8nYZ;^ZSryO$Wl^MA50 z20;%Kbr^SpBSj-ri_qU%5ZaRkzi2rKFENJV&ob5z6Fy>&#n4DL8kX|?4+oo5kNUlH zjs`&^Mz-BB-83fD2Grw&tKVzI-8!^RMi9a*I|R|Q#UE`&HH&xNrnB)3Z*4JW?^1Tj zu!qD?A^f3Oti!FLSnmJ{`I3GupN1A#4XA|KYH|*kT{#*wViHn99(LjFV~WTD3yS&% zL(AL}o(2aG7g8>JnVq`lJiptwH-&a&xXrvFZ<}D$NEQ}&*n{p6oouuEZF#4=xF~AY z0Ymr&K$`!i)Jy?$>kD>H_nt#o{UxJsy00BV()K?{e839uC9YzH0Y}q zAw>PK9j~A0*ev0KNPVc4TU1rqX9xJ919cZ|a%85jZ9Qs!D(pm-qQwt*c{y@T>w%>h z>#4rMerK}y4xvN@A+Prb%c2`o{_~92Z$fhyjsMjO+zxvljC-oejc=>|Y$aOumnX|~ zDfq#rw?IN;5u<6I9a>)Fz9@Lqt#g=s1Z7a&P=48G10YyusJ{s~1>-e%VRnICtAQYP zu=3Ogp`IeJMelZF1OxGc6FwY#LE^s~lENL0c{IjFV7psbis_VNm^t-2Og3hnP0kt-$I9h zx8x8A6u2Kq^Ik3rEccJ(Z1bbL?YYp()NfSAqaH}>oCNMss-8AjJ5E$f(uK%U z-hf)i(<~&ibF0!GRVn)(PVaQMMU|S%S-#bE`7_8z8{*(TiG92Ez_c~G39SUpPr1=0 zdr_C7>6Z2NW5g86rRe_m1k*0HRaUtd7)ykskHLD!W! zs+Kwr-sg0J4zk0acqMCFw#^DHK05}R|}b$GYQ~&OZ3|Zi>F(1N0RvIs6JFCShGHcN%R%ngpx=9f;>1@+3gySp>8c9 zEij9v20f`a;uZGHV3hoH$Vaf3jHv3DL$hxTh zqQxpMmUOL|D<|4adogs)#$W5Ht)_+FfdSMK12Q0k!6v%RL17&EsQbedvV|_Q6XHUT zXcGfSzl`)v*iqgw?)M5LOsEY}k7ZyRSM4l4Kh#;VEdHU#pfa zHzbLl9_;t%#4_MOb!cA|X(Y09G`B=9x&n_4sqKP~QoM$#?ea=jrahj8}r zx8{q+MJTQ7%&^+J7gPEq>k^9eXU{_%+Vq${1iDun$Mku_m^bF>CyZ9;^V|c)b#I0> zx`uwsPi0K&Lo599@)rEVx95oMlT$d>xjq=asVJ)wFLkipn1|>*x39#jU=f4-#D+MVn9__$)jv^n=tJ zTO5W&yUb1dMJyY_)k8qU1?HhiC-T}k)-Ii{QXa;OYfu5ggr=%>)IdmY{+5M6c9MOh znXdl*yc$14tLIND>fHX)4cOoI>r4t5Cm)UBMi@9y5%xvkgLHK;EfLfql$>&%$7+~< zS%*e8I=4XJ;f%ijtz*1bSyXB=g{R`4)e!kuUS_RP`eORkGdH4!b$~5}3yrX+SG+4GR&~gZ+hu=hZ3SL&|!v)tD+Q}fizs$S5TIECU zILt<@W3sSEF}E`wb6JC+F8ExP^32BUfX@5FfK3~HZ@+391vJU)O^DwHew2Hxj7__U zs#jsHA(}V_eI5%Dp$y{`TNIoyVQ-yo`-4GHdKcz_>)}sz3tbiqX~adKquk>@YUOw= zWi)fdhrfo$#)cMwZCuFEp=)`BQ4ceF5|-KCIaW%g6J#=B)8(T&yrf%MSzasgQv}QN zt36;J^zLs~l_K5q=74>i)$VrS;F%ZENFA2)Mz_Ehh(@9CG-O>GeEqyjv41Sy!L$9d zy!jTmfP3EVDEBz7W8v#T*Pyd`vEp1a;rz>1t!qs83B$mg*43SAFvS%gTSd$gdvXl-KqHN_82MnED|_X!pvOG@k1>i>riNJ6$6^ZuFky`?bR5%x zcN4cH2)#`6vYTn) z6Ve40cft1vVRwtK?dIJCs-QCl@3b>jeWBQa;pkjqQIEe_5AG?(Bs~UVa)b&Gue2P! z0@1Yz=rO1;uNQcAHJ^`(VA0g(K5gTjZXy(JE9ID|Q$a(Gr=#<00J&eESri(6)ycr8 z2ciVF!OY0M?7U=@fq@NziX6QV{8RZIH16$MR?zQlQhdtr+-w3-XG@eYh zF^CuS5AJp@8tOvE0@X|4?Ks7Khjh<#BFy6(PCJ;V13k@tukv>3Y7rYiO6WrMNr%J? zl*+MH9_jE4QP+pKhrYI~hb_&0pYi2ki|S>a#XS57NPo-33&wFfbzlUwXb}?Z{eBwc z9yX^g393e?W8{hLJYb*R4_|^Fm~_>+9!hirj`t*~*STqF`X4M1NylHCMn!HbSAr0v z#$-Vc8Uvf4@=`5Le1%C5p^q-V1hOA-=4-OLLm#@r1Obufep}ifp;9JU9 z&ooxQ0Ut!tW3`UTnaV|S@DKKmH)1!$0~*JoULYcB5MNx`R?R#)Cj~KK zi)~o#ih0$K9xXZD8i5OGAJQj+UBo)L;Ye#0pJ^;l<84`|kBg+lq9TzFWcO6u;4_X` z;D+x`ODijQ863{&Ras&Dsn0_*p;w4sksYi0V9(@_2{pmYyx>+#~4 zLFl(JAY-j|MxOuu`4Tn?OhZx_rXB^6E*cC^57sMyRk*Coy)mQMpNdj;F9UV**=Ew? zIX*OCX*I}pt>8XdOhX4BnQ@W$N#pITi+Zp=b)Ns%J{Nscp0MaA`SubTHG$kT2GW2` zML{G>$x~YILdF=Vvz-`|*j8Q8}SxgK`22~;BrGRe--X>9RwBxXtRzjhKzPz>=kxf8Iq2FJQ>NslmMm}P8@V-9jUIu>1z*IPQV4)PL#rO!NA8UQ? zvPDK3|BM6=r>fU%LK?^~oay?V zEk%Ld1BX0V&=$fle)0wdZm8WtP&+&>vIfbl!l!?uvo`0kSD>5MSj)pSbU|(~H(|YL zsg`Xi)~Cx*0h5!oL*l27383eQl!1NZs=a@>$e=AtEvjqSlct%RP~gSR6;}ScB~oP8??* zfp15RB^k+ZD1_6FcuyE#Ia43@BzLZr^Qtm)HPcGFlem|&*mz{VMkw8}b|eA@#|jOD zskaW^?7U-r6p5^wF$bZ>m&H7M#<8--V_{@r$ntjBUtL(I4Z>EzBwBznuF^%=oHydp zkV1W^v$pVC?vB)S9&}^Fmoi5J0L>_&N0nX(B+qPaJiJsfn+zc8$tG^nfnhk zAZnc!vM{FNQkCcE*Dh=H6OZLpC*ba8r?cyGfZ^-t3)R?#;(x&Z6xTe$LC*7dpArPVt zSHAFi0K%yU_MJX;-+3bxoU)wBny3O{F%4En%Q7!`Io6hK8^YA>#ywcyW!@l!pnDUS z5@s%PY=}JRf&a;XHD1L-y4Zf$6sA6!5)fiacwfyh;c>BgxH`L7Dbc$FSm+T48^0;P zxHHMOJ*v{0XIkTLI~Jp&$LDZZrRyRWH7;$-xW{k@z&c1gm~RTBy(}(q|4xT7pAf&iC6urg0uDM_*M005 zM);jfVh^+lhB{m1m2N0pRfC1r1ECLi)G?PbHxTill8KJABp(t#dFH5di|h{)DsCNiD!yL4P~ zy}cJ4PxNQ?&+8X;x-uRkMvLoAc|#RWJy4rf`rl4pr01cBVmFj?k(P^ZH>!GtC3kp8 zzULwoEno>e(}$X;@VB!#*2;4-=)NX?tgkOF4s}&oiv}*jEqskpkYy$>W!wYD6cxkD z)M@=*bsnKp?;zMv?vZ&ck35$(Uf;uIiL<`^mPF;PvoYo6P^ONNa(d6uJFAjmyO7c} zbfl;JdfGo|u9nU3%*>t;RW1mv{J;bKs*=x?gLE8xq+WCU>L5Q(w7{#4e9f`1lo6&E zevJn+%o_NWAVJHVyV(TQ>qCiL2%Gu#Al>o4A84q1gWx$Lj#4K(sWXcvg&Lv0obYzN z!u^E1-01o<(d+9!j=orYp#6!qBO^l*^9cUz6!?L58ZFPdNttZ2uW)?I9r%tWgR* z4)yq)NNy|`Q%0IM^HNHf*8$!IT(i$j#~O{0t!y{?(YX7$rTYk2NTD7%tack@#KSZw zOr*=u22c-hQimAFC6_mhXO)*w-m>>yjcA|yN6jN&V5asUX!rMfK>hc359!IgvZFOF zezqUGEXW(kNYsR4z1kB$K)>%m=Aec}RjUzXOQMA?Vpk$zGx*7{)Qi{qS zuMd4~*W%#=9mfQy%hBH%WgpA;LOrH}9=rq5NM&4Q=-omd)6<)j2eT_M8;^DfeZ-`H z!_*@NDMP;dlVCCG9uRCJX`)FpUEaeYQ~3k${cm!IY(01o?ao;j;Y#u?xU+KYe?&!& z_FR^Ze{~7r#nCd_0$G52I!GWb0o7oQ<3<>sNUn&FyF+5n0?WyDeRqzo2pK^@VGzx} zgjONZrGV)$*dPufHU3as`*4(HB$7r7$cInDagEfX%@Z)vzik15>+}wr1ZC8mKZlca z&ezy=#O*SqVCpJmV#| zL;46&bBi%6F4je=WsQqRharTkLBUIZ6ZX-MaSJ%B*CvO9;ZweQhJXGh0Smd8(k)@8 zHI(;RT*P4jsP8|`hzhnA6P473Vi66u{DB|%OiVYcpG^!NY=P)L zO!~oVb_h>F4_In>Y`2K`Iep$0PNop};C54>HOpAOp8_*hp{F6(l*u>mgZT8$2Rd4R zmYtY(cvWJpanb+Ij6Sf{Vgh5OQ!&E!CLq{Y)kRAZBT#(A_N0E$vXyygO_G3o41xzb z78ctEO<>@|#Yol#kCC7*_C*iak+{f8f1K!G*mZR&rtmDV?q2swHvK#iFbc4D*JIo9 zY)uGn$6BS4m<>gJWY?;Rr;CvDsh?o8{(}CUNhsmqtM*QbewchjO+iQ1w}Mbd!crzC z#KZ47NoTu(NPn1mEcw^LkMoRltR_+A@mOEju$0-)$2Lf}I{>#1!7u9c>q1H@f|~FR z9t0tN$6EFSL2Ye=pa=F5BHJRMjV|ksSC580VjUyF66u|1v&llQ(wk@Gr8rUepNJ~=h38P_A9mMx<6IhwAaY6CUM)EqHbX05!I!L z*v-@enF@q0B+5KCI5CQtjWO09%~x|uBLh5!ExWXg{4SkvhJItbw~IG4{vK_8}GVqeZy zc##@d!;ytWpdM+E*_5g}P>>^l$*nZ)~51<|gw7@35xNLwC!cU(P93PhZk2;=n5$N>dCxF0wEg6cdYPo_#;A(Z`IN zp+c7wbc0cn*oEO43{ExH^tC=OMfLlj^w;8o&amhvw73ea*84Gc1s*fOqCWHijI{lL z447CD=-4xJ#ffcIIZd@TT>G*~+m{ z*uyvqPf+fu!rfJUZ7j2a9M79BD&Qp$ORxEMV!j_NW@RrC8?_o4Z@LDf)9}q(!`U*l z*Rv`yw3+c&H)j4Z2xj1T@^POd+!$I}>SMFT!qx-vUUCKB$p`c1J@huy*CFV!JH@kR zO$WS*tK7H^>XhtPO~K9)I!uogcMh1-h|D6CJ}J}|x%W(pNb=?@1CNKs<3CKJIW|O(5=HL(0M|f33 zr&33CW=T}#ad*3hoQ(aD_Me1@+qXA+Y&*$T$tnLd&)nbrDp>=g5$-XDjj#}fju+P` zoe-4)q``Wog!?(9FZ5Y|b6>-w>H_vhH{w?@*m#(NW2C8!XzDT@ggd(9Z_91mtOdS@ z3VCqkCLc=fO!*O!<>`JT)e_O4HUe1$`8Jz2SSKCid9cgDt)SyR{rvE2EYOkvpS@;Q z6rDVjC_FITe|~|GChBR%!0Hh+1t}JA@X%d%j4zw6uSGpbTu7Gv9hkv?`I)qdA`|(pvV3el($%x z^)~(5m#6An;e*hnk}}h-UgA1>r}g$u`vyu#JYASjl^m!PjO2-QA9ZWbUssfqZ+$>w zhnn%Vwy~%Id``wJG~3X9Jc`O%!km+NQGy>49;+`1RwH_ppPx52!iMn7N{cSnt6X(@ zoNhNxGTWqE(4{tb008yiSq{v?w6H<$RwN# zvkCC@jlk9 zrL+$gEbBsNTL{wdhiifyuqUOWWr<34R{uj-)waMC$V*A*|b4AJPpzTlVJ@+Y>sI_zP(++X8mwF?UovvI9mRx*yqQ?S*&~v`VSsl6q6g5fNkS_d5$TyXuc8gWg)_G!!G`Ogkj?(nB z@K+&W^Oiz=+$<6&hk~!QjrF&EMAm?VFz+)wz70gi1j#~18>@}x@jR#5;eo4USR8bZl)3v+rvK%n3fquP0$%es&Gip+x8`d@iu$bjws0* z5u-;mw0YcZb>c;JJLi^K7)ve+o76tk##UG8M!bQV!R^F&TUXCrLe;FIlqmHuzXSsC zBJ4R;I7Tz-ah)DV&nHufoc$07u?!7lCdM;N#nP}i?L%^!7&l)yn=r`=U168$OM$FQ zWQ%6O2R!SWi}4r;7JWb_L(&lVTZ}4qgBBUl66Q!rg`r2i$1qS1GOoC2=d{EygqJQF ztnuzV`>Q1O>=y7?v$G)`NMNYXFPQUvUd=YsP(U;->W{H;oN*AWWqt|QzVuGj>6Pff zXMa|*$~))hF@n$2&4@X>I-Fd!G~!EvDZ$uX^%m%c`JHLHzNu;G9j;Ha=m#CY?Tkj~ z{Pif4r#^iU&x6G*h2e|%UIPN1jWNGlK;xnw@TGTHHGH<+hL8rSl!E!o98@awXP75_ z7q19w8TyZ@(sl5k8j9oz&V9IG96&{2utAjSYa|Gg@`Q8 zvzr#1Y!XBoPJ4*Oeez)ujdA8-BDJIkRW|gantw;+ZR4~y=Z!p$NQX9k2_Z2BYMv)wGNTbzorFJRF2(dFq=&>P-JIS8d6$+841WunJ& z(E~XD6J0aCU;I#3en%GcMKrCWTaF$N0t8hjB(TtmIjzlZ8a|3zibtI;gm`AKNv-9$ zgEMb#O14iixM39(cXr7L@zB>Ax8Rm=ZCMHzHy5>fb z^oym^pO1ECl+H1H454ZdX}M~h_zqD8C?korh81oHOQRy(aRI8ZFr%!uE7R`(5mCIjc8TJMzTanrtxa)WqK2|s^0!AG!<0dZktALuKb8J09+WUqbX8j zVwX$b?`aW3$Hk8Ihu>NDdxSHwkbmpbI6^K9@p=82MLu8^f!dV{tY(?6rOGw-Y5^2PH zUp5^&T`%Rz;Qf5^fJ^Q#4bl(`6)6896dJE4L4G^}@sdTZYTLPdOJj`4W4L{$IGc;0 z`XnA>WNPTg41K6B6tj~So_Fb{Q!vs;u2)V$fn!318SFn*b<_YuMB{y+9(H;IP5zu! z*FK7^=Q(8`7B*NEy7oiG_0Cg5tGgU@q$_msg_$zv9liju&DEh zlsMtYFY)X6*-Hsku{%8n4#)(5{c}p~erTDLjJlAFDYkAXij}UKm0ph1jr>vFX+E;{ z9&k(MKGhKyb`=6$A@L&aGDi3S{B`HI^gy|rWX+YlojaZ&Y|^o z&U!@s9oVTi5|}bllxma}HR}&BBWfb!pQU6rmFN@{a@bWT5MAkvXLq|6ZZ7u85 z%Xn#NiTJ#^9xxAxszXJCmIP5xu6PPEY6dHs!FoEYWL(1-pf#-tb`W;=MMD&o(`&O}{Jva8`dYO!@rP8S+V=3O2z)>(6XhO@%wx887q0lI6s5s& zrtUkd0+HzYalL|HIJ-%bs1d|V#>Gb|srYxswvUujMUN4W&)S)P%qU@X3v`q7!ji7Q ziC#Z?N&c?3N$(I&Jr)8`FT@4G+*~z(?}U1Fs)We*Wm_B;6>RUbyzs1y;wN-7;N5w@t%z;FKR+ zgzy7Vih@~VI2@@zT?x&nh^S2!v8^Du!c#PpSno%NB&cL*1S(JXJ3Jw?!~~C%cot7F z3knzeo$0%Gjk*P$?KnB=i=re^6W#ZpZ&###YJNLA7}r&9H72^nG0zJTjH?GdRheuB zc*pJwX%^iov!FZb8%(+BY2UxBTs};HV)=Bc^`fHONn~?3^6F!945o(%=KW1ykZ2Bv zT^C{El#Wy?nS+0Cy24LZ#6_ZIOtsBw!X7CG^j-q_I6Xd)fVVaXbN2xE9LC_F%Jk~X4~%=B3Fxq={h`x)5%A6wvdo` zs=^;i#_TA{M`t0({ISLQCP9#1>=$=Ah>nk5)WrdoI~H|CS4+S5Icw(>ktyE)(MYH| z$QFu}0#EUf&AXP7u-D1hR`1MT3nAyrM7F4d*p%)_6O4MO?H7Dyg`T1d*H;x|cd4vC z%CWq1)|iT30Vp?IaUf$I9O`jY&JkW49EtR>)Kt9BEQwnruswh!ZQ#(%gc}$nF|2$O z+{5@(Z2_Bjc!N?A9nmhiX+6LK_BmT@j3;kAtiU zJEg8IM?@fFXeHlqO@lzun zpq5k;?n>&UqIAx#)2;OyuN*D6S}B*&kH%eWi$|w_0dX&E7K&#IQ*I4V2)4UAD~#*1 z?p$3oYSg^lcy`p3Wm(SU2S!81*ZuQc}anNd|U@iqiT_R8JsM%qi;3 z0e!NVd&DE!iC>R~$a}C|mMy+`2?7sGjD#?W~W=4&LNA)@?t za%kkqy3Xvy2!@uw7wH?<^Nc0P($oFiHE=9bRu^%v?h>(TlZ_-ib+qAxGf_s3R) zN+e^|@M+^@SjroHF~joGV}YJ0R^h?!aq&`cwSAovi{xRCQE=wCeY%^;vi(6 z?Yv=)unenZJ<5@vVEbXhj7*707R+_bpKDsLs&l0i4h-OygARJr+>I<~FU!kr(H5Dr zACZ6zkx+7X3!j)qRg|@WMa}76(j%W7-XOYorA|}Ct<>TIzSmYtRo|=d)y) zU23^?NJ#7m@*1kXN#Ez*1!tYN=pl~ftjh&L1SG7L+?u|s$CU&TnINm`?2=7vUi`y3YvSj!#`k(ZWJypUs{1Z#5o@?GCIVrR zd3`k!?>J_#y>{CFh1qESiT_cjSL!5q-Pbh`^Wa-L+|yo?G7Gi*eif2#*^`{Nt09Ab z46uvIJ?Qx3St1PotUA@N-6h{|AB&a&>k*2!!5i}kHF#v-Mvo{SG8iTvWQVN;DofHXKfWa(6%odP+C@txM2W5V%WyCVFjN?Ngc`^&L%*! zo9#RXn@}!#83sccsG*K=({vZ^v(B|K2YJ7X3y$`n?dxkR%dFGOG+1$AN-?6FJoNV! zUK-ITR&0x4xqE1eJ681*2je#20S~?KL@1R@7$#S+>7kD z=Jl|)Wrdfu_}a>vU@hSm;}xIHUIk*ITxn%e7wFKke4ATrLh0rAnoG!MDejs+p+0tI z+A2Mdt3}4SJ;#?oMQm*K*%}i9*Mh)@p>J&H>&6EA&+j7;R;P{5rA_MVe~gI7rZf6( z+(U$K=v=LqIyrioGU;1gJY7Jz`c6A%+bRs^9{O)WFpn3T`%U#(Z;vFyxp$ZX2<)=F< zuO~xgm<29o6@PmW)Ok#<@pi1!5qqgwvEi~1|N1gx7W8B7bucpI$6epRsg-o#d-NN# zpX9Cthu?`u?lxp)Qy$ShEu{@7q`Km&PfcM~6Ee-B7|X-q9wP{S_)!l^&Q`ddqK~Ji zr`@W8>KTd^89`hVo=g^HZQ#zuO%|Lr?`Y&QMpBJpb9?W?>@Z!Z-wG|8eRO zEfu9-o#vLN0K+{F41_(kV}aHKPl{VD=wUm>ii=rQi`y&Bm0D$tMj5bZ5)*3V1 z{^HrIK zepVK}FxSIOr8c?ueUWXI+l7S0j-#AHsMzkxO_P>CMd?{0HM(B|hN!gt+nL<8an?m_?HJ6du(ZOTbl-!-}^ zLkUOqfCiP7-k(~cdjs2b652ea9e9~OqM6E`S48H2*JI*ySZ;L^w(@chk3TpDUE=)= z%Vd;$tn=n-%d8NQZS*>?Q}uH&)AY0Dpfzp~_b`TpoNH@1)DLurhsUQMwV-_+7hCWy zB&-b##(_W-{w{kw5uy=}VEuUBh($WU7WXi2vF3Jo3X4P^zZ+}(GAwgt?x|F! zRSxneYPRR;Iwh8HXU-Q}Z-MP)(IdzxHtmrliw=QipVZLJdrZ=qmLuCPM5Jw3O!N>W|}bi1MT+ik3GE1whSj zCgzucEDl9J)&=hB4AraV`n%mW{81~&ox^zF*KoQXWXeLXH04HRq7 zA|#hVadoWr2l7)9@_`U3Y|TA3$$D&qlnfyE)@3q^!Zw$cdOiBLVzVBOCgU5>ux~Fw znCx`*lDo=(pZ;Ap-R7-_Rnd9rZS`b6k$ypg9<`oR{43^VwWwk#YO>huSdw{2NIXRH z0RrxP3Zsi}TFQ%uQmnjC%j{8J%pR2XwOjy+(p=4#XEh(5!QU@IzJlqS-O9cJfF(E;WH1WGKDfr z-U9QlzgHhi>H$ynq^jnR`fIg$6Pi^VHN*b#lq<|fL==5}d1a_H1XH#))d%PCHQgs4 z`toq0YE<_z58kl+QEv%?vfN)5X`Kyj#bF$0SsKIWGYfWLAeirt-3FL8urCt438sb` zz745^eW@uU9>+QJsPQ_dz&kz&vQS(sW_X?j^i43f%11{H_RVGUudFMr(lTA0m(FmPwdCd?A@O6JmJfY^(6_Mc=GfMSweRT!EVE8oC$hz1W3R@& z5P|{~a| zRs<6h<{6;?xz~Y zu>tIhYK;K%^Ys69KOH2BZ^L0k}0m^^eM0Ef4qPR85+%vVfwLo+9fGl-aKV z6yWIl8jcZG8~UK>qWcbuaqz#j5fq6|`)B$oMmi?LQsQMnQuzMlB(u44=ZwnjZ0L<{ zS@~=!+4IoyXP+iZuL0dmWFWvrH||d7vKl5^%DG$*-TFPdoVy<9!Kcr;!vbB%O(^+x z6?)L1Ub%e2E>$WXVnnXSYoYZ`t!)q)r~PR7;Sa9p+HB&*7zC*g>XD2IGeE8jXFAq8 zNKgo{TPZMoM}s>Ak*(yX1#Z6#C2ZjnnF>}VsFgAn1Xrq`)7q_s-)_e)mzure0h9D~ z$26aD3}o~&?f0tx7WQn|^?u0l**ziCEfNwx+L_5xW>iRVTA2#wW{+96MANDJy^dnd z#_uKj5|M$#o4pl$(+w6IVUAOULgT)o8*vY@@VVef=wqr@8x4x+xB+d^TUX&Cl;&}- zl(VCOc01E7vd*?FZr~Q1Z`p~*H{H+6F?iK2sa{bgSmE?8OJiTr6O2tIJ|%)Z7`~r} zpdN*vC3I)rgXhD6?1u1!@rCH`a%|MtMn!0gtk}8fr!O*eqep zp5XfYy0J?Ci|9;31ql~6K#%oUoQuU}4F48&i|vE^OHqZWm1`F@({bUB`OuwXWJEpG zJ56~?HQjCrfhpU6u2|{;?EE^@<|b2*^KlpkKj9!cQPIsqFs1WnvdLnF+uvQWZfHmk zIp@eY+&%UozSAvi`Ylm&PeQYi0rJ}@bHdTB4~Bat-&+YSdzfz5e-br{ki1U0>9j%o zARloKX3p3=zeX=c>D{Ww)(A>ZrYRf3o@QQGW>VrlA-n&l11&ZcRq_rAi61>=t0*(Q zwxw9vvo32+md^3!(n`nSmg}LBRbg9ljILl9yc0vL4zqxSrNBtd4Dg)U5p{5l__wW7ttQJ0NI(;-lgEzv{Wyh%Rk<6ca?=c zU^!jM1c%|0W_kw3Rq@pGYrK=oEJDjcnXM7CImPji$MV?dMdMx8wE1PSS_Yf=}Icc?0nf__R7_KqSdRIypO4) zrBkn+$lI#jNfs~kC%s}1nzlp)riyajR!bra_qb1Cphj69w=m!K(+27c(>cKXd;9mljA)|7Z z9Vvt--0dVcE~PgboHvk@&U7rL)js%{&I7&e)-RREo?c2wJjD#;qy}PdMadnwz#AHL zY&L=Oe}dEtA`44fA5ZQUn-IPqBUPA~fUaG;%tyMDNXpFT~scjaEpOn;2>xo#I)Lbj2wIZJ;>~g1-Ek6f-N-wHP z58+w5&A84fNo~j_+8c=5nP>>k|+=ts6`Wa`T;ota0F1 zO_PUstEp@>-YFp=@hC7;YIf!z#9VHkW+#Zxk}M0VmcU-?u4Q!v6h8=wg=h-L_J~m_ z=vWL%MyEE-=WOzs5Du_s3`I7BDDlANyUi>ZhgB|unOKrn;j!v}yO+tg+8WEWq_5M( zJ9*Tyu6LfKmB~tE_Ke|{uqCxBZq;%1H7}L)hGOuB@S7qi@#fpzbg3c zd1HNJ{ubpO2GeC2+hH1`U)u<`MzI$zZ?+E>m;iv)#PItPds?q~y_4AEt2@AkHj_+O zsyBK1sW{g9r;XIc>*^gP>CO=M9TP55n}0b%5*9nC14^I z$Y=GzDo&)ixO^r;6Y;d@KgXwDZJdP;id}!+JhDr;t}6^qPDSVP()d&jVg|_dfPLJB zge>D|-SiZmnu@Lv@cWmvUa6G`h@;y4z;y{;gpdzBcI{HSlsf@wsL}@);pe@|Zx~6H zArA?OM~`x~+J@=-M$(*z`S~4h*qUfgojz1-AT+KcSgZlu*ou>>pb0x!!rMYkH2aSJ z{%9(Nt4RvOz2gF-iwG+TiIaP@`4+6yrGq95(SmojIPn7c(7Y-;BV9NEA^V8~$W)al z>jbRi^n>BSUCp#hwn`6zFDm(pUN@fiJi3Y-j*eq}^^99|+h6C2e+*kwI15ALG&bZ>AC5i-mV))M{Uf8^`-bOS9AC`F zAItdSY>O2~D>EnPonE%ycvjkXNX7k>u_*K`Ec}Pe+`kjmJ$^UJ> z&;$B0bNNq@9iR2I|AtRn&L7mdxy%c z8aIM`Pa^+YL$$e6eoP*_@0Cs{>Q~wJVY($vImKkqyg>zF{LJ@YY{{C6K?LaS&P%=j z&OLeKSTyX3fP6TJ{E4lyZ&djR&5}t-P^}TP#;rrSRO6T+4%}wlR|jwj2z0r{f~`c! z$Hw~ny3TDyBZ|;t_f9%iM0t%cPRC(Kpe<-ejrh8c4=Z!6PT8+)pu6pza;BN;6%D>~ zx!Sd|YUi23)ZH+=<^TX5u1Q2eRGn<{X!S!KpVN|^tA1X_I$^VrQ6ljqD-L(@m#>N_ z&h7t2XcFPl41Dj9j`%)}OGnZxn7h0!$Cbr+%Tx;<9)M`Riw)Nxtga^{5}de;p0qn4 z^=>F988t7%9?QhVBAfKV@sbF4VW(JnYesPI|JaIJs=i=4;Ui!(-4vB9`ClJ(;l$C* zC7zSaLqg*5LOxw>cJffzaXH1(59k-gWM0WNVS3xovV;r}17;CcAlZ zV|MIZm@Jys)@r$ZGKYa=YW~LSK z;II>!R7G>n@s$3BV(&mR`-k&_W3D_nrvC%`;5;O$EUmQYru@Fgh==Ki zJp9^*nNl)+fyG7$svfbQ{FNy$s)F|@O0HDpeM>|&au*GBuTLu3PA2U}#%gLwP>;IL zNJKvn*4G}ysr@w_FR#U2GJ~jxNV)JgLs^sni{lJLV$pfNZxllMLE^WR_*lPCIoh7< zB&;BERsKirdg)-Xy4U~l=lB1*6OzY#vY0kK_tdAQ?1|uJx0IGa+*I?2V(TfK$Ka6X zzQCHMHD^3Dz+fwj(8rp~IVZj9^z!y2BGff8Vd9Yv97H;XWmz#N+D*yFCKjfRx}R@B zk!VUyBzC6^E&b*znaro{wCReu-Kd9;hTTd#bEs@bUao58%NZstWj}Sv{bVl7mB)&m zhk4#C{wsT%T^K3zkdSx`mn}Y9OGOj<$zSQTQl3BCd%Pa?cBXi0nK_Qn#_R2dyQ+%V z$JFMcQWpQ%;>fgl*msN7t?M^*;Rj?Vm9;Ia5T1%JlGo4x!lrtvcVn+=zKK4Lgv04%=Lh;KN{k)X#0Xcc)MStF>g z^^Mn8H!rruWHHJ+*6`+))7^lLgky~L-Cwj{>Lk=iu%lT_S8nOV;+PCjf zR0IS?DbhrxcLZrcM3fprkU#(_L0XUq(n1$dk5ZMQ1PCF3U;;_#5IA%Z5J-dw0qIqG zl}@OabKlIHd2i-^xZnT3FZk-Qeq;UJc`GI85s!9-*lPaJ*jy)!^yzmJ+jiY{pEi&H zEM^$&D_t@_m_T_{BI}{@bK@oFqbiHt!cpxFMBH#^K7Al5$G~vr>6+g<<89e<8eI$R zxVd5xNd;Oe4|@1Y9}1qc2{*1$yvd`sEU?(AK4bOIO;zw8om@_9ltRVZA})sRuQH~FLckmptUpQs8CKt(EO9J{< z^0F<@$;>V{egva;YtQNZ{j1iJBJO)S3fn0CdZBuz6j!99#c#4xjTPE0N=_MC32%55 za_4}nM$jga(U|c{sfX2`#&#%4#DL3J_QQAQ=`z6Eo4Wy=%lS3URsn`F*ZZ)sF4XJ1 zJ!IDu2euESbCZ&L%u{dLfAu+6mr1FE4Gwx@wc{abW9{{p$A$j2g-|lWzj*ea2&3&G zGz9NIzc?@cNr9G8kHh(4A=we1+Xdy)x5!ovRa}!2yB5N4g9CNPZkw4*1!BV?lDJ~TmRg-X+5HFRT7a;Y$QZ5!y8+*YeM5g(}-`lQl=(xo|l8bSrk?-!lz{HJ{TRE3t*L zYO0>3yGl$);0l!&Th}JbspirD#D89shsmITjWjXctk4-S9u?g9Y@b#_U2P(p_rc1^ zUXhnAiwZVYE0BqrZUA)hLa|YOYJ451qn+=W)Wo2T%ce0SoQmuga2w{M3Gu~<)E~-y zuL5_OAdlnPw6Pg2>o%#@S)uo&|71I0TG?z>u}|wizo*3#EcFEY5-Q1Yb+`a>pcdz4 zojG%+se2J-dtepYZ!QIgTkw;W4dV*|a^EG(VY{Q$L9h&yz67|>UqNdvY<@x4m={xR zH&|vm9yZ4Z#Po@;KYn*D0ofZp{*vn*t79dV{q`!P0T?u4?-wm>{scCw2Rx&)4x-aJ z8Z1Hx$?jN|LUn6%f$iAF;U6x*`ds(TXZsU0NMZIzRo;x(v_ttjzYTW6Z>I$-L+{y? zSw~BdgS%sF!*(6|ZG>z)f^F5qlguQVYPZra`2qI#^@zdQC(D^F8FBRGg5|?0iLdv8 z>1cQqs8+fEzzJO}4qc(EU5nj@Bqs4KDdLq;Q|fVBX8X60=ig&nI@IpEyaZpX*}tZ7ZVtfmF4YMRaas$n z?o_!ExfE93^hRh^uYVoUjETX3GvzV^7?*RCwjvy?-@H%L?QL15f7p6TC}*C_a}pdR zO~`=pfS*3zYWDZYp~Y79&$`H=1PI&+=T_sO`oj-9xA~y%jYV0`ljXKwd z0%!lqhW9uu&sKFMTN%0f1|DK2Nt(W;DTzUpL=#Ls1YJD1lax$|)BA3m3aDOUju&w{ zhPplPx;pMF&O5M>8u((3S)MbA9T5PUZua^Hp6YU9yE2rurB+d5UOO49-odZ+t8sj_ zK3y8dh2~oGCT{J5UPQ`y@laQ6-Aw5BmN(1?mSq<(E04TybEw?V{*amS%WCI`m6PU+ z^JW}MWS#-HWz|kZ-)aBS88aG=!#P{nbvE{o#!0F5_T5P!be5@4$Ut|Ao#&Sm2i*T+ zlp^~^do^17%-@*_5ipNbfE%Tn#IS4ePWEZ9`aD{;$QCKp<)+*TUt==JlaZfBXRD(`*^%Gv*|2UU*IoKG?jEh#Rk1_N_#%KzA^= zujohZ=MFCuQmKcNvV7a8w=LH7gov;T1EU|VI_gi|hKF7xy(aMWZAsnT4irnh{aXDM z&J>@bD{-Mxzwm>*fSMiCwNfDgOnA&B-hk%0EP?!ur$r`CK5MlyHt71p-nQG-MNU5f z#J;;Vbyl$C7g7Og8UE2fP*rOL-!r0jh%lvtxTL(lmZ$w3&H8vbs%ULIc&(BK-)P#g z*V*IcuyZme&ZH2Gf0rcBSVI?Fd+Qt+aWKbs_!$q1+-0U zV-xoyq7z4QdfExw;SlzXBbOO{?H=5ZA#r^ET-+m7GyS`)_}#Ob?>;%>W4K7QlN%~G zUA;s-hRaf0_tIVzyuy|ljOHc_FVTaH=M+bk$x|{_jJ?ijDIddWCD%Kds*PC63ao6v zA~aLy7(%#jPFU@W)v`o!@s)1~QIh1{hUyiF0AyNE|AObBypMxMXe4elU9S3`vEe;3 zvt$EGLePTK{?}L#39U-wbc96LL2mzD8}4jYSE7s0*_kCri}(rNKl3F0()6vMUkXjz zVG4|6*ZKENpwi=-0mVy#FPy#YiUdtifWU8ls{#t78B4rB19w?|^6Q}aa_N^i(qPt$ zH|j|vp7?6Xhgin7mhn`BgA0rCbM7doR%9&NV@bFge7{S$d5*8oG4TURJEN4eWiA8ZtddzWZ#_*Ksodd0ZI*3<1Urd+)3_>Um}CFK zz6);LX+fOQqxf*7$X&67bws%>Yxz#?@8w%?XfuePsDdT)mGx8!|6>(uU~FctdldFG zp@_H{cBOCn;`K4M;s8o@mvQS(WWhpuFnDFKtVZE;ej!W=)A4Yr5jN*?zc}-X#D!L1qmx8evL<$^uyPJ6 zbR)C5FIP%32U@)M+xC94TX%6?K_2RKTq(mq-u}>D0&Ok}-*A~r*Nf77uo%7E$FdOO zkOJZV=ay-_;lsbnGv?vPRG6CgaC`XPN;gu@pT5rM%aF)1JNf*&PO>*8hwcE+xvQX zeUt#-m}}oSM_3;U79d*p8QT+5slW*s`Z;@V z&VH7x@|@hp&|<^YWpknh6B0RD-0cHHapV3JtjkUp%g)6n?0GNn-leIR#s?Qpx-APp z2T=N5Y;RV;37-OAYu7m7m)}hGA!GWnwR|d7$afLXY{2&Ym3=W#;(7UWmE(|GoHowp zqdm~@@XMblql4rx}{Bf+SC{+SnX%|>OVH;mMn%7W0{8)6RCr`IYInIEt z7cz8VRHv^OG~a~ya~GtOfB$SxY3*K~MNR4(Uv8BwT5363q|&$H(}COCM^32n#y6I= zIp&Yhox427h^f3x;TJ3+W@J5mk?v^^*%KQnbnuFy6xyRQ)F2Mtr-E$mGcYJt)v%d= zpxr-=^+@^H2r15SCsacS!P)2)7hs_W-h$$yO+j6g0B5v|eF}d!bM7a*W|sM8WntI3 z1r*Yf?1y!z^2Ku9>ERFK2Z4R*PeJ)Mj7eMuHi(h^C#A=vP|ExmQalwuoueae^w@_>^U>D~r3_P!WR1ANR)6)!=Si_eHHp}5%@NwmV_MyY zlSWdlV8tXlda=&!>ddlny=whr!@y4oG+`jN7IWi9NWtZ^*ZlHbfghACccO-U)x|`^ ziP;BGc?^)5>>FdLwBk6fl55r7=<_c2Rqe}?@4xECmrFX7nsj)tyl?bD^5!&f%c1dZ zVj)vfh%2iPMzjjP-`+#!Raey7fT}Qq6JIbvCs?-l&9nOISc1ntw*_fLHy&$h3LQ0G zv4Oa)xBJsbVzi8Vp)A8>XP$BObE8y>LjHA$g6x8u!<1F3>Sf47>ut$vO)el!of_ly zG-d$mhYR2YG}2&u{p?nD0}HdJ^ubO)r9&wZWi`A&(G%hfQ~HzZI~IC`>aoKdzkY;l zJk&-{FY(XRLgldFN=mSX!kRlr9*kzj`jgRV`=`UU`en6W{!vJ65VFXkApDwl=a6{k zyReu(w*_DssxusS!BM5?f@O0PbR0g_Qwq;bMy4pFhNS<#U>{mX#2-CI_+P#E8V{d6 z{yydwiiX#0+G*Ts13#R~`v5Awgy%bkL&FK!UxI=x2;D0DDm?tD;dQyCBGM9m;iRFu zfsoP(V%UQ=3x8~T#ATL*=0%NgbF!Sj(4rWc93;u;aX4tFhw#CCr4u@yo+Nozu1RV* z9`Y~q(4M4dg@jpPR=KLds^*Ae5*B!5L;`Tcf4>)GE>wcZUl7pWelTlD@`FK5A9f}Q zt@3r-x6cms@X4$P69#|WHD(^FAAeb*hPZqO7djitY~BH%4UBofdv=>$tPLb&2tRhD zey(fmj;iT{;BeMbZQfG-+IxO&-JO<|z4r%5X?b?LLC(qt9QRaO0V2-#}7dK8tyA!a*_05-g!&TRLj(!nBKb8 zWI-MPEAbxpCj+r~`#xAk1{6Ipcwh ztCTMmOc(%9Zx+JKlR@}#0s{4S@h*t2;uJd4$_vJ%ry$@qgJ8F;6*UD{S6T0xNO@d9 z8UPb*F$Nq_W|OL^vuj5R*>9rZ)frTA2U8k~ zQ4J~I3Ix1hA!Qtm7AqHy`=4%+Ie5D0wxSJz98sby5RQGX~*{nACJhw=tTig-R-$s^pUJ3bM6%7zvM8Dcq)dnn9zu zJD=a^@ShmTp!{qLlf!5hPb+sgxvJ@}n$%2~yk1VebdVbJ%A5RA+I4gAL?B~WZ@W<1 zs@VHdTM}zXSh%xgLWnU8-tRrn6oey=AxmK@1muu922hkvl7n3grRby)3f@P8bn!? ziE!m*nS)}cxhR97$T!xSI(%*m4;BoGslG3VE{c1TZ9I>-Jmfg8zf-4u#jw%Tw|eXP zHD{{x?zL^ofAv-pb5#1&>AG;IT6Z_w4hCJRJIWw}td(zR{J`x>_!Ta*FUgk*#0Xtq zvr`@n;hZuEwf%uM|%L*X}wQD_%MrK<*?&dN)GW>dC_Js6e zy26b@uDBsh;g_L*)CiE%ur6_&7$o9FE3sQ?;MoMpTcyVWN)_xq==8V(SW;r*KaGZl zkwJx)GIL&gJ62mI7Sc1a+XzCc(g#B>7kBA`f_DnNZB-OO`dyCSDpNWXJ>-KAX$JEV z-LWX3Ca>;-=aZM!<*%<^jFJcpy@Frcd8B9hc&Bc)VnxOZtY{pnnMHHZ`ec}~Q0L#= zB|%}?XT0}3op3JoE&G;_mJK=xUgEc317a6aLqiu%5ich{RtY5LzK$-VemhQCi?YB|tMLy~RPiwa% zH#(TS_*=YXa4Dx9o*Of*6qxaS%rf-;&Lulxqc%{|SN<=rSsTX1)%dS9B_$TgdXGz& zI5O)ImU&)mydlp1W+5$4W~i+dSzKU^ zhK0&E<5VTaU!5^>8K2VREzyyQkXVP>ZrTa)N_@4;nYYj?w}QtzRm1hKem77VThuyI z6a`uQ3^(1&x%o%#H~+1fu2e#RgwybbL#FeM)spdgGiez_9yC6_oa>eGzq;5kLr}y6 zy#`lAYrs+^aTaamy2lid^U0{vyq?0FXFAFG#BkKhP&}QM^fge6hkac;zdFJrz_(iW znArR6B)Y`IH7CQ93}BJzMySr&3<|QT5Eccz@)1?Hx31i>r(!NNrWz#Q-3Nxp?J@w*%5U(jx7f6-S zFrKzZwb+h}GjBJnI%bJ~H*pa+#2Btlpj3t&e^8o{X6WXf{XWMG5q@UVM`uw52T!zk zTAJ)PZr;25!7z{h^unJ-W)zIbEmM&k`b&iGng3>y*8|M}PqUcY%q9;{F?DNl#siN9 z3d^~_mb5T-Xw20h2;eAzw55x+tu7=e5dN8$O-wio>5CRY_j(CdG2ok^u}ax(y>@|N zW#ULfrd_*p(c4qBBm~^$xL-MUyp6G_d3Jw|Kb6CphM;{>qY|&Yy`*bs(<%1ID4kpT zx$+ZC-PhALt$*Rn63xx>_`#7FJuLr8xs8^6VLA%g>bF}{JihSn^J?6+BFZ5wzEdPxd;n%1Z?NPCV&Qk~Z z7x!G2hw5PeD*PY(#{&O*3rv+Zoe1k_+BnGjLO%cX*I#1D(?Q}cj!0L4v#;yv@t2aK zlB%4dx}4Ho3&lGCC1t=}B^gCUfTAMnpoYl*L-6!+afb*0&xFvoud_}GlK)o%(%sY5 i59#RX{r_|B0u=B3A0eS@#jsP(Uq*Uh-J*w2-~1OlF=>GS literal 319228 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

    L{xCZ2N<>OE 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 VT?8TT?f_m!24- From 3426a047231c9eb10c54f924e2be0823a1ed55f5 Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 24 Aug 2026 21:27:23 +0800 Subject: [PATCH 097/115] Add EMF round-trip coverage --- src/docx/image/constants.py | 1 + src/docx/image/emf.py | 3 +-- tests/integration/test_word_roundtrip.py | 26 ++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/docx/image/constants.py b/src/docx/image/constants.py index 03fae585..be7e5fe0 100644 --- a/src/docx/image/constants.py +++ b/src/docx/image/constants.py @@ -101,6 +101,7 @@ class MIME_TYPE: """Image content types.""" BMP = "image/bmp" + EMF = "image/x-emf" GIF = "image/gif" JPEG = "image/jpeg" PNG = "image/png" diff --git a/src/docx/image/emf.py b/src/docx/image/emf.py index 771c549f..3bb95b96 100644 --- a/src/docx/image/emf.py +++ b/src/docx/image/emf.py @@ -13,7 +13,7 @@ class Emf(BaseImageHeader): @property def content_type(self): """ - MIME content type for this image, unconditionally `image/emf` for + MIME content type for this image, unconditionally `image/x-emf` for EMF images. """ return MIME_TYPE.EMF @@ -38,7 +38,6 @@ def from_stream(cls, stream): y1 = stream_rdr.read_long(20) frame = tuple(map(stream_rdr.read_long, (24, 28, 32, 36))) - size = x1 - x0, y1 - y0 xdpi = 2540.0 * (x1 - x0) / (frame[2] - frame[0]) ydpi = 2540.0 * (y1 - y0) / (frame[3] - frame[1]) diff --git a/tests/integration/test_word_roundtrip.py b/tests/integration/test_word_roundtrip.py index ef4ef061..369a4dd5 100644 --- a/tests/integration/test_word_roundtrip.py +++ b/tests/integration/test_word_roundtrip.py @@ -12,6 +12,7 @@ from docx import Document FIXTURE_DIR = Path(__file__).parent.parent / "fixtures" +TEST_FILE_DIR = Path(__file__).parent.parent / "test_files" A_NS = "http://schemas.openxmlformats.org/drawingml/2006/main" ASVG_NS = "http://schemas.microsoft.com/office/drawing/2016/SVG/main" @@ -115,6 +116,31 @@ def it_preserves_an_svg_image_and_its_png_fallback(self): assert f"word/{svg_target}" in package assert _content_type(package, f"/word/{svg_target}") == "image/svg+xml" + def it_creates_and_round_trips_an_emf_image_in_memory(self): + emf_blob = (TEST_FILE_DIR / "sonic.emf").read_bytes() + document = Document(io.BytesIO(_fixture("documents", "word-blank.docx").read_bytes())) + document.add_picture(io.BytesIO(emf_blob)) + + output = io.BytesIO() + document.save(output) + reopened = Document(io.BytesIO(output.getvalue())) + assert len(reopened.inline_shapes) == 1 + + round_trip_output = io.BytesIO() + reopened.save(round_trip_output) + with ZipFile(io.BytesIO(round_trip_output.getvalue())) as docx_package: + package = {name: docx_package.read(name) for name in docx_package.namelist()} + + document_xml = _xml(package, "word/document.xml") + blip = document_xml.find(f".//{{{A_NS}}}blip") + assert blip is not None + relationship_id = blip.get(f"{{{R_NS}}}embed") + assert relationship_id is not None + emf_target = _relationship_target(package, relationship_id) + assert emf_target.endswith(".emf") + assert package[f"word/{emf_target}"] == emf_blob + assert _content_type(package, f"/word/{emf_target}") == "image/x-emf" + def it_preserves_distinct_latin_and_east_asian_fonts(self): package = _round_trip(_fixture("fonts", "word-east-asian-fonts.docx")) document = _xml(package, "word/document.xml") From 9cfb1e29ba2e7cb00b18ea0b3b90821fb404d4a9 Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 24 Aug 2026 21:27:38 +0800 Subject: [PATCH 098/115] Complete Custom XML part lifecycle --- docs/user/custom-xml.rst | 10 ++++++- src/docx/opc/rel.py | 5 ++++ src/docx/parts/document.py | 18 +++++++++++ .../customxml/test_custom_xml_roundtrip.py | 30 +++++++++++++++++++ tests/opc/test_rel.py | 9 ++++++ 5 files changed, 71 insertions(+), 1 deletion(-) diff --git a/docs/user/custom-xml.rst b/docs/user/custom-xml.rst index 1cbbf01a..e0b8df9d 100644 --- a/docs/user/custom-xml.rst +++ b/docs/user/custom-xml.rst @@ -89,7 +89,15 @@ Delete a child by passing the element itself:: customers.delete_item(customer) The indexes in ``items`` can change after deletion. Removing an entire Custom -XML part is not currently provided by this API. +XML part uses the main document part:: + + document.part.delete_custom_xml_part(customers) + +The Custom XML part, its relationship from the main document, and any related +``itemPropsN.xml`` property part are omitted the next time the document is +saved. The deleted ``itemN.xml`` name becomes available for later additions. +Attempting to delete a part that is not related to the document, including a +part that has already been deleted, raises ``ValueError``. Existing relationships to Custom XML property parts, such as ``itemPropsN.xml``, are preserved during load/save round trips. diff --git a/src/docx/opc/rel.py b/src/docx/opc/rel.py index 3f70fe28..eaae3c1e 100644 --- a/src/docx/opc/rel.py +++ b/src/docx/opc/rel.py @@ -28,6 +28,11 @@ def add_relationship( self._target_parts_by_rId[rId] = target return rel + def __delitem__(self, rId: str) -> None: + """Remove the relationship and its cached target-part reference.""" + super().__delitem__(rId) + self._target_parts_by_rId.pop(rId, None) + def get_or_add(self, reltype: str, target_part: Part) -> _Relationship: """Return relationship of `reltype` to `target_part`, newly added if not already present in collection.""" diff --git a/src/docx/parts/document.py b/src/docx/parts/document.py index 442861cb..7422ef97 100644 --- a/src/docx/parts/document.py +++ b/src/docx/parts/document.py @@ -54,6 +54,24 @@ def add_header_part(self): rId = self.relate_to(header_part, RT.HEADER) return header_part, rId + def delete_custom_xml_part(self, part: CustomXmlPart) -> None: + """Delete a Custom XML part related to this document. + + Related Custom XML property parts are detached with the part and omitted from + the package when it is next saved. + """ + matching_rIds = [ + rId + for rId, rel in self.rels.items() + if rel.reltype == RT.CUSTOM_XML and not rel.is_external and rel.target_part is part + ] + if not matching_rIds: + raise ValueError(f"part '{part.partname}' is not related to this document") + + part.drop_rels(lambda rel: rel.reltype == RT.CUSTOM_XML_PROPS) + for rId in matching_rIds: + del self.rels[rId] + @property def comments(self) -> Comments: """|Comments| object providing access to the comments added to this document.""" diff --git a/tests/integration/customxml/test_custom_xml_roundtrip.py b/tests/integration/customxml/test_custom_xml_roundtrip.py index 70824204..52986397 100644 --- a/tests/integration/customxml/test_custom_xml_roundtrip.py +++ b/tests/integration/customxml/test_custom_xml_roundtrip.py @@ -88,3 +88,33 @@ def it_rejects_an_explicit_partname_collision(self): with pytest.raises(ValueError, match="part already exists at '/customXml/item1.xml'"): document.part.add_custom_xml_part("", file_name="item1") + + def it_round_trips_deleting_a_part_and_reuses_its_partname(self): + document = Document(io.BytesIO(FIXTURE.read_bytes())) + customers = _parts_by_name(document)["/customXml/item1.xml"] + + document.part.delete_custom_xml_part(customers) + replacement = document.part.add_custom_xml_part(f'') + assert str(replacement.partname) == "/customXml/item1.xml" + + output = io.BytesIO() + document.save(output) + reopened = Document(io.BytesIO(output.getvalue())) + reopened_parts = _parts_by_name(reopened) + + assert set(reopened_parts) == {"/customXml/item1.xml", "/customXml/item3.xml"} + assert reopened_parts["/customXml/item1.xml"].tag == f"{{{AUDIT_NS}}}audit" + with ZipFile(io.BytesIO(output.getvalue())) as package: + names = set(package.namelist()) + assert "customXml/itemProps1.xml" not in names + assert "customXml/_rels/item1.xml.rels" not in names + assert "customXml/itemProps3.xml" in names + assert "customXml/_rels/item3.xml.rels" in names + + def it_rejects_deleting_a_part_twice(self): + document = Document(io.BytesIO(FIXTURE.read_bytes())) + customers = _parts_by_name(document)["/customXml/item1.xml"] + document.part.delete_custom_xml_part(customers) + + with pytest.raises(ValueError, match="is not related to this document"): + document.part.delete_custom_xml_part(customers) diff --git a/tests/opc/test_rel.py b/tests/opc/test_rel.py index 9758ab1a..fccea6f1 100644 --- a/tests/opc/test_rel.py +++ b/tests/opc/test_rel.py @@ -106,6 +106,15 @@ def it_can_find_a_related_part_by_rId(self, rels_with_known_target_part): part = rels.related_parts[rId] assert part is known_target_part + def it_removes_the_cached_target_when_deleting_a_relationship(self): + rels = Relationships("/word") + target_part = Mock(name="target_part") + rels.add_relationship("reltype", target_part, "rId1") + + del rels["rId1"] + + assert "rId1" not in rels.related_parts + def it_raises_on_related_part_not_found(self, rels): with pytest.raises(KeyError): rels.related_parts["rId666"] From efa13d9f762ff8349aafc8293b744bf3aa534b6a Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 24 Aug 2026 21:44:19 +0800 Subject: [PATCH 099/115] Add in-memory document snapshots --- docs/user/documents.rst | 18 ++++++++++++++++ src/docx/document.py | 12 +++++++++++ tests/integration/test_word_roundtrip.py | 27 ++++++++++++++++++++++++ tests/test_document.py | 8 +++++++ 4 files changed, 65 insertions(+) diff --git a/docs/user/documents.rst b/docs/user/documents.rst index d3bff846..a0bf8de1 100644 --- a/docs/user/documents.rst +++ b/docs/user/documents.rst @@ -92,5 +92,23 @@ After saving, rewind the output stream before reading it or opening it again:: Always open ``.docx`` files in binary mode (``"rb"`` for reading and ``"wb"`` for writing). +Exporting and copying in memory +------------------------------- + +Use :meth:`Document.to_bytes ` when the complete +DOCX package needs to be uploaded, cached, returned over HTTP, or stored in a +database:: + + content = document.to_bytes() + +Use :meth:`Document.copy ` to create an independent +snapshot that can be modified without changing the source document:: + + customer_document = document.copy() + customer_document.add_paragraph("Customer-specific content") + +The copy has its own XML trees, parts, and relationships. Both operations stay +in memory and do not create temporary files. + Okay, so you've got a document open and are pretty sure you can save it somewhere later. Next step is to get some content in there ... diff --git a/src/docx/document.py b/src/docx/document.py index 8f52484f..1d46abcf 100644 --- a/src/docx/document.py +++ b/src/docx/document.py @@ -5,8 +5,10 @@ from __future__ import annotations +import io from typing import IO, TYPE_CHECKING, Iterator, List, Sequence +from docx.api import Document as open_document from docx.blkcntnr import BlockItemContainer from docx.enum.section import WD_SECTION from docx.enum.text import WD_BREAK @@ -182,6 +184,10 @@ def core_properties(self): """A |CoreProperties| object providing Dublin Core properties of document.""" return self._part.core_properties + def copy(self) -> Document: + """Return an independent in-memory snapshot of this document.""" + return open_document(io.BytesIO(self.to_bytes())) + @property def custom_properties(self) -> CustomProperties: """A |CustomProperties| object providing custom properties of document.""" @@ -249,6 +255,12 @@ def tables(self) -> List[Table]: """ return self._body.tables + def to_bytes(self) -> bytes: + """Serialize this document as a complete in-memory DOCX package.""" + with io.BytesIO() as stream: + self.save(stream) + return stream.getvalue() + @property def _block_width(self) -> Length: """A |Length| object specifying the space between margins in last section.""" diff --git a/tests/integration/test_word_roundtrip.py b/tests/integration/test_word_roundtrip.py index 369a4dd5..c6a0148b 100644 --- a/tests/integration/test_word_roundtrip.py +++ b/tests/integration/test_word_roundtrip.py @@ -73,6 +73,33 @@ def it_round_trips_a_minimal_word_document_in_memory(self): assert "word/styles.xml" in package assert not any(name.startswith("word/media/") for name in package) + def it_creates_independent_document_copies_from_one_snapshot(self): + source = Document( + io.BytesIO(_fixture("customxml", "multiple-custom-xml-parts.docx").read_bytes()) + ) + source.add_paragraph("Shared snapshot") + + document_b = source.copy() + document_c = source.copy() + document_d = source.copy() + document_b.add_paragraph("Version B") + document_c.add_paragraph("Version C") + document_d.part.custom_xml_parts[0].add_item("version", "D") + + assert source.part.package is not document_b.part.package + assert document_b.part.package is not document_c.part.package + assert document_c.part.package is not document_d.part.package + assert source.paragraphs[-1].text == "Shared snapshot" + assert document_b.paragraphs[-1].text == "Version B" + assert document_c.paragraphs[-1].text == "Version C" + assert document_d.paragraphs[-1].text == "Shared snapshot" + assert len(source.part.custom_xml_parts[0].items) == 2 + assert len(document_d.part.custom_xml_parts[0].items) == 3 + + reopened = Document(io.BytesIO(document_d.to_bytes())) + assert reopened.paragraphs[-1].text == "Shared snapshot" + assert reopened.part.custom_xml_parts[0].items[-1].text == "D" + def it_preserves_a_floating_picture(self): package = _round_trip(_fixture("drawing", "word-floating-picture.docx")) document = _xml(package, "word/document.xml") diff --git a/tests/test_document.py b/tests/test_document.py index 2a399b12..7088d02f 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -202,6 +202,14 @@ def it_can_save_the_document_to_a_file(self, document_part_: Mock): document_part_.save.assert_called_once_with("foobar.docx") + def it_can_serialize_the_document_to_bytes(self, document_part_: Mock): + document_part_.save.side_effect = lambda stream: stream.write(b"docx-package") + document = Document(cast(CT_Document, element("w:document")), document_part_) + + content = document.to_bytes() + + assert content == b"docx-package" + def it_provides_access_to_the_comments(self, document_part_: Mock, comments_: Mock): document_part_.comments = comments_ document = Document(cast(CT_Document, element("w:document")), document_part_) From e8c63e952117789928a197395dd04493d54c1d5d Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 24 Aug 2026 22:06:37 +0800 Subject: [PATCH 100/115] Complete Phase 0 memory APIs and policy --- README.md | 26 ++++--- docs/dev/upstream-maintenance.rst | 95 ++++++++++++++++++++++++ docs/index.rst | 2 +- docs/user/documents.rst | 13 +++- src/docx/api.py | 9 ++- tests/integration/test_word_roundtrip.py | 6 +- tests/test_api.py | 20 +++++ 7 files changed, 147 insertions(+), 24 deletions(-) create mode 100644 docs/dev/upstream-maintenance.rst diff --git a/README.md b/README.md index 645ad9b0..f8b57bd8 100644 --- a/README.md +++ b/README.md @@ -24,18 +24,19 @@ Use it when an application needs more than basic paragraphs and tables: custom d metadata, application-owned XML, vector images, floating pictures, East Asian fonts, or low-level package and relationship access. -## Features - -| Capability | Support | -| --- | --- | -| Documents, paragraphs, runs, tables, styles, sections, headers, and footers | ✓ | -| Custom document properties | ✓ | -| Custom XML parts | ✓ | -| SVG and EMF images | ✓ | -| Inline and floating pictures | ✓ | -| Independent ASCII, High ANSI, and East Asian font controls | ✓ | -| Low-level OPC parts and relationships | ✓ | -| File-path and in-memory stream processing | ✓ | +## Capability Matrix + +| Capability | Status | Primary API | +| --- | --- | --- | +| Documents, paragraphs, tables, styles, sections, headers, and footers | Stable | `Document()` and document object APIs | +| Custom document properties | Stable | `document.custom_properties` | +| Custom XML lifecycle | Stable | `add_custom_xml_part()`, `delete_custom_xml_part()` | +| SVG and EMF images | Stable | `add_picture()` | +| Inline and floating pictures | Stable | `add_picture()`, `add_float_picture()` | +| Latin and East Asian font controls | Stable | `run.font.name`, `run.font.hAnsi`, `run.font.eastAsia` | +| Low-level OPC parts and relationships | Stable | `document.part.package`, `part.rels` | +| In-memory read, export, and independent copies | Stable | `Document()`, `to_bytes()`, `copy()` | +| Package inspection, diff, and sanitization | Planned | — | ## Installation @@ -141,6 +142,7 @@ available through `Document.add_float_picture()` and `Run.add_float_picture()`. - [API reference](docs/index.rst#api-documentation) - [Custom properties](docs/user/custom-properties.rst) - [Custom XML](docs/user/custom-xml.rst) +- [Upstream maintenance](docs/dev/upstream-maintenance.rst) - [Release history](HISTORY.md) ## Quality and Testing diff --git a/docs/dev/upstream-maintenance.rst b/docs/dev/upstream-maintenance.rst new file mode 100644 index 00000000..3e9b6ddf --- /dev/null +++ b/docs/dev/upstream-maintenance.rst @@ -0,0 +1,95 @@ +Upstream maintenance +==================== + +``python-docx-oss`` evolves as an independent DOCX SDK. Its source, tests, +versioning, and releases are authoritative in this repository. The official +`python-docx repository `_ is an +upstream source of compatible APIs, bug fixes, and OPC/WordprocessingML +improvements; it is not the development repository for ``python-docx-oss``. + +Upstream baseline +----------------- + +The current upstream baseline is ``python-docx v1.2.0`` at commit +``e45454602b53e8e572b179ccf1c91093ec9f4ed7``. + +This baseline identifies the last official release whose changes have been +evaluated as a whole. It does not imply compatibility with every private or +internal upstream API. + +No local repository layout is required. A maintainer may obtain upstream source +using a temporary clone, a read-only Git remote, a release archive, or another +equivalent method. Maintenance instructions and project documentation must not +depend on sibling directories, personal filesystem paths, or local-only +branches. + +When to evaluate upstream +------------------------- + +Evaluate upstream changes when: + +* ``python-docx`` publishes a release; +* upstream fixes a security, data-loss, or document-compatibility issue; +* a supported downstream workflow needs a new standard API; or +* an upcoming ``python-docx-oss`` release needs a baseline refresh. + +Continuous synchronization with individual upstream commits is not required. + +Integration workflow +-------------------- + +#. Obtain the target upstream tag or commit and compare it with the recorded + baseline. +#. Review release notes and classify changes to public APIs, OPC packaging, + XML handling, templates, schemas, tests, and documentation. +#. Create a dedicated branch in ``python-docx-oss`` for the integration. The + branch name and the location used to obtain upstream source are not part of + the public maintenance contract. +#. Integrate the relevant changes as a reviewable change set. Preserve upstream + history when practical, but prefer a clear, auditable result over a blind + merge. +#. Resolve conflicts according to the compatibility rules below. +#. Run the full verification gates and review the package artifacts. +#. Update this baseline, compatibility notes, and ``HISTORY.md`` in the same + integration change. + +Compatibility and conflict rules +-------------------------------- + +Standard public ``python-docx`` behavior is preferred unless adopting it would +break an API intentionally supported by ``python-docx-oss``. An upstream +integration must preserve the supported capabilities documented in the +Capability Matrix and covered by the regression test suite. + +Compatibility with upstream private APIs is not guaranteed. Intentional public +API differences must be recorded in compatibility or divergence notes rather +than hidden in conflict-resolution commits. + +Verification gates +------------------ + +An upstream integration is complete only when the repository CI passes. This +includes: + +* unit, integration, and acceptance tests on all supported Python versions; +* lint, formatting, and scoped type checks; +* documentation and distribution builds; and +* real-DOCX round trips required by the Capability Matrix and regression test + suite. + +The resulting wheel and source distribution must contain the expected package +data and install without also installing the official ``python-docx`` +distribution, because both projects provide the ``docx`` import namespace. + +Recording the result +-------------------- + +For each completed baseline refresh, record: + +* the upstream tag and resolved commit; +* the material APIs and fixes adopted; +* intentionally omitted upstream changes and their rationale; and +* any new compatibility boundary visible to users. + +Temporary comparison checkouts, remotes, and branches are local implementation +details and are not part of the permanent project record. diff --git a/docs/index.rst b/docs/index.rst index 3922a5a8..42839cec 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -117,11 +117,11 @@ API Documentation api/shared api/enum/index - Contributor Guide ----------------- .. toctree:: :maxdepth: 1 + dev/upstream-maintenance dev/analysis/index diff --git a/docs/user/documents.rst b/docs/user/documents.rst index a0bf8de1..69fe51b6 100644 --- a/docs/user/documents.rst +++ b/docs/user/documents.rst @@ -67,13 +67,18 @@ Opening a file-like document |docx| can open a document from a so-called *file-like* object. It can also save to a file-like object. This can be handy when you want to get the source or target document over a network connection or from a database and don't want -to (or aren't allowed to) interact with the file system. A ``.docx`` package is -binary, so an in-memory stream must be an :class:`io.BytesIO` object:: - - from io import BytesIO +to (or aren't allowed to) interact with the file system. Raw DOCX bytes can be +opened directly:: from docx import Document + with open("foobar.docx", "rb") as file: + document = Document(file.read()) + +A binary file-like object such as :class:`io.BytesIO` is also supported:: + + from io import BytesIO + with open("foobar.docx", "rb") as file: source_stream = BytesIO(file.read()) document = Document(source_stream) diff --git a/src/docx/api.py b/src/docx/api.py index aea87645..a338dbbd 100644 --- a/src/docx/api.py +++ b/src/docx/api.py @@ -5,6 +5,7 @@ from __future__ import annotations +import io import os from typing import IO, TYPE_CHECKING, cast @@ -16,18 +17,20 @@ from docx.parts.document import DocumentPart -def Document(docx: str | IO[bytes] | None = None) -> DocumentObject: +def Document(docx: str | bytes | IO[bytes] | None = None) -> DocumentObject: """Return a |Document| object loaded from `docx`, where `docx` can be either a path - to a ``.docx`` file (a string) or a file-like object. + to a ``.docx`` file, raw DOCX bytes, or a binary file-like object. If `docx` is missing or ``None``, the built-in default document "template" is loaded. """ docx = _default_docx_path() if docx is None else docx + source_name = "" if isinstance(docx, bytes) else docx + docx = io.BytesIO(docx) if isinstance(docx, bytes) else docx document_part = cast("DocumentPart", Package.open(docx).main_document_part) if document_part.content_type != CT.WML_DOCUMENT_MAIN: tmpl = "file '%s' is not a Word file, content type is '%s'" - raise ValueError(tmpl % (docx, document_part.content_type)) + raise ValueError(tmpl % (source_name, document_part.content_type)) return document_part.document diff --git a/tests/integration/test_word_roundtrip.py b/tests/integration/test_word_roundtrip.py index c6a0148b..c462bdcc 100644 --- a/tests/integration/test_word_roundtrip.py +++ b/tests/integration/test_word_roundtrip.py @@ -74,9 +74,7 @@ def it_round_trips_a_minimal_word_document_in_memory(self): assert not any(name.startswith("word/media/") for name in package) def it_creates_independent_document_copies_from_one_snapshot(self): - source = Document( - io.BytesIO(_fixture("customxml", "multiple-custom-xml-parts.docx").read_bytes()) - ) + source = Document(_fixture("customxml", "multiple-custom-xml-parts.docx").read_bytes()) source.add_paragraph("Shared snapshot") document_b = source.copy() @@ -96,7 +94,7 @@ def it_creates_independent_document_copies_from_one_snapshot(self): assert len(source.part.custom_xml_parts[0].items) == 2 assert len(document_d.part.custom_xml_parts[0].items) == 3 - reopened = Document(io.BytesIO(document_d.to_bytes())) + reopened = Document(document_d.to_bytes()) assert reopened.paragraphs[-1].text == "Shared snapshot" assert reopened.part.custom_xml_parts[0].items[-1].text == "D" diff --git a/tests/test_api.py b/tests/test_api.py index 6b5d3ae0..58b9f7eb 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1,5 +1,7 @@ """Test suite for the docx.api module.""" +import io + import pytest from docx.api import Document as DocumentFactoryFn @@ -22,6 +24,18 @@ def it_opens_a_docx_file(self, Package_: Mock, document_: Mock): Package_.open.assert_called_once_with("foobar.docx") assert document is document_ + def it_opens_raw_docx_bytes(self, Package_: Mock, document_: Mock): + document_part = Package_.open.return_value.main_document_part + document_part.document = document_ + document_part.content_type = CT.WML_DOCUMENT_MAIN + + document = DocumentFactoryFn(b"docx-package") + + stream = Package_.open.call_args.args[0] + assert isinstance(stream, io.BytesIO) + assert stream.getvalue() == b"docx-package" + assert document is document_ + def it_opens_the_default_docx_if_none_specified( self, _default_docx_path_: Mock, Package_: Mock, document_: Mock ): @@ -41,6 +55,12 @@ def it_raises_on_not_a_Word_file(self, Package_: Mock): with pytest.raises(ValueError, match="file 'foobar.xlsx' is not a Word file,"): DocumentFactoryFn("foobar.xlsx") + def it_does_not_include_raw_bytes_in_a_not_Word_file_error(self, Package_: Mock): + Package_.open.return_value.main_document_part.content_type = "BOGUS" + + with pytest.raises(ValueError, match="file '' is not a Word file,"): + DocumentFactoryFn(b"sensitive-content") + # -- fixtures -------------------------------------------------------------------------------- @pytest.fixture From 4a2c344cab073733490248392ac341bc216b01f9 Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 24 Aug 2026 22:08:35 +0800 Subject: [PATCH 101/115] Document python-docx compatibility boundary --- README.md | 1 + docs/index.rst | 1 + docs/user/compatibility.rst | 48 +++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 docs/user/compatibility.rst diff --git a/README.md b/README.md index f8b57bd8..5fa47cab 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,7 @@ available through `Document.add_float_picture()` and `Run.add_float_picture()`. - [API reference](docs/index.rst#api-documentation) - [Custom properties](docs/user/custom-properties.rst) - [Custom XML](docs/user/custom-xml.rst) +- [python-docx compatibility](docs/user/compatibility.rst) - [Upstream maintenance](docs/dev/upstream-maintenance.rst) - [Release history](HISTORY.md) diff --git a/docs/index.rst b/docs/index.rst index 42839cec..9c6abd65 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -97,6 +97,7 @@ User Guide user/shapes user/custom-properties user/custom-xml + user/compatibility API Documentation diff --git a/docs/user/compatibility.rst b/docs/user/compatibility.rst new file mode 100644 index 00000000..86498f89 --- /dev/null +++ b/docs/user/compatibility.rst @@ -0,0 +1,48 @@ +python-docx compatibility +========================= + +``python-docx-oss`` and the official ``python-docx`` project share the +``docx`` import namespace and a common code lineage. They are separate Python +distributions with independent versions and release schedules. + +Compatibility target +-------------------- + +The current upstream baseline is ``python-docx v1.2.0`` at commit +``e45454602b53e8e572b179ccf1c91093ec9f4ed7``. + +Public APIs inherited from that baseline are compatibility targets unless an +intentional difference is documented. Compatibility with private modules, +private attributes, undocumented XML internals, or implementation details is +not guaranteed. + +Extensions provided by ``python-docx-oss`` are additive where practical. The +project's current supported and planned features are maintained in the +Capability Matrix rather than duplicated here. + +Distribution boundary +--------------------- + +Do not install ``python-docx`` and ``python-docx-oss`` into the same Python +environment. Both distributions provide the ``docx`` package, so installing +both can produce an environment whose imported files depend on installation +order. + +Applications should declare exactly one of the two distributions as a direct +dependency. Migrating an existing application normally does not require import +changes, but its use of undocumented upstream internals must be reviewed. + +Intentional differences +----------------------- + +An intentional difference is recorded when ``python-docx-oss`` changes a +public inherited API or its observable behavior. Each record must identify: + +* the affected public API; +* the behavior of the recorded upstream baseline; +* the ``python-docx-oss`` behavior and rationale; and +* any migration action required by callers. + +Additive APIs and capabilities do not require individual divergence records; +they belong in the API documentation and Capability Matrix. Upstream baseline +changes follow the :doc:`../dev/upstream-maintenance` policy. From da11c731d834d9ed8275681ebd9945e652923648 Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 24 Aug 2026 22:21:37 +0800 Subject: [PATCH 102/115] release: v0.2.0 --- HISTORY.md | 11 +++++++++++ src/docx/__init__.py | 2 +- src/docx/parts/customxml.py | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 0bd58b81..b0fff666 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,16 @@ ## Release History +**0.2.0 (2026-08-24)** + +- Added direct loading from raw DOCX bytes with ``Document(bytes)``. +- Added ``Document.to_bytes()`` for in-memory export and ``Document.copy()`` + for independent document snapshots. +- Added safe removal of Custom XML parts, including their document and property + relationships. +- Added real-document EMF round-trip coverage and corrected the EMF MIME type. +- Documented the capability matrix, upstream maintenance policy, and + compatibility boundary with official ``python-docx``. + **0.1.1 (2026-08-21)** - Added Python 3.14 support and CI coverage for Python 3.12 through 3.14. diff --git a/src/docx/__init__.py b/src/docx/__init__.py index 97d9e7c5..994792a5 100644 --- a/src/docx/__init__.py +++ b/src/docx/__init__.py @@ -13,7 +13,7 @@ if TYPE_CHECKING: from docx.opc.part import Part -__version__ = "0.1.1" +__version__ = "0.2.0" __all__ = ["Document"] diff --git a/src/docx/parts/customxml.py b/src/docx/parts/customxml.py index 45c4426e..5b9038dc 100644 --- a/src/docx/parts/customxml.py +++ b/src/docx/parts/customxml.py @@ -59,7 +59,7 @@ def items(self) -> list[etree._Element]: """ return self.element.getchildren() - def add_item(self, tag: str, text: str = "", **attrib): + def add_item(self, tag: str, text: str = "", **attrib: str) -> None: """ Add a child element to root. """ From f3229740102010b577f9628afee254b1577bf8a6 Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 24 Aug 2026 22:44:23 +0800 Subject: [PATCH 103/115] Use local Twine for PyPI releases --- .github/workflows/release.yml | 21 +++++++++------------ Makefile | 22 +++++++++++++++++----- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1d677665..93a2e717 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -43,16 +43,12 @@ jobs: - name: Run acceptance tests run: python -m behave --format progress --stop --tags=-wip - publish: - name: Publish to PyPI + package: + name: Verify release distributions needs: test runs-on: ubuntu-latest - environment: - name: pypi - url: https://pypi.org/project/python-docx-oss/ permissions: contents: read - id-token: write steps: - uses: actions/checkout@v5 @@ -66,14 +62,15 @@ jobs: run: | python -m pip install --upgrade build twine python -m build - python -m twine check dist/* + release_version="${GITHUB_REF_NAME#v}" + python -m twine check \ + "dist/python_docx_oss-${release_version}-py3-none-any.whl" \ + "dist/python_docx_oss-${release_version}.tar.gz" - name: Install and verify distribution run: | - python -m pip install --force-reinstall dist/*.whl - package_version="$(python -c 'import docx; print(docx.__version__)')" tag_version="${GITHUB_REF_NAME#v}" + python -m pip install --force-reinstall \ + "dist/python_docx_oss-${tag_version}-py3-none-any.whl" + package_version="$(python -c 'import docx; print(docx.__version__)')" test "$package_version" = "$tag_version" - - - name: Publish distributions - uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/Makefile b/Makefile index 2b2fb412..47f6e7cd 100644 --- a/Makefile +++ b/Makefile @@ -2,9 +2,12 @@ BEHAVE = behave MAKE = make PYTHON = python TWINE = $(PYTHON) -m twine +VERSION := $(shell sed -n 's/^__version__ = "\(.*\)"/\1/p' src/docx/__init__.py) +SDIST = dist/python_docx_oss-$(VERSION).tar.gz +WHEEL = dist/python_docx_oss-$(VERSION)-py3-none-any.whl .PHONY: accept build clean cleandocs coverage docs install opendocs sdist test -.PHONY: test-upload wheel +.PHONY: test-upload upload verify-release wheel help: @echo "Please use \`make ' where is one or more of" @@ -54,11 +57,20 @@ sdist: test: uv run pytest -x -test-upload: sdist wheel - uv run $(TWINE) upload --repository testpypi dist/* +test-upload: clean sdist wheel + uv run $(TWINE) check $(WHEEL) $(SDIST) + uv run $(TWINE) upload --repository testpypi $(WHEEL) $(SDIST) -upload: clean sdist wheel - uv run $(TWINE) upload dist/* +upload: verify-release + $(MAKE) clean + $(MAKE) sdist wheel + uv run $(TWINE) check $(WHEEL) $(SDIST) + uv run $(TWINE) upload $(WHEEL) $(SDIST) + +verify-release: + test -n "$(VERSION)" + test "$$(git rev-parse HEAD)" = "$$(git rev-parse v$(VERSION)^{})" + test -z "$$(git status --short)" wheel: uv build --wheel From d3b8a0b5ff91df64b4edc2488e9f942dc5fd61e8 Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 24 Aug 2026 22:54:30 +0800 Subject: [PATCH 104/115] Fix vulnerable dependencies --- pyproject.toml | 4 +- uv.lock | 282 +++++++++++++++++++++++++++---------------------- 2 files changed, 158 insertions(+), 128 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 605289d2..52864f34 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ classifiers = [ "Topic :: Office/Business :: Office Suites", "Topic :: Software Development :: Libraries", ] -dependencies = ["lxml>=3.1.0", "typing_extensions>=4.9.0"] +dependencies = ["lxml>=6.1.0", "typing_extensions>=4.9.0"] description = "Create, read, and update Microsoft Word .docx files." dynamic = ["version"] keywords = ["docx", "office", "openxml", "word"] @@ -41,7 +41,7 @@ dev = [ "behave>=1.2.6", "pyparsing>=3.2.3", "pyright>=1.1.401", - "pytest>=8.4.0", + "pytest>=9.0.3", "ruff>=0.11.13", "sphinx-book-theme", "tox>=4.26.0", diff --git a/uv.lock b/uv.lock index 5d15f5fc..ee7c9b1a 100644 --- a/uv.lock +++ b/uv.lock @@ -186,40 +186,40 @@ wheels = [ [[package]] name = "cryptography" -version = "46.0.4" +version = "50.0.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/78/19/f748958276519adf6a0c1e79e7b8860b4830dda55ccdf29f2719b5fc499c/cryptography-46.0.4.tar.gz", hash = "sha256:bfd019f60f8abc2ed1b9be4ddc21cfef059c841d86d710bb69909a688cbb8f59" } -wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/87/91/874b8910903159043b5c6a123b7e79c4559ddd1896e38967567942635778/cryptography-46.0.4-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5f14fba5bf6f4390d7ff8f086c566454bff0411f6d8aa7af79c88b6f9267aecc" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c0/35/690e809be77896111f5b195ede56e4b4ed0435b428c2f2b6d35046fbb5e8/cryptography-46.0.4-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:47bcd19517e6389132f76e2d5303ded6cf3f78903da2158a671be8de024f4cd0" }, - { url = "https://mirrors.aliyun.com/pypi/packages/1a/5b/a26407d4f79d61ca4bebaa9213feafdd8806dc69d3d290ce24996d3cfe43/cryptography-46.0.4-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:01df4f50f314fbe7009f54046e908d1754f19d0c6d3070df1e6268c5a4af09fa" }, - { url = "https://mirrors.aliyun.com/pypi/packages/2b/08/f83e2e0814248b844265802d081f2fac2f1cbe6cd258e72ba14ff006823a/cryptography-46.0.4-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:0a9ad24359fee86f131836a9ac3bffc9329e956624a2d379b613f8f8abaf5255" }, - { url = "https://mirrors.aliyun.com/pypi/packages/0a/05/19d849cf4096448779d2dcc9bb27d097457dac36f7273ffa875a93b5884c/cryptography-46.0.4-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:dc1272e25ef673efe72f2096e92ae39dea1a1a450dd44918b15351f72c5a168e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e6/89/f7bac81d66ba7cde867a743ea5b37537b32b5c633c473002b26a226f703f/cryptography-46.0.4-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:de0f5f4ec8711ebc555f54735d4c673fc34b65c44283895f1a08c2b49d2fd99c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a6/f7/6d43cbaddf6f65b24816e4af187d211f0bc536a29961f69faedc48501d8e/cryptography-46.0.4-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:3d425eacbc9aceafd2cb429e42f4e5d5633c6f873f5e567077043ef1b9bbf616" }, - { url = "https://mirrors.aliyun.com/pypi/packages/9e/4f/ebd0473ad656a0ac912a16bd07db0f5d85184924e14fc88feecae2492834/cryptography-46.0.4-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:91627ebf691d1ea3976a031b61fb7bac1ccd745afa03602275dda443e11c8de0" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d1/f7/7923886f32dc47e27adeff8246e976d77258fd2aa3efdd1754e4e323bf49/cryptography-46.0.4-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:2d08bc22efd73e8854b0b7caff402d735b354862f1145d7be3b9c0f740fef6a0" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f8/f5/559c25b77f40b6bf828eabaf988efb8b0e17b573545edb503368ca0a2a03/cryptography-46.0.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:078e5f06bd2fa5aea5a324f2a09f914b1484f1d0c2a4d6a8a28c74e72f65f2da" }, - { url = "https://mirrors.aliyun.com/pypi/packages/49/a1/551fa162d33074b660dc35c9bc3616fefa21a0e8c1edd27b92559902e408/cryptography-46.0.4-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:dce1e4f068f03008da7fa51cc7abc6ddc5e5de3e3d1550334eaf8393982a5829" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b0/6a/4d8d129a755f5d6df1bbee69ea2f35ebfa954fa1847690d1db2e8bca46a5/cryptography-46.0.4-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:2067461c80271f422ee7bdbe79b9b4be54a5162e90345f86a23445a0cf3fd8a2" }, - { url = "https://mirrors.aliyun.com/pypi/packages/43/ae/9f03d5f0c0c00e85ecb34f06d3b79599f20630e4db91b8a6e56e8f83d410/cryptography-46.0.4-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:829c2b12bbc5428ab02d6b7f7e9bbfd53e33efd6672d21341f2177470171ad8b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/8b/22/e0f9f2dae8040695103369cf2283ef9ac8abe4d51f68710bec2afd232609/cryptography-46.0.4-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:62217ba44bf81b30abaeda1488686a04a702a261e26f87db51ff61d9d3510abd" }, - { url = "https://mirrors.aliyun.com/pypi/packages/01/5b/6a43fcccc51dae4d101ac7d378a8724d1ba3de628a24e11bf2f4f43cba4d/cryptography-46.0.4-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:9c2da296c8d3415b93e6053f5a728649a87a48ce084a9aaf51d6e46c87c7f2d2" }, - { url = "https://mirrors.aliyun.com/pypi/packages/83/17/259409b8349aa10535358807a472c6a695cf84f106022268d31cea2b6c97/cryptography-46.0.4-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:df4a817fa7138dd0c96c8c8c20f04b8aaa1fac3bbf610913dcad8ea82e1bfd3f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/9c/fe/e4a1b0c989b00cee5ffa0764401767e2d1cf59f45530963b894129fd5dce/cryptography-46.0.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:b1de0ebf7587f28f9190b9cb526e901bf448c9e6a99655d2b07fff60e8212a82" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b3/81/ba8fd9657d27076eb40d6a2f941b23429a3c3d2f56f5a921d6b936a27bc9/cryptography-46.0.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9b4d17bc7bd7cdd98e3af40b441feaea4c68225e2eb2341026c84511ad246c0c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d8/cc/8f3224cbb2a928de7298d6ed4790f5ebc48114e02bdc9559196bfb12435d/cryptography-46.0.4-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8bf75b0259e87fa70bddc0b8b4078b76e7fd512fd9afae6c1193bcf440a4dbef" }, - { url = "https://mirrors.aliyun.com/pypi/packages/17/43/4a18faa7a872d00e4264855134ba82d23546c850a70ff209e04ee200e76f/cryptography-46.0.4-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3c268a3490df22270955966ba236d6bc4a8f9b6e4ffddb78aac535f1a5ea471d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ee/64/6651969409821d791ba12346a124f55e1b76f66a819254ae840a965d4b9c/cryptography-46.0.4-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:812815182f6a0c1d49a37893a303b44eaac827d7f0d582cecfc81b6427f22973" }, - { url = "https://mirrors.aliyun.com/pypi/packages/db/a7/20c5701e2cd3e1dfd7a19d2290c522a5f435dd30957d431dcb531d0f1413/cryptography-46.0.4-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a05177ff6296644ef2876fce50518dffb5bcdf903c85250974fc8bc85d54c0af" }, - { url = "https://mirrors.aliyun.com/pypi/packages/00/dc/3e16030ea9aa47b63af6524c354933b4fb0e352257c792c4deeb0edae367/cryptography-46.0.4-cp38-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:daa392191f626d50f1b136c9b4cf08af69ca8279d110ea24f5c2700054d2e263" }, - { url = "https://mirrors.aliyun.com/pypi/packages/42/c8/ad93f14118252717b465880368721c963975ac4b941b7ef88f3c56bf2897/cryptography-46.0.4-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:e07ea39c5b048e085f15923511d8121e4a9dc45cee4e3b970ca4f0d338f23095" }, - { url = "https://mirrors.aliyun.com/pypi/packages/03/c3/c90a2cb358de4ac9309b26acf49b2a100957e1ff5cc1e98e6c4996576710/cryptography-46.0.4-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:6bb5157bf6a350e5b28aee23beb2d84ae6f5be390b2f8ee7ea179cda077e1019" }, - { url = "https://mirrors.aliyun.com/pypi/packages/96/2c/8d7f4171388a10208671e181ca43cdc0e596d8259ebacbbcfbd16de593da/cryptography-46.0.4-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:dd5aba870a2c40f87a3af043e0dee7d9eb02d4aff88a797b48f2b43eff8c3ab4" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e9/23/cbb2036e450980f65c6e0a173b73a56ff3bccd8998965dea5cc9ddd424a5/cryptography-46.0.4-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:93d8291da8d71024379ab2cb0b5c57915300155ad42e07f76bea6ad838d7e59b" }, +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/de/41/6cbdcf9142d00fe82836fbb51e503e58088575cf7a0fe1dbff6695bf0840/cryptography-50.0.0.tar.gz", hash = "sha256:eeac2acb5a20ed25e0ad6d1df9891a520b78b404266b6d11778f25d5d691a6c9" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/57/ef/8f2df13c7216bcad3e1c74e07f6e193d93e998e114f524a53877c9af27ad/cryptography-50.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fd9192b7b70c573d7f214eb1ae35e00d359f6f5e4b27c7e21e30de1fc6204645" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d9/41/029086c34d91052fc3b88bcc8056f709a7c915c7a23b235a54eb800b1c97/cryptography-50.0.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:06a32a980526a6ab9a4b9bf8f7385800791e2bb960903cb6b530e4817509a3b7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7d/ff/b6ce0954962e7f7b969f850a883744197bb3910bdfd7b6da162eab7d9f68/cryptography-50.0.0-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:a1b30560f2acc95aa8b2e06e716a13dbfc97314747b80d9707e307f77b40d6b3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6b/72/a1116d683a6d7ece94590013882515de087edf9ef0e6292aae615a44df73/cryptography-50.0.0-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b42a28c1844fd9de8f3f7d540e36b66f3a9c83fceac7170ebc7a6a19edd9dcae" }, + { url = "https://mirrors.aliyun.com/pypi/packages/15/37/36a9c479bbe49acea2636c7fd3360d20f7b7e079c300352011c44850b181/cryptography-50.0.0-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:900131fafd8aead39ac7dd3a7e833be754c17a95cfd91221636949fe4eb0aa8a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/32/98/8a151d64367204cbc63ec65d37502f1d9c53cf4bfc6ec3c532614dbec60d/cryptography-50.0.0-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:07949c449a1abcf60d1ee6e88956d89404c7df3c8258f46589e912988e551987" }, + { url = "https://mirrors.aliyun.com/pypi/packages/da/3a/f05e32c99d440c9bb891ea0e36c9091891e36be5a9a87ab2ee6ea20729f6/cryptography-50.0.0-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:82148ec5bddac30b51a5b3c1945075f896fa022cb93f8e4a01e9f6ee95292c5f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ca/dc/bd72b26be8953f80625f63151efd38eee71c76ca6cf591c08ff34615a79e/cryptography-50.0.0-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1489e263a8048bb8b6a8bac662eb2d402ea5d2b7b4699b72f385f1e2772db105" }, + { url = "https://mirrors.aliyun.com/pypi/packages/27/20/c930314a2ab476d15dec966ec87e2e9637bb02b06106b12c0396c57bb603/cryptography-50.0.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:7cec5b856506da6defb290f30c9ee687d5f5e8cb0bd3f6459dde43b0b4fa40ef" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d4/67/91eb047e69c5e845f2f14b8a2e4a1aab0f283cb885531e9e22c8adb176bc/cryptography-50.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:19736989797678c6af1e55cd49055cdbcb55d8f6b5583ac5335f933aba9101dc" }, + { url = "https://mirrors.aliyun.com/pypi/packages/30/82/85f0f7425c856b9f96459411eb12e74ef72df9caf6f8f15bf23a33ff131f/cryptography-50.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:80b63928fa35083b33966ce1efb70e5b9607181e49dcd1c22c8c005e319f667f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1a/28/b555a365adff1cca2fbe7b9e487d68a40de6bc67ff2cb587473eb43de0e7/cryptography-50.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:d58c3db7cd6eed54e6c06744db55456b65ebd7492ddeae9c1e93cfca7aa857d3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/38/14/6120e5bd7c5aa022ad15424ba4d5c5269d0d9448ed4d55e492ea91e3c1c4/cryptography-50.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:11b74db56cdbe3cdee6e3f6982ecb70334fa10dce99ed58bf7894aaaa3b2a037" }, + { url = "https://mirrors.aliyun.com/pypi/packages/fa/71/190bf38c3ee2e0f8efc9860ae100c9df4169742eef274b91e7aa1cb133b9/cryptography-50.0.0-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:f59e38625469987d7ef6d495323c55e7db6c212eaf6112267e0d3b565a2e9c9f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3a/63/504ccfbbe61fd8aa983f7f146399cdf034c72c2fc55f5b2dfdcdcdb20c99/cryptography-50.0.0-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:ecfed7367f965a0328cfbdd70da860f15441f002f613185668c6e6ebf5a0ac11" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e5/45/8aae2972c520145377ea3559a605a899bebe227bf070b33cdb445929a9b9/cryptography-50.0.0-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:6ba6a53445bd3cfa809ef3ef5f1589aa6ba08784a1d962bf47d0940e871dab1c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7b/20/4fe50b619a48c2525cc46e2dbc1ac490708d704be5d467bdaac6dc955682/cryptography-50.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3f5735ffe4996d28b809371756219f5354864902a3b9e7c0b9ee87041209fc9c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/92/91/3a31366e183343d3703f8995c095f5734676bd6938118047e50fcf279eb4/cryptography-50.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:1b4a266766514614f8aa60416e71f2fc6e575d36e7bdc90f644fadb2f4b75b95" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ff/c6/7a6202a534e32103a285b7834a120869557fe198d51d7cfe59754c8bda9c/cryptography-50.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:910e1d2668e7de9648f2bcee30e180db2a6b15c30f887d7c4c93ddf96e3992e3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/85/4f/0fa8c2f4428198f15d9ff8d63400e27afbf94ce833f6108da1eb3753f945/cryptography-50.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a91296cb61e8df6f86d0c19cc4068228da256bf59bf86049fbd821084565327f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d1/63/54dd723490ba2dc09b299682c10b38db38f159728bcaae8c591b8af2f22d/cryptography-50.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:e722f16708d854fe924790e051061f6704a472c3bac347b6fd88033ea8dd0dc5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/46/c9/f60aed34c013f317f92817b6c171c2d22a78270fa41109bd4b08af26b194/cryptography-50.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:105110f43a471dbd0060b9c9516cb8a6a79233631a04cc2ba16f28323ac6e025" }, + { url = "https://mirrors.aliyun.com/pypi/packages/be/f3/f9a0173b139372c3a48ed98154b45cc6b9de17c789d5ab552e621c293609/cryptography-50.0.0-cp39-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:828743d939e9629bc267b8e2d08d8bb67cd4319c771a33d4b18b22dd8fb7440a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d8/36/83bb81f6e569bc38e1e4a7bc80f29b46bb9601920bc455fc8e888f5d5742/cryptography-50.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:2a8183b489dc1f7f80f135780fadc1108f14b31b8a40411c7a5b17425f65f28b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9c/f8/d97f9603efda3888187bfdb893f26c41be4735c10631d05d284ee6b047c4/cryptography-50.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:37fdb0d0111f1e2ff07139dfb79f1b49531f8e213c46f1163dd7642979b58c47" }, + { url = "https://mirrors.aliyun.com/pypi/packages/64/a2/4615c8f7d81a00b1d6e6afe19f694e1543582349fb5f4076f6cb5dc36485/cryptography-50.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c87f62a3d3b9888ed0fdde100ec06aa61ca9cd44bad9057d1dff9a516b5f5bb9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d2/1a/efcfb02f91407149a0dacffffab791f7e19bf6385f63b3666dc8b5e5c9c8/cryptography-50.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:65c2c3add92b45fd0709db8594536aea39c2a67af0e27ffcf049c498501140b7" }, ] [[package]] @@ -290,11 +290,11 @@ wheels = [ [[package]] name = "idna" -version = "3.11" +version = "3.19" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/5f/f7/abb373e5757eaec4b922b92f97ec8d6d7e057cf06778247604fbc4e7c3f3/idna-3.19.tar.gz", hash = "sha256:5e0811a4383b21dc5838069f801c4fb62113b7447663d2530d2bd6e77b49bf15" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea" }, + { url = "https://mirrors.aliyun.com/pypi/packages/57/b0/0e52c878c53f245edd3a11020f20979b3f490f245af532c7cae3027754b5/idna-3.19-py3-none-any.whl", hash = "sha256:815e7be7a7806d54abb586dc943addc79e8b2ee16915059658cbeff4b1b43bf4" }, ] [[package]] @@ -388,82 +388,112 @@ wheels = [ [[package]] name = "lxml" -version = "6.0.2" -source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/aa/88/262177de60548e5a2bfc46ad28232c9e9cbde697bd94132aeb80364675cb/lxml-6.0.2.tar.gz", hash = "sha256:cd79f3367bd74b317dda655dc8fcfa304d9eb6e4fb06b7168c5cf27f96e0cd62" } -wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/f3/c8/8ff2bc6b920c84355146cd1ab7d181bc543b89241cfb1ebee824a7c81457/lxml-6.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:a59f5448ba2ceccd06995c95ea59a7674a10de0810f2ce90c9006f3cbc044456" }, - { url = "https://mirrors.aliyun.com/pypi/packages/37/6f/9aae1008083bb501ef63284220ce81638332f9ccbfa53765b2b7502203cf/lxml-6.0.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e8113639f3296706fbac34a30813929e29247718e88173ad849f57ca59754924" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f1/ca/31fb37f99f37f1536c133476674c10b577e409c0a624384147653e38baf2/lxml-6.0.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a8bef9b9825fa8bc816a6e641bb67219489229ebc648be422af695f6e7a4fa7f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/da/87/f6cb9442e4bada8aab5ae7e1046264f62fdbeaa6e3f6211b93f4c0dd97f1/lxml-6.0.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:65ea18d710fd14e0186c2f973dc60bb52039a275f82d3c44a0e42b43440ea534" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c8/20/a7760713e65888db79bbae4f6146a6ae5c04e4a204a3c48896c408cd6ed2/lxml-6.0.2-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c371aa98126a0d4c739ca93ceffa0fd7a5d732e3ac66a46e74339acd4d334564" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a2/b0/7e64e0460fcb36471899f75831509098f3fd7cd02a3833ac517433cb4f8f/lxml-6.0.2-cp312-cp312-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:700efd30c0fa1a3581d80a748157397559396090a51d306ea59a70020223d16f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b9/e1/e5df362e9ca4e2f48ed6411bd4b3a0ae737cc842e96877f5bf9428055ab4/lxml-6.0.2-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c33e66d44fe60e72397b487ee92e01da0d09ba2d66df8eae42d77b6d06e5eba0" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c6/d1/232b3309a02d60f11e71857778bfcd4acbdb86c07db8260caf7d008b08f8/lxml-6.0.2-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:90a345bbeaf9d0587a3aaffb7006aa39ccb6ff0e96a57286c0cb2fd1520ea192" }, - { url = "https://mirrors.aliyun.com/pypi/packages/35/35/d955a070994725c4f7d80583a96cab9c107c57a125b20bb5f708fe941011/lxml-6.0.2-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:064fdadaf7a21af3ed1dcaa106b854077fbeada827c18f72aec9346847cd65d0" }, - { url = "https://mirrors.aliyun.com/pypi/packages/1e/be/667d17363b38a78c4bd63cfd4b4632029fd68d2c2dc81f25ce9eb5224dd5/lxml-6.0.2-cp312-cp312-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fbc74f42c3525ac4ffa4b89cbdd00057b6196bcefe8bce794abd42d33a018092" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ea/47/62c70aa4a1c26569bc958c9ca86af2bb4e1f614e8c04fb2989833874f7ae/lxml-6.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6ddff43f702905a4e32bc24f3f2e2edfe0f8fde3277d481bffb709a4cced7a1f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/bd/55/6ceddaca353ebd0f1908ef712c597f8570cc9c58130dbb89903198e441fd/lxml-6.0.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:6da5185951d72e6f5352166e3da7b0dc27aa70bd1090b0eb3f7f7212b53f1bb8" }, - { url = "https://mirrors.aliyun.com/pypi/packages/cf/e8/fd63e15da5e3fd4c2146f8bbb3c14e94ab850589beab88e547b2dbce22e1/lxml-6.0.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:57a86e1ebb4020a38d295c04fc79603c7899e0df71588043eb218722dabc087f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/76/47/b3ec58dc5c374697f5ba37412cd2728f427d056315d124dd4b61da381877/lxml-6.0.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:2047d8234fe735ab77802ce5f2297e410ff40f5238aec569ad7c8e163d7b19a6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/19/93/03ba725df4c3d72afd9596eef4a37a837ce8e4806010569bedfcd2cb68fd/lxml-6.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6f91fd2b2ea15a6800c8e24418c0775a1694eefc011392da73bc6cef2623b322" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c6/80/c06de80bfce881d0ad738576f243911fccf992687ae09fd80b734712b39c/lxml-6.0.2-cp312-cp312-win32.whl", hash = "sha256:3ae2ce7d6fedfb3414a2b6c5e20b249c4c607f72cb8d2bb7cc9c6ec7c6f4e849" }, - { url = "https://mirrors.aliyun.com/pypi/packages/f7/d7/0cdfb6c3e30893463fb3d1e52bc5f5f99684a03c29a0b6b605cfae879cd5/lxml-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:72c87e5ee4e58a8354fb9c7c84cbf95a1c8236c127a5d1b7683f04bed8361e1f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ea/7b/93c73c67db235931527301ed3785f849c78991e2e34f3fd9a6663ffda4c5/lxml-6.0.2-cp312-cp312-win_arm64.whl", hash = "sha256:61cb10eeb95570153e0c0e554f58df92ecf5109f75eacad4a95baa709e26c3d6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/53/fd/4e8f0540608977aea078bf6d79f128e0e2c2bba8af1acf775c30baa70460/lxml-6.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:9b33d21594afab46f37ae58dfadd06636f154923c4e8a4d754b0127554eb2e77" }, - { url = "https://mirrors.aliyun.com/pypi/packages/5d/f4/2a94a3d3dfd6c6b433501b8d470a1960a20ecce93245cf2db1706adf6c19/lxml-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6c8963287d7a4c5c9a432ff487c52e9c5618667179c18a204bdedb27310f022f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/25/2e/4efa677fa6b322013035d38016f6ae859d06cac67437ca7dc708a6af7028/lxml-6.0.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1941354d92699fb5ffe6ed7b32f9649e43c2feb4b97205f75866f7d21aa91452" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ce/0f/526e78a6d38d109fdbaa5049c62e1d32fdd70c75fb61c4eadf3045d3d124/lxml-6.0.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bb2f6ca0ae2d983ded09357b84af659c954722bbf04dea98030064996d156048" }, - { url = "https://mirrors.aliyun.com/pypi/packages/81/76/99de58d81fa702cc0ea7edae4f4640416c2062813a00ff24bd70ac1d9c9b/lxml-6.0.2-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eb2a12d704f180a902d7fa778c6d71f36ceb7b0d317f34cdc76a5d05aa1dd1df" }, - { url = "https://mirrors.aliyun.com/pypi/packages/b5/35/9e57d25482bc9a9882cb0037fdb9cc18f4b79d85df94fa9d2a89562f1d25/lxml-6.0.2-cp313-cp313-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:6ec0e3f745021bfed19c456647f0298d60a24c9ff86d9d051f52b509663feeb1" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a6/8e/cb99bd0b83ccc3e8f0f528e9aa1f7a9965dfec08c617070c5db8d63a87ce/lxml-6.0.2-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:846ae9a12d54e368933b9759052d6206a9e8b250291109c48e350c1f1f49d916" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d0/34/9e591954939276bb679b73773836c6684c22e56d05980e31d52a9a8deb18/lxml-6.0.2-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ef9266d2aa545d7374938fb5c484531ef5a2ec7f2d573e62f8ce722c735685fd" }, - { url = "https://mirrors.aliyun.com/pypi/packages/8d/27/b29ff065f9aaca443ee377aff699714fcbffb371b4fce5ac4ca759e436d5/lxml-6.0.2-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:4077b7c79f31755df33b795dc12119cb557a0106bfdab0d2c2d97bd3cf3dffa6" }, - { url = "https://mirrors.aliyun.com/pypi/packages/2b/9f/f756f9c2cd27caa1a6ef8c32ae47aadea697f5c2c6d07b0dae133c244fbe/lxml-6.0.2-cp313-cp313-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a7c5d5e5f1081955358533be077166ee97ed2571d6a66bdba6ec2f609a715d1a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/61/46/bb85ea42d2cb1bd8395484fd72f38e3389611aa496ac7772da9205bbda0e/lxml-6.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:8f8d0cbd0674ee89863a523e6994ac25fd5be9c8486acfc3e5ccea679bad2679" }, - { url = "https://mirrors.aliyun.com/pypi/packages/95/0c/443fc476dcc8e41577f0af70458c50fe299a97bb6b7505bb1ae09aa7f9ac/lxml-6.0.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:2cbcbf6d6e924c28f04a43f3b6f6e272312a090f269eff68a2982e13e5d57659" }, - { url = "https://mirrors.aliyun.com/pypi/packages/48/78/6ef0b359d45bb9697bc5a626e1992fa5d27aa3f8004b137b2314793b50a0/lxml-6.0.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dfb874cfa53340009af6bdd7e54ebc0d21012a60a4e65d927c2e477112e63484" }, - { url = "https://mirrors.aliyun.com/pypi/packages/ff/ea/e1d33808f386bc1339d08c0dcada6e4712d4ed8e93fcad5f057070b7988a/lxml-6.0.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:fb8dae0b6b8b7f9e96c26fdd8121522ce5de9bb5538010870bd538683d30e9a2" }, - { url = "https://mirrors.aliyun.com/pypi/packages/4f/47/eba75dfd8183673725255247a603b4ad606f4ae657b60c6c145b381697da/lxml-6.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:358d9adae670b63e95bc59747c72f4dc97c9ec58881d4627fe0120da0f90d314" }, - { url = "https://mirrors.aliyun.com/pypi/packages/76/04/5c5e2b8577bc936e219becb2e98cdb1aca14a4921a12995b9d0c523502ae/lxml-6.0.2-cp313-cp313-win32.whl", hash = "sha256:e8cd2415f372e7e5a789d743d133ae474290a90b9023197fd78f32e2dc6873e2" }, - { url = "https://mirrors.aliyun.com/pypi/packages/fe/0a/4643ccc6bb8b143e9f9640aa54e38255f9d3b45feb2cbe7ae2ca47e8782e/lxml-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:b30d46379644fbfc3ab81f8f82ae4de55179414651f110a1514f0b1f8f6cb2d7" }, - { url = "https://mirrors.aliyun.com/pypi/packages/31/ef/dcf1d29c3f530577f61e5fe2f1bd72929acf779953668a8a47a479ae6f26/lxml-6.0.2-cp313-cp313-win_arm64.whl", hash = "sha256:13dcecc9946dca97b11b7c40d29fba63b55ab4170d3c0cf8c0c164343b9bfdcf" }, - { url = "https://mirrors.aliyun.com/pypi/packages/03/15/d4a377b385ab693ce97b472fe0c77c2b16ec79590e688b3ccc71fba19884/lxml-6.0.2-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:b0c732aa23de8f8aec23f4b580d1e52905ef468afb4abeafd3fec77042abb6fe" }, - { url = "https://mirrors.aliyun.com/pypi/packages/c8/e8/c128e37589463668794d503afaeb003987373c5f94d667124ffd8078bbd9/lxml-6.0.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4468e3b83e10e0317a89a33d28f7aeba1caa4d1a6fd457d115dd4ffe90c5931d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/00/ce/74903904339decdf7da7847bb5741fc98a5451b42fc419a86c0c13d26fe2/lxml-6.0.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:abd44571493973bad4598a3be7e1d807ed45aa2adaf7ab92ab7c62609569b17d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/1f/d3/131dec79ce61c5567fecf82515bd9bc36395df42501b50f7f7f3bd065df0/lxml-6.0.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:370cd78d5855cfbffd57c422851f7d3864e6ae72d0da615fca4dad8c45d375a5" }, - { url = "https://mirrors.aliyun.com/pypi/packages/3a/ea/a43ba9bb750d4ffdd885f2cd333572f5bb900cd2408b67fdda07e85978a0/lxml-6.0.2-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:901e3b4219fa04ef766885fb40fa516a71662a4c61b80c94d25336b4934b71c0" }, - { url = "https://mirrors.aliyun.com/pypi/packages/60/23/6885b451636ae286c34628f70a7ed1fcc759f8d9ad382d132e1c8d3d9bfd/lxml-6.0.2-cp314-cp314-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:a4bf42d2e4cf52c28cc1812d62426b9503cdb0c87a6de81442626aa7d69707ba" }, - { url = "https://mirrors.aliyun.com/pypi/packages/48/5b/fc2ddfc94ddbe3eebb8e9af6e3fd65e2feba4967f6a4e9683875c394c2d8/lxml-6.0.2-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2c7fdaa4d7c3d886a42534adec7cfac73860b89b4e5298752f60aa5984641a0" }, - { url = "https://mirrors.aliyun.com/pypi/packages/29/9c/47293c58cc91769130fbf85531280e8cc7868f7fbb6d92f4670071b9cb3e/lxml-6.0.2-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:98a5e1660dc7de2200b00d53fa00bcd3c35a3608c305d45a7bbcaf29fa16e83d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/9b/da/ba6eceb830c762b48e711ded880d7e3e89fc6c7323e587c36540b6b23c6b/lxml-6.0.2-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:dc051506c30b609238d79eda75ee9cab3e520570ec8219844a72a46020901e37" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a5/24/7be3f82cb7990b89118d944b619e53c656c97dc89c28cfb143fdb7cd6f4d/lxml-6.0.2-cp314-cp314-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8799481bbdd212470d17513a54d568f44416db01250f49449647b5ab5b5dccb9" }, - { url = "https://mirrors.aliyun.com/pypi/packages/1b/bd/dcfb9ea1e16c665efd7538fc5d5c34071276ce9220e234217682e7d2c4a5/lxml-6.0.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9261bb77c2dab42f3ecd9103951aeca2c40277701eb7e912c545c1b16e0e4917" }, - { url = "https://mirrors.aliyun.com/pypi/packages/21/04/a60b0ff9314736316f28316b694bccbbabe100f8483ad83852d77fc7468e/lxml-6.0.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:65ac4a01aba353cfa6d5725b95d7aed6356ddc0a3cd734de00124d285b04b64f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d6/bd/7d54bd1846e5a310d9c715921c5faa71cf5c0853372adf78aee70c8d7aa2/lxml-6.0.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:b22a07cbb82fea98f8a2fd814f3d1811ff9ed76d0fc6abc84eb21527596e7cc8" }, - { url = "https://mirrors.aliyun.com/pypi/packages/fd/32/5643d6ab947bc371da21323acb2a6e603cedbe71cb4c99c8254289ab6f4e/lxml-6.0.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:d759cdd7f3e055d6bc8d9bec3ad905227b2e4c785dc16c372eb5b5e83123f48a" }, - { url = "https://mirrors.aliyun.com/pypi/packages/33/da/34c1ec4cff1eea7d0b4cd44af8411806ed943141804ac9c5d565302afb78/lxml-6.0.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:945da35a48d193d27c188037a05fec5492937f66fb1958c24fc761fb9d40d43c" }, - { url = "https://mirrors.aliyun.com/pypi/packages/82/57/4eca3e31e54dc89e2c3507e1cd411074a17565fa5ffc437c4ae0a00d439e/lxml-6.0.2-cp314-cp314-win32.whl", hash = "sha256:be3aaa60da67e6153eb15715cc2e19091af5dc75faef8b8a585aea372507384b" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e3/e0/c96cf13eccd20c9421ba910304dae0f619724dcf1702864fd59dd386404d/lxml-6.0.2-cp314-cp314-win_amd64.whl", hash = "sha256:fa25afbadead523f7001caf0c2382afd272c315a033a7b06336da2637d92d6ed" }, - { url = "https://mirrors.aliyun.com/pypi/packages/d5/5d/b3f03e22b3d38d6f188ef044900a9b29b2fe0aebb94625ce9fe244011d34/lxml-6.0.2-cp314-cp314-win_arm64.whl", hash = "sha256:063eccf89df5b24e361b123e257e437f9e9878f425ee9aae3144c77faf6da6d8" }, - { url = "https://mirrors.aliyun.com/pypi/packages/5e/5c/42c2c4c03554580708fc738d13414801f340c04c3eff90d8d2d227145275/lxml-6.0.2-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:6162a86d86893d63084faaf4ff937b3daea233e3682fb4474db07395794fa80d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/bf/4f/12df843e3e10d18d468a7557058f8d3733e8b6e12401f30b1ef29360740f/lxml-6.0.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:414aaa94e974e23a3e92e7ca5b97d10c0cf37b6481f50911032c69eeb3991bba" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e4/0c/9dc31e6c2d0d418483cbcb469d1f5a582a1cd00a1f4081953d44051f3c50/lxml-6.0.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:48461bd21625458dd01e14e2c38dd0aea69addc3c4f960c30d9f59d7f93be601" }, - { url = "https://mirrors.aliyun.com/pypi/packages/e7/2b/9b870c6ca24c841bdd887504808f0417aa9d8d564114689266f19ddf29c8/lxml-6.0.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:25fcc59afc57d527cfc78a58f40ab4c9b8fd096a9a3f964d2781ffb6eb33f4ed" }, - { url = "https://mirrors.aliyun.com/pypi/packages/bf/0c/4f5f2a4dd319a178912751564471355d9019e220c20d7db3fb8307ed8582/lxml-6.0.2-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5179c60288204e6ddde3f774a93350177e08876eaf3ab78aa3a3649d43eb7d37" }, - { url = "https://mirrors.aliyun.com/pypi/packages/12/64/554eed290365267671fe001a20d72d14f468ae4e6acef1e179b039436967/lxml-6.0.2-cp314-cp314t-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:967aab75434de148ec80597b75062d8123cadf2943fb4281f385141e18b21338" }, - { url = "https://mirrors.aliyun.com/pypi/packages/7a/31/1d748aa275e71802ad9722df32a7a35034246b42c0ecdd8235412c3396ef/lxml-6.0.2-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d100fcc8930d697c6561156c6810ab4a508fb264c8b6779e6e61e2ed5e7558f9" }, - { url = "https://mirrors.aliyun.com/pypi/packages/8f/41/2c11916bcac09ed561adccacceaedd2bf0e0b25b297ea92aab99fd03d0fa/lxml-6.0.2-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ca59e7e13e5981175b8b3e4ab84d7da57993eeff53c07764dcebda0d0e64ecd" }, - { url = "https://mirrors.aliyun.com/pypi/packages/99/05/4e5c2873d8f17aa018e6afde417c80cc5d0c33be4854cce3ef5670c49367/lxml-6.0.2-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:957448ac63a42e2e49531b9d6c0fa449a1970dbc32467aaad46f11545be9af1d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/0f/c9/dcc2da1bebd6275cdc723b515f93edf548b82f36a5458cca3578bc899332/lxml-6.0.2-cp314-cp314t-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b7fc49c37f1786284b12af63152fe1d0990722497e2d5817acfe7a877522f9a9" }, - { url = "https://mirrors.aliyun.com/pypi/packages/9c/e2/5172e4e7468afca64a37b81dba152fc5d90e30f9c83c7c3213d6a02a5ce4/lxml-6.0.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e19e0643cc936a22e837f79d01a550678da8377d7d801a14487c10c34ee49c7e" }, - { url = "https://mirrors.aliyun.com/pypi/packages/a5/b3/15461fd3e5cd4ddcb7938b87fc20b14ab113b92312fc97afe65cd7c85de1/lxml-6.0.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:1db01e5cf14345628e0cbe71067204db658e2fb8e51e7f33631f5f4735fefd8d" }, - { url = "https://mirrors.aliyun.com/pypi/packages/05/33/f310b987c8bf9e61c4dd8e8035c416bd3230098f5e3cfa69fc4232de7059/lxml-6.0.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:875c6b5ab39ad5291588aed6925fac99d0097af0dd62f33c7b43736043d4a2ec" }, - { url = "https://mirrors.aliyun.com/pypi/packages/70/ff/51c80e75e0bc9382158133bdcf4e339b5886c6ee2418b5199b3f1a61ed6d/lxml-6.0.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:cdcbed9ad19da81c480dfd6dd161886db6096083c9938ead313d94b30aadf272" }, - { url = "https://mirrors.aliyun.com/pypi/packages/56/4d/4856e897df0d588789dd844dbed9d91782c4ef0b327f96ce53c807e13128/lxml-6.0.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:80dadc234ebc532e09be1975ff538d154a7fa61ea5031c03d25178855544728f" }, - { url = "https://mirrors.aliyun.com/pypi/packages/0f/85/86766dfebfa87bea0ab78e9ff7a4b4b45225df4b4d3b8cc3c03c5cd68464/lxml-6.0.2-cp314-cp314t-win32.whl", hash = "sha256:da08e7bb297b04e893d91087df19638dc7a6bb858a954b0cc2b9f5053c922312" }, - { url = "https://mirrors.aliyun.com/pypi/packages/fe/1a/b248b355834c8e32614650b8008c69ffeb0ceb149c793961dd8c0b991bb3/lxml-6.0.2-cp314-cp314t-win_amd64.whl", hash = "sha256:252a22982dca42f6155125ac76d3432e548a7625d56f5a273ee78a5057216eca" }, - { url = "https://mirrors.aliyun.com/pypi/packages/92/aa/df863bcc39c5e0946263454aba394de8a9084dbaff8ad143846b0d844739/lxml-6.0.2-cp314-cp314t-win_arm64.whl", hash = "sha256:bb4c1847b303835d89d785a18801a883436cdfd5dc3d62947f9c49e24f0f5a2c" }, +version = "6.1.2" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ad/a9/970b8fa0ecc4fbf1dfaed0d89bbc1fc1421b25ec26a2038c91e872dc6c8e/lxml-6.1.2.tar.gz", hash = "sha256:1055241852f2b02068af4a625a5d32c087db193c12251928af2562ecd2239f18" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/ee/a4/55eb54507073089ab27743c5da2113c84f0d0b1715b33175fdd943c9652d/lxml-6.1.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:7d506bdba580ecb1a6ad2e2b5c49445e66d3e1f95894885739094393a1aad237" }, + { url = "https://mirrors.aliyun.com/pypi/packages/bc/bf/6332f45d78da385bb01d5cac3fe4acda19f025d1307cbc7ad538355fecbb/lxml-6.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:12acd337d2821cb8b9247dfe4b7aa2f2769a3df5ae8511b7e550df42b8f4d3c3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/68/e0/21fba0fe74d417fbe976903ae6bc77e92cdce01aae7b636abd87756f4588/lxml-6.1.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5078ff51e6316c0f75ea8127c2cd24374747fb351f62fb93d1761f8ae5a04a40" }, + { url = "https://mirrors.aliyun.com/pypi/packages/de/e5/ce3e885264fdd0bdcb6b49c1ea1842f94281b39e4ff956099e8d57532c60/lxml-6.1.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9477e14217c212e6023c994a71a1a349db19b0e10fd5bf189666b281ae63b1fd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e6/b6/990a8446c488c70fa25681e150de94b7bf2eaaf387e374d195ab3c8faafb/lxml-6.1.2-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:261d98065326676d7253882db0198d0aa06748d7ee0443367acf10b148273f99" }, + { url = "https://mirrors.aliyun.com/pypi/packages/bb/6a/f70f41363dae27e3bfd6224b128f5ba150874bd32ca4938552930ffa33b0/lxml-6.1.2-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0666943ee1576fa890a6dc6316ef42e8241b5dd56f67bc5475acb2ac298c6ca9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3d/e0/a65b64f34d556925faef2c4f14167d58c571bc15a3e1f2bba71138830562/lxml-6.1.2-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:04cf9e3f4ee9cab9d9ba05401bef8668840fa9620fcd4d8e85a2d2fd0b0fa960" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c6/a9/471552e015e954fc9d960aa27c3d67ebf489683d03f033399a790417c67c/lxml-6.1.2-cp312-cp312-manylinux_2_28_i686.whl", hash = "sha256:9429d2371d406344ed1da5b5686d9412e74137c07b0171278368ff704f470ed5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d7/0f/bc6248fbec2cc416f102b1267f1567e07510f6fa909bbe8cd2a22d6fb78e/lxml-6.1.2-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:eff128ffdc093cc6317955934ad9751105d37ed8dbca3ff4ccd751af6be37185" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a9/3f/cec859f50e63f1fa338fab43d2362d7543e1237f2475960d8ab0769de0eb/lxml-6.1.2-cp312-cp312-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ba58574d710b82ead7cbedea01cac3e110bc3ef82d4731519b74a2c11f7cf5e9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7c/d9/2ced0cf2967115f92a1b8b3ae6bd18763abc3ebef88c98cf25145fda396c/lxml-6.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:52f6d4dff133c9778a24e9a2cfc1608930b15869866171aacc5131b5a418a003" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d5/f5/4f07386d3c88673daeec3b8cc09a2a4d39fa01c1fc49009791b0746d97fa/lxml-6.1.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:8807998c1023d1e9d60e02500f90e85a0752dbc0b670989806bba87b82dd5b42" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9a/5a/f4fe3ecbc189f48fba2547c5db5c940a10151d3e86b856a60a533a77e816/lxml-6.1.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:2170d0a280c877b6e2dc6738217db947be35dd8cf09ca458b355aa1bab2a9e70" }, + { url = "https://mirrors.aliyun.com/pypi/packages/92/c4/f586aa1bf27bfbace2dfdbb704da5c52f0bdece8ee440c8fb4946c940b2e/lxml-6.1.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:c67f3c1278f942e97d8665c2a690324aaea5137de16f056583a21f0ac706177f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/18/a1/677494bbaef4d6db5e4633af817414f478865850b55c03ae4bf70fa7b8ca/lxml-6.1.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:093fbf547d0f3ca02705381f795a050fbb58988be4aac7f79f99f280c4082313" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5a/71/b71425b8764d4cb7c92eb970483be7d5610dce2a6316242b5aaae7d260be/lxml-6.1.2-cp312-cp312-win32.whl", hash = "sha256:be365ce8d2d411cf2fb573747684b4fd470fa6224e0094d9d5a21155acc369d3" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1b/fb/909584e16d2148c1a252cc2c32dd99fe0e2682459c586d3d7a192e74a0ae/lxml-6.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:b97153ca609b434b712ddfb92cd6af101a7045a7724c542258bd4727a344472f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5f/8d/41207c9212caad0b52749e34739fb9bfab67486729f52a8fe9bd9266fee6/lxml-6.1.2-cp312-cp312-win_arm64.whl", hash = "sha256:7feb72424f19a893ae4f3373c7aae821b1aacb6076b708915c651f0683a97c49" }, + { url = "https://mirrors.aliyun.com/pypi/packages/61/2a/e9651f47a31a60b5cae031abc23391ed9aa30c8fc07571d1a38f58d6d770/lxml-6.1.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:351318f5c0eb7fcab5b4fdb507c6f88fb2c4b5e67784c7e5911448c91fffb5d4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/61/87/a8098abaf35118767d1703b84c98940a5d833064e0eca39a00ecfe9840ab/lxml-6.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c0edde95e4b4278dcc0175eda06dc8aa2631ad9f83ae5dbdbc4f0925e200b0b0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/93/cc/fe74d1def7f4fb967c4a825608a074d4dbdbb871b0d6bd59c6ed07d67868/lxml-6.1.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a8326e24ae6c3a6bfb03fa8b4793f9a5d804c125228aa067f652b0428e31b87c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b7/ad/b96e6ca926e26726a99aa643602aac7411ecc1731ddb1b25af8cc57edfcd/lxml-6.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7c534ed898413f439b048130011e99a4245ee13d62d431f6b4f7f2484d02a93a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d2/84/616f5d3b7cd086fcfba3e5add6fccda67f976c1c753ae9ed7bbd317cb9be/lxml-6.1.2-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2e37fe49fe2d5aa40a2cb1cc8176673ad7de0d124e6f4a509d9318f5979c7871" }, + { url = "https://mirrors.aliyun.com/pypi/packages/80/88/d5b453a8d083483c9442ad7f5ac5c560796022eb5c80d60b65d75e449236/lxml-6.1.2-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9b52ea73a37fc64aa3357ff8607801d46dd170506d3cf8253a91a1d91639d4f9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/71/45/31e5aa4d4bae024908ba1d03480c7425cf027a28b7e5c88d1b7202bd80cc/lxml-6.1.2-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e8b9a92652e75e7731309ea51db5dee892eef414ce70a6ec3441e5d36bf5189f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f5/5a/2627912420df8b2d31ba3014da5539f15ec85add01d42048864ffefda516/lxml-6.1.2-cp313-cp313-manylinux_2_28_i686.whl", hash = "sha256:9088da25ecd609965f838d89fda0465a905b48f4dd90331db9845518f2177372" }, + { url = "https://mirrors.aliyun.com/pypi/packages/16/86/54ac0f529b22a8f12313726dd49e12961bb46471d9028cc28d2a29408f0b/lxml-6.1.2-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:0349321a0537d4fdbebb2af06dd1b64676132c72e2ae250de8cdb58f8c43019c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3a/42/ffcdc6e4519be90df907cdae7e88409efb25d823ae4de8846f737dae1884/lxml-6.1.2-cp313-cp313-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b20440e578d269c5e8a722ab602ddd0f0cedb8b080006b3f936da9991a593d3b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/68/49/5b1d7ab35f013f1127ec48f3108319f58b65b00d5cb26f215adbe86eadfb/lxml-6.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7766e525282dd38fd89567311323e441996eb958e8e816d16b38f782e3aecd2a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b0/57/1cf049d054189b55c8fe8012269234f6602256949b69cd3ba80608a88219/lxml-6.1.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:9221442682c27417f10fe11184ea4cce174b25ab52465570b1f3ee3f85f320fa" }, + { url = "https://mirrors.aliyun.com/pypi/packages/d5/ad/064488a8fa60e639fd773e421a18bf17541d02a95fbf36238ad7c65f69d4/lxml-6.1.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:75530642d8471327e691ab9b0513a5f9c77f38871014ceda40f51bb51765c0a1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/85/bb/120e56f3cf1c149bb3b014278fb86d0a6dd552403981081f0ee0a0a57be7/lxml-6.1.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:678e35f1cbca98f55107511ee21a60568535c950f3c2371819bd64504c980d20" }, + { url = "https://mirrors.aliyun.com/pypi/packages/b1/2c/7d49aab893c128671a3276580074cce4c002896145b8dd2893da79633bca/lxml-6.1.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5c2bae42b3a09f977330a08f4a8fe72aec58c4bdb89069d3fe7272a71d885881" }, + { url = "https://mirrors.aliyun.com/pypi/packages/72/28/ddea3aa1fa9acfd384fe34d4a2a93eecc07541dd2d922fa9b140c60d8014/lxml-6.1.2-cp313-cp313-win32.whl", hash = "sha256:5848f3de6a8de8a93cff9f068134393ff5fa69ac2a04399f7d49cd67c61c348c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1b/7a/96bac167538748cae2544335855f812fa33e49a9a67bc8b8520dcbd592bd/lxml-6.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:6cb0c87421946030b92b558be416852780a912454e3dcba0998e4497c9c588d5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0a/24/9498fa3c84135956e5ef55ea4d8bd11e999e381f7f210fb6f8c6a980ef03/lxml-6.1.2-cp313-cp313-win_arm64.whl", hash = "sha256:648861c19b775b89ebefa14586f85090b10163367476d77f242c4131c835ce73" }, + { url = "https://mirrors.aliyun.com/pypi/packages/27/b5/728b0578791b397ace8d1b101c8b3fe10f36043542f7bb85f82d8bdc3f50/lxml-6.1.2-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:d50a44113fe6800dcc8a859332b823a4735b1e6ae1b0063882e4cca569ec3e29" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3c/6b/49209fa6225c15c48a30061f03d3aba75e3c19634813b88bf83b88c525ed/lxml-6.1.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fa813b0247d0543a563b993ac3dba6168eef59e3a61448432cf5453300c2412b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/20/86/80bae4e8bc2eed9d6f017701a3d86fdea56936218efa738911d0b76aa7f4/lxml-6.1.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d858e718b94033ab4b67e4a58fe3114c65bae01ae2314a62fb39ae8897ed4324" }, + { url = "https://mirrors.aliyun.com/pypi/packages/70/ce/4782caee7a22959c1ac67cb46495e03912c22a4ba7d20c163496a519e815/lxml-6.1.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e3b666f57a5d81562f38c766c762416b0f6eb58a00590546911514b48412abd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/32/21/f120967cc43b54e05512dff0c39726b832c836195d30f41f88733ef36ac8/lxml-6.1.2-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:26ff164c6629e5c4d11c9e55d5ea3d6eed0be2a420eee1f55cbce6e2c23e231a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/61/ba/8005e9f47598e3ec5c18312c77f94e889580027616678848405c6aeba5de/lxml-6.1.2-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:962c12b51d0b164f12569af225dea57568477e24a845b96eaccbef6c07e4cc03" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6a/ba/add33b3c7ce51462cf7a4637bcfec2eaa258364d6015b989dd7d1216e6a6/lxml-6.1.2-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:47e367dfe341521426692819803e260d0673899c0ff611f14af978d725e2c999" }, + { url = "https://mirrors.aliyun.com/pypi/packages/05/b3/a43012748fb861c914c5eac1c1a3bad44282e767499cd02280d4d1edf092/lxml-6.1.2-cp314-cp314-manylinux_2_28_i686.whl", hash = "sha256:92c2b366028ac01e90399e6d17734ce6e4f4aeddd8ba75fbaf80ea11d6c6d645" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8b/cb/813021d9a445713b8d758b9e5eae2ed392cd598d9f119d9b053b37c2ab93/lxml-6.1.2-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:7e81fc065ede5d58dd0bf0912025aee1bd04c52c2affd61fdb93226a97ce2fc6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/17/c9/1155299f4577bebf3c280497534a73e4b8ad8cab3b96074731ad10949d4e/lxml-6.1.2-cp314-cp314-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:633ac039cb32366dd5935868e041e385875c017b8cd54ea56aeee3fe29ca5935" }, + { url = "https://mirrors.aliyun.com/pypi/packages/25/6e/d76e58384b378b877e140e25b9a9835da00035f81ff70cbe943a3749bf27/lxml-6.1.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2f3194777c0d05945ac91d8594be25d2679d1d826e01e1fc90bae568ff3a547b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f3/b7/898013c0f8891481d0624ab3bd5dd8c8ff827232dfee2a5d1f8bf970a7cc/lxml-6.1.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:1133bd969f2bfcc6b0c0cf7cdf5f2631e62b23fa2471ee8bd44f6ab73554ee9a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c3/47/efb53c4d7b655831c03317a450d9da439b0829c61f34d9d4fe7c863445d6/lxml-6.1.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:1edca8f4a92b94e873093df959f141d388f2141fcad0c47598442fb4730ef57a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/da/0a/0ff36a584cbba14a71326ee8a5300694400f0b97927d1f90a87d95b17d4a/lxml-6.1.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:8512b3775d68994dd1d6d533161e0a214f2ad9c634659d34a99c98e86c6c3d68" }, + { url = "https://mirrors.aliyun.com/pypi/packages/8f/9e/303717a1aa56d4bd775c91936717d3c9e8d999a8e8b68b00979c4c1f93d0/lxml-6.1.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:a5005c0c9e4d749a76a2ff8bd5918a8bb248df8e08e73a55654b9f79c9cd1e2b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ad/c2/2ae7cb97089eb86bf0689516db3cf280a007b6145853d2a0235a1f01683d/lxml-6.1.2-cp314-cp314-win32.whl", hash = "sha256:e17e2c30e27f56da5551e7a425888b45f013e940b99ab07d125a1c33f77a4605" }, + { url = "https://mirrors.aliyun.com/pypi/packages/77/13/a3d483230a09201e211ceb1aa208b1374d27d23b8b180d74dba14b30f6b3/lxml-6.1.2-cp314-cp314-win_amd64.whl", hash = "sha256:87e9673cd8a3445024fe38e7f91b55fa3428437eec9b7a7ff7d81979520c0d2d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/1c/f1/c1445d4b6ad7c51e39d4e2ebbf015a4880f5b297a4ab0e77e4d0e5b70110/lxml-6.1.2-cp314-cp314-win_arm64.whl", hash = "sha256:878e7c8ada8f92c52f13f35a2ab98ef0adf7fd0211d164fc2af589e4c3cfed63" }, + { url = "https://mirrors.aliyun.com/pypi/packages/9d/eb/598c76f4ce19a67c635e86a46d880cc854f308f39a6f1fdf13bbb01813ec/lxml-6.1.2-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:94162456ed0a64fb1c06915df5bd06af4675ae3966d6048fcb73b0906e0e0222" }, + { url = "https://mirrors.aliyun.com/pypi/packages/da/c7/1f9fac7b566a86ad0da13dcc0259164266469c0ad86744c740ccd5c2a081/lxml-6.1.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:4b0fa7109b1d0bc1747d8241a0853e135eefb1c978685241b544c46937383efd" }, + { url = "https://mirrors.aliyun.com/pypi/packages/3e/1b/cfda9307388d496e7eeb7493d9455896b8137ed95f51f3d6ae6ddcc14a47/lxml-6.1.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:604f4778632588d7c000e7e19430639dc12fca58b5b6e99edffba7631725ef0e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e5/71/f732c8919c45b7f29acf443288c6e90036877a67bfeeb1acceb0fffa011b/lxml-6.1.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5a096d6a5f96b776a5b020cb45c17c545effd2a3b6639e6fa97bc95537600923" }, + { url = "https://mirrors.aliyun.com/pypi/packages/30/00/121d52b944f41e33ea86c62875f902d24982842dc7231ab154ac5a6c6593/lxml-6.1.2-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6454d184d556eaf4cb3d6f69e405d21602d6fdcf08b8d57796824275986c6595" }, + { url = "https://mirrors.aliyun.com/pypi/packages/70/19/cadb73c7fe48c7563dc8ab62ea53d5b920c8911bfb808507a6daa82e78d2/lxml-6.1.2-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8b68f2548259bb04e0b3d5df0c397abe8b0080f5e1ffe4019fb7a8bf01a9339e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/13/32/9de126a14d5a5db8c371c5ec869178417db226707b62a47273a95ae6df7f/lxml-6.1.2-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c9cc4b6532abe154dbdebb42aaba8d52c852919591e45067f5b7d46a0405e88" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ff/9b/22dd9e843629ed04652591fb220eb2bf2394d97be3be377d60d8083405d7/lxml-6.1.2-cp314-cp314t-manylinux_2_28_i686.whl", hash = "sha256:57188e441ab24f906bd5a5c14eb55363ab51aa6c0de549f3dd320043721cc118" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2c/2c/b12a1dc121f81c280635c721c7bcaa341441fcbe37397f60b8915048aece/lxml-6.1.2-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:d0bfd719c254bbe60ea022cff0e6ffb799a6fa7d4d72852cebe0257957b32d68" }, + { url = "https://mirrors.aliyun.com/pypi/packages/57/41/fd87a41edc531e7969c25ab1d6b52b5b041eb108b88f6394d6afb4374396/lxml-6.1.2-cp314-cp314t-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:be6f87cd224254a8f81324e34cc655508b83f1d70458a1a39857ad2aa9925852" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6e/30/713ba813b6e6673c6dc34733746516017efcd17949b767b154cc50bccf20/lxml-6.1.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:074a88f70a7360a4a0c5be5d898062cd26f898c25b459efb1bdd43ae700c5a1a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/33/f8/6532ce0fecd9c326d06b08274ee075cc28dbc9f5e9285355db8504689114/lxml-6.1.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:9031f5f01452681abf39fdd65f84a70cb01a7572a1bbf570042e826b1232d07b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/74/b6/5a1f7833ebaa0dd33c28f6f9755ec6ff3891bf63f097634b44e6da1bb65e/lxml-6.1.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:cfeac14425fc7a6fca7864b774d4ee63547926158f4a18c67d77b2c9a948acf1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e6/20/6ae0fc1b45e20877cdcfb1168ceeaf9abb0fba5ed36bd639a260e7b2101e/lxml-6.1.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:8ec111ff8067325f85c08aa9c2b26179ec0537bb89c003fde31127139f85f82d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/47/b4/2bc7b37fbb990ccfb7d30393660741592177224a94e07d842c8da70638e8/lxml-6.1.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:48e912f37c99a297175ba955f55a47c0e1c834b506ef162e52a6e4fe276e6e45" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4d/0b/07fb8e1dee29a78e2c5fa5c6c914218be76a6406baff27907429566e90ec/lxml-6.1.2-cp314-cp314t-win32.whl", hash = "sha256:7c444c3a6e8e75334879980eed96568f0e12064c8b1913424eac1805e976736b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/58/ab/3371527bd9820aae6f511697c93032ed197b0d8dab0f17818f18d3099637/lxml-6.1.2-cp314-cp314t-win_amd64.whl", hash = "sha256:7f35ba7667004ecdafebbe08da7c9fa06ee6195275bb7ef7a29ee1901e69519c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/e6/bb/e6de9b2546a4e6df4fb52fb18921906a8b7a041aba06570995759a4d6d8b/lxml-6.1.2-cp314-cp314t-win_arm64.whl", hash = "sha256:d117f39b28ab8a330a74abdbe61c2255b51973b238db25fd6c2448de1eb2a02d" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0e/83/7ff98683e14a148191278728d11ba782c3d5137886d49fd95ab4036efa1b/lxml-6.1.2-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:1e3c67b817867c484794d7fe0d73045d7d0c67460c78a0a1249a9e92266e6a0e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/24/39/c39f05e8240e98009dd3d4ceb248319d0f36467babc5f90a909ed0c5b68a/lxml-6.1.2-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:d3e97ac4353cca3fbbfa829bc0c6a913771573d1c6d46932d4335c46f2b7796a" }, + { url = "https://mirrors.aliyun.com/pypi/packages/c5/bf/25e26b089510940a0777ab334357874569255e50930224c8159cd649e754/lxml-6.1.2-cp315-cp315-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:827438bf6c8292d22a409bb7990d7cffce410f33e7664e46ca74d2ecc26975ef" }, + { url = "https://mirrors.aliyun.com/pypi/packages/65/6d/aed3a58a3d662f7367a537fabe8c549f1446dbd043719e0ae8cd53f47819/lxml-6.1.2-cp315-cp315-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c470d192e27f97842a068cf12a1c1296b20ca716c56a9249715c6654bc192d19" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a5/ca/706d32b6957c0c2e005a9833e8fc528449196b38d5cfcf9e0fd86a96fb00/lxml-6.1.2-cp315-cp315-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ef0b8ba6e13597f681b2b4924ca9c4e8c88420bf0e21d9a9006c757f2fc39d1f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ac/e9/445ff43f56fcffa06f6f3a7189920c216f3eacef68ef834d4111cdbd86ba/lxml-6.1.2-cp315-cp315-manylinux_2_31_armv7l.whl", hash = "sha256:65c32ddc5d0750129c7b119fb57d48192b76d334c21e6b690d19dfb06b34af79" }, + { url = "https://mirrors.aliyun.com/pypi/packages/69/78/20b8b7e79a1b1d9cd4465c332d62962858562b446692f16a27068fa54b85/lxml-6.1.2-cp315-cp315-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0aa07065497f191ad26c4b587ce5dbb5a7105285a3789aafd0661750e8bac537" }, + { url = "https://mirrors.aliyun.com/pypi/packages/54/ca/84a0e1148bf511e12e0d99732a4e136a3bf1b91622f0a1b197796e2ff984/lxml-6.1.2-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:cde6b8db7d2e5135129eb5e74b7b44dd2053aa767cd5023541fccedddc262453" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6f/f8/1ef6fc7070bed8753315f2e4ea66bc0d37620e1444d014db7f0267b8faaf/lxml-6.1.2-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:b28842b30c4bc2e6afe137d98a5d2071a62589471e76d053bea55b0e53298af9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/87/f6/3a4824cd1c1b81d996d2d75bbd176ba13fbe9b5d89489290d93ff9558486/lxml-6.1.2-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:11f529062255209a421ae4de5b1bb36b2f0a2e1a700745e675a4bf4084d13c00" }, + { url = "https://mirrors.aliyun.com/pypi/packages/64/9a/f133bf16a67149e00ca5d8a8f1ae662c30a86c303aa242693b67f8e19856/lxml-6.1.2-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:f8b89b3be75a37509602b03f9cfa1a28298d4eed4625748148307aeb907901b7" }, + { url = "https://mirrors.aliyun.com/pypi/packages/50/63/273e7e8a73a5d183d8552dfdaa131dfda0292ddab7bcddc5a66a0ae525d8/lxml-6.1.2-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:1a2331da06dd55a8184985306eb2afd72d708283ce7e85d67bba77317b785060" }, + { url = "https://mirrors.aliyun.com/pypi/packages/49/eb/614117c36a28909e79ff7cdec87008f0bd996478f35cf72309189cf398b1/lxml-6.1.2-cp315-cp315-win32.whl", hash = "sha256:442766b326d9892585a64e8c6c4b5ab81d0e6c0538c9f0fc11a84dc101a5d97f" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5c/e9/06aee6107cf8e7b870f10f82539f366cba10dc6053144cca80e838caf8c8/lxml-6.1.2-cp315-cp315-win_amd64.whl", hash = "sha256:a7fd1dd6faa3df9dcd8f1765237362cd885ca62cdf77a7c5f5ea383ae5b6048b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/84/bf/dad9b6baf9b26d79584834e15cef2a5dd0a13c7b1df08831e8f18244b494/lxml-6.1.2-cp315-cp315-win_arm64.whl", hash = "sha256:054175250531a5fb102d485743ff16412279c93add12385b3b1c3d7b16d8deaa" }, + { url = "https://mirrors.aliyun.com/pypi/packages/5f/9d/cd0c43d45e2eb52df7735c6558f24054ca633499191899b0cb9040fbbc3c/lxml-6.1.2-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:84a2a46b93b789d8acb44cfcb3d967ce9dbe29884ddb93fbb1a33f0e0c8fcd86" }, + { url = "https://mirrors.aliyun.com/pypi/packages/0b/26/27093dc1a9edbdd8a54652f237a387f7e63ec0192efe708bc2576d8a1383/lxml-6.1.2-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:4aced3284e0353c798b060fe2c175eb81410e99b9a7e2ae6951be5333732b111" }, + { url = "https://mirrors.aliyun.com/pypi/packages/2c/ee/502f7c93507f57eb496744a64da8f4ca86855cf88e48d14584342f1bfd92/lxml-6.1.2-cp315-cp315t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:47c92dc5167de16e27ace8332454f12ba172dcab04f7a78a9eae14e2e41b6a41" }, + { url = "https://mirrors.aliyun.com/pypi/packages/bf/72/c4cbbe72f951650f2afe43a70e51687e111d82b9bec46e3310ea76419d46/lxml-6.1.2-cp315-cp315t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:40366c23a938008a3bedfcfd80709b3a857c188b4d710b083e978ef5d2c1c715" }, + { url = "https://mirrors.aliyun.com/pypi/packages/14/83/a3df966d6d7b6513e9dfb6fbfb041c0619642170359c1b36ab20a83e59eb/lxml-6.1.2-cp315-cp315t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c4c6dc1b2485aaa4adfb6ed754f90dddcb2b96a66bbebc9e1ac242b5ce5e818" }, + { url = "https://mirrors.aliyun.com/pypi/packages/4f/85/8692ec8173c9f8d295735b9bf410d202317e7b3ed11141e80a30f421f409/lxml-6.1.2-cp315-cp315t-manylinux_2_31_armv7l.whl", hash = "sha256:3a698fad6f122a9b3e2dc2fb598c1de7329c74a67c7a334c9109a440de2508e5" }, + { url = "https://mirrors.aliyun.com/pypi/packages/11/e7/dbe3cece28a5bf82997a091d9dbb0fc49e725a5fa86550897ee2cf6412e6/lxml-6.1.2-cp315-cp315t-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:14879fa5eb2b793c040bbfcb62011aa3015c65d6c9875e063ea98ce2029d51fb" }, + { url = "https://mirrors.aliyun.com/pypi/packages/99/a9/81a2d27640db0d27200b2f32339a54e74c36d58feb5ad528b87d52a59ecc/lxml-6.1.2-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:b631174cd2e4d9f8a94ef17f911c6ded10ede93b5e7860dee7bbf85961d321e9" }, + { url = "https://mirrors.aliyun.com/pypi/packages/cb/f4/0b0304c70c087f618d95b0306738b070bd556afd09c2c92589b78dbe5eb0/lxml-6.1.2-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:ceafa5e0536c62a5cd9f65327fa0b57d6f0b0e3435daf2c98a78d0dde7ecbae1" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a2/ec/f9fc45f1d01b632b673e11880e75292dff9953db9f426d1a38201b8eb5f5/lxml-6.1.2-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:7c482e87cc86bed78a50462560675bc2c348ef72c47596f9b933346d5a8e920e" }, + { url = "https://mirrors.aliyun.com/pypi/packages/6a/0b/d65e0458c2bcce0df68d5cc29ad0006e76446f02d9e50caf188fd1fb8bae/lxml-6.1.2-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:b1c0d2dde8a50520efc51644587f0fc4810e3af7d3e029d7af0be93bf39e2b5c" }, + { url = "https://mirrors.aliyun.com/pypi/packages/ee/62/1fee828238badd3bfe9544f5cc9ce6ded421ef38e9634030445dedd78b36/lxml-6.1.2-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:dd7ea3fa47154b9fff90591b961e41b3718bd7fcd5bc2d9bb47e9845c8ace088" }, + { url = "https://mirrors.aliyun.com/pypi/packages/20/18/35fb14dd6baccbffa6daeb2369802f04a94e3f73db3c7bb405dbab009729/lxml-6.1.2-cp315-cp315t-win32.whl", hash = "sha256:87534cec6ea325435e4adf2326b0cf3110eee9a47abf73652eb155db639c08c6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/f0/b6/07530896ca062bc3d2f09d5cb8a48e799c05b12c496205db03159ba13b6c/lxml-6.1.2-cp315-cp315t-win_amd64.whl", hash = "sha256:4e220a9c297e5d36895d489a08c9a3f1f6193b6414e702c5fb751e4a3767f8d0" }, + { url = "https://mirrors.aliyun.com/pypi/packages/31/a8/237d8de1d77085cfd41d0c6049a044d8d01886f3afb7f1eda2f43d900a96/lxml-6.1.2-cp315-cp315t-win_arm64.whl", hash = "sha256:f16a407766bac51c65d605b06d900821751a79aa20e12185f273f14a17180e7b" }, ] [[package]] @@ -680,11 +710,11 @@ wheels = [ [[package]] name = "pygments" -version = "2.19.2" +version = "2.21.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/49/2e/ced460408999b33da6b31b0021b0f37d329e202d4169aeb164493778f25b/pygments-2.21.0.tar.gz", hash = "sha256:610ca751c9bc2492b38eb9a38a7fbc93edbbb2d7182edaf34e66ae493dee5c8c" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/71/46/17f022dd3e953bf20a04a028a21ec746d942f8d2af30fa0f124fa0e6a684/pygments-2.21.0-py3-none-any.whl", hash = "sha256:2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9" }, ] [[package]] @@ -723,7 +753,7 @@ wheels = [ [[package]] name = "pytest" -version = "9.0.2" +version = "9.1.1" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -732,9 +762,9 @@ dependencies = [ { name = "pluggy" }, { name = "pygments" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b" }, + { url = "https://mirrors.aliyun.com/pypi/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c" }, ] [[package]] @@ -764,7 +794,7 @@ dev = [ [package.metadata] requires-dist = [ - { name = "lxml", specifier = ">=3.1.0" }, + { name = "lxml", specifier = ">=6.1.0" }, { name = "typing-extensions", specifier = ">=4.9.0" }, ] @@ -776,7 +806,7 @@ dev = [ { name = "markupsafe", specifier = ">=2.1.2" }, { name = "pyparsing", specifier = ">=3.2.3" }, { name = "pyright", specifier = ">=1.1.401" }, - { name = "pytest", specifier = ">=8.4.0" }, + { name = "pytest", specifier = ">=9.0.3" }, { name = "ruff", specifier = ">=0.11.13" }, { name = "sphinx", specifier = ">=7.0.0" }, { name = "sphinx-book-theme" }, @@ -810,7 +840,7 @@ wheels = [ [[package]] name = "requests" -version = "2.32.5" +version = "2.34.2" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } dependencies = [ { name = "certifi" }, @@ -818,9 +848,9 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/ac/c3/e2a2b89f2d3e2179abd6d00ebd70bff6273f37fb3e0cc209f48b39d00cbf/requests-2.34.2.tar.gz", hash = "sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6" }, + { url = "https://mirrors.aliyun.com/pypi/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl", hash = "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0" }, ] [[package]] @@ -925,11 +955,11 @@ wheels = [ [[package]] name = "soupsieve" -version = "2.8.3" +version = "2.9.2" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/7b/ae/2d9c981590ed9999a0d91755b47fc74f74de286b0f5cee14c9269041e6c4/soupsieve-2.8.3.tar.gz", hash = "sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/69/99/a6ca3beb3ccacb41fb3321d8a60e5566f9e6467601ef8eba6a17e1b89778/soupsieve-2.9.2.tar.gz", hash = "sha256:4a55d8cf158a9c2e587fa4922f1bbb91d68ac829e2d6f25403a85747c71daf74" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl", hash = "sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95" }, + { url = "https://mirrors.aliyun.com/pypi/packages/eb/dc/ad025c1ee131eba60c69f4dd5779b18fcf1e6b21a343e2162a84d5d133c7/soupsieve-2.9.2-py3-none-any.whl", hash = "sha256:8089a26fd974ca7a1f30276d3d8492ab266ab15af581642dfe8aa162e0c1c823" }, ] [[package]] @@ -1114,11 +1144,11 @@ wheels = [ [[package]] name = "urllib3" -version = "2.6.3" +version = "2.7.0" source = { registry = "https://mirrors.aliyun.com/pypi/simple" } -sdist = { url = "https://mirrors.aliyun.com/pypi/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed" } +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c" } wheels = [ - { url = "https://mirrors.aliyun.com/pypi/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4" }, + { url = "https://mirrors.aliyun.com/pypi/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897" }, ] [[package]] From 9db5ef48293b45ebeb18a8923681ff899e2898ab Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 28 Aug 2026 18:34:51 +0800 Subject: [PATCH 105/115] Add package-level document sanitization --- HISTORY.md | 6 + README.md | 3 +- docs/api/sanitize.rst | 60 +++++ docs/index.rst | 6 +- docs/user/sanitization.rst | 56 +++++ src/docx/document.py | 22 ++ src/docx/opc/coreprops.py | 35 +++ src/docx/opc/part.py | 8 + src/docx/sanitize/__init__.py | 10 + src/docx/sanitize/cleaner.py | 221 ++++++++++++++++++ src/docx/sanitize/result.py | 38 +++ tests/fixtures/README.md | 2 + .../fixtures/comments/word-comments-rich.docx | Bin 0 -> 20023 bytes tests/opc/test_coreprops.py | 16 ++ tests/opc/test_part.py | 11 + tests/test_sanitize.py | 197 ++++++++++++++++ 16 files changed, 689 insertions(+), 2 deletions(-) create mode 100644 docs/api/sanitize.rst create mode 100644 docs/user/sanitization.rst create mode 100644 src/docx/sanitize/__init__.py create mode 100644 src/docx/sanitize/cleaner.py create mode 100644 src/docx/sanitize/result.py create mode 100644 tests/fixtures/comments/word-comments-rich.docx create mode 100644 tests/test_sanitize.py diff --git a/HISTORY.md b/HISTORY.md index b0fff666..028ef402 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,11 @@ ## Release History +**Unreleased** + +- Added opt-in package-level document sanitization for personal metadata, + comments, web extensions, and formatting revision history. +- Added structured sanitization reports and real Word comment round-trip coverage. + **0.2.0 (2026-08-24)** - Added direct loading from raw DOCX bytes with ``Document(bytes)``. diff --git a/README.md b/README.md index 5fa47cab..95400aa5 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,8 @@ or low-level package and relationship access. | Latin and East Asian font controls | Stable | `run.font.name`, `run.font.hAnsi`, `run.font.eastAsia` | | Low-level OPC parts and relationships | Stable | `document.part.package`, `part.rels` | | In-memory read, export, and independent copies | Stable | `Document()`, `to_bytes()`, `copy()` | -| Package inspection, diff, and sanitization | Planned | — | +| Document sanitization | Development | `document.sanitize()` | +| Package inspection and diff | Planned | — | ## Installation diff --git a/docs/api/sanitize.rst b/docs/api/sanitize.rst new file mode 100644 index 00000000..b0d5f71b --- /dev/null +++ b/docs/api/sanitize.rst @@ -0,0 +1,60 @@ +.. _sanitize_api: + +Sanitization objects +==================== + +.. currentmodule:: docx.sanitize + + +SanitizationReport objects +-------------------------- + +.. autoclass:: SanitizationReport + :members: changed + + .. attribute:: scrubbed_properties + + Names of core properties normalized during sanitization. + + .. attribute:: removed_comment_markers + + Number of outermost comment marker elements removed from Word story XML. + + .. attribute:: removed_formatting_revisions + + Number of outermost formatting revision elements removed. + + .. attribute:: removed_parts + + Package part names made unreachable by removed relationships. + + .. attribute:: removed_relationships + + :class:`RemovedRelationship` records for relationships removed from the + package graph. + + .. attribute:: warnings + + Non-fatal conditions encountered while sanitizing the package. + + +RemovedRelationship objects +--------------------------- + +.. autoclass:: RemovedRelationship + + .. attribute:: source + + Part name of the relationship source, or ``/`` for the package itself. + + .. attribute:: relationship_id + + Relationship identifier used by the source. + + .. attribute:: relationship_type + + Full relationship type URI. + + .. attribute:: target + + Target part name or external target reference. diff --git a/docs/index.rst b/docs/index.rst index 9c6abd65..85b77f82 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -22,7 +22,9 @@ supports capabilities needed by more demanding document workflows: * SVG and EMF vector images; * separate Latin and East Asian font settings; * document custom properties; and -* multiple Custom XML parts that survive a load/save round trip. +* multiple Custom XML parts that survive a load/save round trip; and +* explicit package-level sanitization of metadata, comments, web extensions, + and formatting revision history. Here is a small example: @@ -94,6 +96,7 @@ User Guide user/styles-understanding user/styles-using user/comments + user/sanitization user/shapes user/custom-properties user/custom-xml @@ -113,6 +116,7 @@ API Documentation api/table api/section api/comments + api/sanitize api/shape api/dml api/shared diff --git a/docs/user/sanitization.rst b/docs/user/sanitization.rst new file mode 100644 index 00000000..9378af05 --- /dev/null +++ b/docs/user/sanitization.rst @@ -0,0 +1,56 @@ +.. _sanitization: + +Document sanitization +===================== + +Sanitization removes selected package-level information before a document is +shared. Every operation is disabled by default because removal is destructive. + +Use :meth:`Document.sanitize() ` with explicit +options and inspect its report before saving:: + + from docx import Document + + document = Document("input.docx") + report = document.sanitize( + personal_metadata=True, + comments=True, + web_extensions=True, + formatting_revisions=True, + ) + + if report.changed: + document.save("sanitized.docx") + +The returned :class:`~docx.sanitize.SanitizationReport` identifies scrubbed +properties, removed XML markers, parts, and relationships, plus any warnings. +Each removed relationship is represented by +:class:`~docx.sanitize.RemovedRelationship`. Repeating the same sanitization is +idempotent: the second report has ``changed == False`` when nothing new was +added. + +Options +------- + +``personal_metadata`` + Clears author and last-modified-by values and canonicalizes the revision + number. Duplicate property elements are removed. + +``comments`` + Removes comment markers from all reachable Word XML story parts and removes + the complete comments relationship tree, including modern comments extension + parts when present. + +``web_extensions`` + Removes web-extension task panes and their related package parts. + +``formatting_revisions`` + Removes property-change history such as ``rPrChange`` and ``pPrChange`` while + retaining the currently effective formatting. + +Scope boundary +-------------- + +This API does not accept or reject tracked content revisions. It also does not +remove Custom XML, macros, OLE objects, external links, or application-specific +business metadata. Those operations require separate policy decisions. diff --git a/src/docx/document.py b/src/docx/document.py index 1d46abcf..9514f4b2 100644 --- a/src/docx/document.py +++ b/src/docx/document.py @@ -12,6 +12,7 @@ from docx.blkcntnr import BlockItemContainer from docx.enum.section import WD_SECTION from docx.enum.text import WD_BREAK +from docx.sanitize import SanitizationReport, sanitize_document from docx.section import Section, Sections from docx.shared import ElementProxy, Emu, Inches, Length from docx.text.run import Run @@ -229,6 +230,27 @@ def save(self, path_or_stream: str | IO[bytes]): """ self._part.save(path_or_stream) + def sanitize( + self, + *, + personal_metadata: bool = False, + comments: bool = False, + web_extensions: bool = False, + formatting_revisions: bool = False, + ) -> SanitizationReport: + """Apply the explicitly selected package-level cleanup operations. + + Every option defaults to |False| because sanitization is destructive. The + returned report describes all package and XML changes made to this document. + """ + return sanitize_document( + self, + personal_metadata=personal_metadata, + comments=comments, + web_extensions=web_extensions, + formatting_revisions=formatting_revisions, + ) + @property def sections(self) -> Sections: """|Sections| object providing access to each section in this document.""" diff --git a/src/docx/opc/coreprops.py b/src/docx/opc/coreprops.py index 62f0c5ab..9e62eae3 100644 --- a/src/docx/opc/coreprops.py +++ b/src/docx/opc/coreprops.py @@ -9,6 +9,7 @@ from typing import TYPE_CHECKING from docx.oxml.coreprops import CT_CoreProperties +from docx.oxml.ns import qn if TYPE_CHECKING: from docx.oxml.coreprops import CT_CoreProperties @@ -21,6 +22,40 @@ class CoreProperties: def __init__(self, element: CT_CoreProperties): self._element = element + def deduplicate(self, *property_names: str) -> set[str]: + """Remove duplicate XML elements for the named core properties. + + The first occurrence is retained so callers can subsequently normalize its + value through the regular property setter. + """ + element_tags = { + "author": qn("dc:creator"), + "category": qn("cp:category"), + "comments": qn("dc:description"), + "content_status": qn("cp:contentStatus"), + "created": qn("dcterms:created"), + "identifier": qn("dc:identifier"), + "keywords": qn("cp:keywords"), + "language": qn("dc:language"), + "last_modified_by": qn("cp:lastModifiedBy"), + "last_printed": qn("cp:lastPrinted"), + "modified": qn("dcterms:modified"), + "revision": qn("cp:revision"), + "subject": qn("dc:subject"), + "title": qn("dc:title"), + "version": qn("cp:version"), + } + changed: set[str] = set() + for property_name in property_names: + try: + tag = element_tags[property_name] + except KeyError as exc: + raise ValueError(f"Unsupported core property: {property_name}") from exc + for duplicate in self._element.findall(tag)[1:]: + self._element.remove(duplicate) + changed.add(property_name) + return changed + @property def author(self): return self._element.author_text diff --git a/src/docx/opc/part.py b/src/docx/opc/part.py index a9f67a29..43b58d15 100644 --- a/src/docx/opc/part.py +++ b/src/docx/opc/part.py @@ -144,6 +144,10 @@ def relate_to(self, target: Part | str, reltype: str, is_external: bool = False) rel = self.rels.get_or_add(reltype, cast(Part, target)) return rel.rId + def replace_blob(self, blob: bytes) -> None: + """Replace the serialized payload of this non-XML part.""" + self._blob = blob + @property def related_parts(self): """Dictionary mapping related parts by rId, so child objects can resolve @@ -235,6 +239,10 @@ def element(self): """The root XML element of this XML part.""" return self._element + def replace_blob(self, blob: bytes) -> None: + """Reject raw replacement because this part serializes from ``element``.""" + raise TypeError("cannot replace the blob of an XmlPart; replace its element instead") + @element.setter def element(self, e: BaseOxmlElement): self._element = e diff --git a/src/docx/sanitize/__init__.py b/src/docx/sanitize/__init__.py new file mode 100644 index 00000000..83ec334c --- /dev/null +++ b/src/docx/sanitize/__init__.py @@ -0,0 +1,10 @@ +"""Package-level DOCX sanitization. + +Callers use :meth:`docx.document.Document.sanitize`; this package keeps OPC graph +mutation and XML cleanup details behind that single method. +""" + +from docx.sanitize.cleaner import sanitize_document +from docx.sanitize.result import RemovedRelationship, SanitizationReport + +__all__ = ["RemovedRelationship", "SanitizationReport", "sanitize_document"] diff --git a/src/docx/sanitize/cleaner.py b/src/docx/sanitize/cleaner.py new file mode 100644 index 00000000..babf2099 --- /dev/null +++ b/src/docx/sanitize/cleaner.py @@ -0,0 +1,221 @@ +"""Implementation of the package-level sanitization boundary.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Iterator + +from lxml import etree + +from docx.opc.oxml import serialize_part_xml +from docx.opc.part import Part, XmlPart +from docx.oxml.ns import qn +from docx.oxml.parser import parse_xml +from docx.sanitize.result import RemovedRelationship, SanitizationReport + +if TYPE_CHECKING: + from lxml.etree import _Element as etree_Element # pyright: ignore[reportPrivateUsage] + + from docx.document import Document + from docx.opc.package import OpcPackage + from docx.oxml.xmlchemy import BaseOxmlElement + + +_COMMENT_MARKER_TAGS = ( + qn("w:commentRangeStart"), + qn("w:commentRangeEnd"), + qn("w:commentReference"), +) +_COMMENT_RELATIONSHIP_NAMES = frozenset( + { + "commentauthors", + "comments", + "commentsextended", + "commentsextensible", + "commentsids", + "people", + } +) +_FORMATTING_REVISION_TAGS = tuple( + qn(tag) + for tag in ( + "w:rPrChange", + "w:pPrChange", + "w:tblPrChange", + "w:trPrChange", + "w:tcPrChange", + "w:sectPrChange", + ) +) +_WEB_EXTENSION_RELATIONSHIP_NAMES = frozenset({"webextension", "webextensiontaskpanes"}) + + +def sanitize_document( + document: Document, + *, + personal_metadata: bool, + comments: bool, + web_extensions: bool, + formatting_revisions: bool, +) -> SanitizationReport: + """Apply selected sanitizers while keeping all graph mechanics internal.""" + package = document.part.package + assert package is not None + + if not any((personal_metadata, comments, web_extensions, formatting_revisions)): + return SanitizationReport() + + parts_before = _reachable_part_names(package) + scrubbed_properties: list[str] = [] + removed_relationships: list[RemovedRelationship] = [] + warnings: list[str] = [] + removed_comment_markers = 0 + removed_formatting_revisions = 0 + + if personal_metadata: + scrubbed_properties.extend(_scrub_personal_metadata(package)) + + if comments or formatting_revisions: + for part, root in _iter_word_xml(package, warnings): + part_changed = False + if comments: + count = _remove_elements(root, _COMMENT_MARKER_TAGS) + removed_comment_markers += count + part_changed = part_changed or count > 0 + if formatting_revisions: + count = _remove_elements(root, _FORMATTING_REVISION_TAGS) + removed_formatting_revisions += count + part_changed = part_changed or count > 0 + if part_changed and not isinstance(part, XmlPart): + part.replace_blob(serialize_part_xml(root)) + + if comments: + removed_relationships.extend(_drop_relationships(package, _COMMENT_RELATIONSHIP_NAMES)) + if web_extensions: + removed_relationships.extend( + _drop_relationships(package, _WEB_EXTENSION_RELATIONSHIP_NAMES) + ) + + parts_after = _reachable_part_names(package) + return SanitizationReport( + scrubbed_properties=tuple(scrubbed_properties), + removed_comment_markers=removed_comment_markers, + removed_formatting_revisions=removed_formatting_revisions, + removed_parts=tuple(sorted(parts_before - parts_after)), + removed_relationships=tuple(removed_relationships), + warnings=tuple(warnings), + ) + + +def _drop_relationships( + package: OpcPackage, relationship_names: frozenset[str] +) -> list[RemovedRelationship]: + removed: list[RemovedRelationship] = [] + for source_name, source in _relationship_sources(package): + for rId, rel in list(source.rels.items()): + if _relationship_name(rel.reltype) not in relationship_names: + continue + target = rel.target_ref if rel.is_external else str(rel.target_part.partname) + removed.append(RemovedRelationship(source_name, rId, rel.reltype, target)) + del source.rels[rId] + return removed + + +def _iter_word_xml( + package: OpcPackage, warnings: list[str] +) -> Iterator[tuple[Part, BaseOxmlElement]]: + for part in _reachable_parts(package): + if not str(part.partname).startswith("/word/"): + continue + if isinstance(part, XmlPart): + yield part, part.element + continue + if not part.content_type.endswith("+xml") and part.content_type != "application/xml": + continue + try: + yield part, parse_xml(part.blob) + except etree.XMLSyntaxError as exc: + warnings.append(f"Could not sanitize XML part {part.partname}: {exc}") + + +def _reachable_parts(package: OpcPackage) -> list[Part]: + parts: list[Part] = [] + visited: set[int] = set() + + def walk(source: OpcPackage | Part) -> None: + for rel in source.rels.values(): + if rel.is_external: + continue + part = rel.target_part + identity = id(part) + if identity in visited: + continue + visited.add(identity) + parts.append(part) + walk(part) + + walk(package) + return parts + + +def _reachable_part_names(package: OpcPackage) -> set[str]: + return {str(part.partname) for part in _reachable_parts(package)} + + +def _relationship_name(relationship_type: str) -> str: + return relationship_type.rstrip("/").rsplit("/", 1)[-1].lower() + + +def _relationship_sources(package: OpcPackage) -> list[tuple[str, OpcPackage | Part]]: + return [("/", package), *[(str(part.partname), part) for part in _reachable_parts(package)]] + + +def _remove_elements(root: BaseOxmlElement, tags: tuple[str, ...]) -> int: + tag_set = set(tags) + elements = [ + element + for tag in tags + for element in root.iter(tag) + if not any(ancestor.tag in tag_set for ancestor in element.iterancestors()) + ] + for element in elements: + parent = element.getparent() + if parent is not None: + comment_run = _empty_comment_reference_run(element) + parent.remove(element) + if comment_run is not None: + comment_run_parent = comment_run.getparent() + if comment_run_parent is not None: + comment_run_parent.remove(comment_run) + return len(elements) + + +def _scrub_personal_metadata(package: OpcPackage) -> list[str]: + core_properties = package.core_properties + changed = core_properties.deduplicate("author", "last_modified_by", "revision") + if core_properties.author: + changed.add("author") + if core_properties.last_modified_by: + changed.add("last_modified_by") + if core_properties.revision != 1: + changed.add("revision") + core_properties.author = "" + core_properties.last_modified_by = "" + core_properties.revision = 1 + return [name for name in ("author", "last_modified_by", "revision") if name in changed] + + +def _empty_comment_reference_run(element: etree_Element) -> etree_Element | None: + if element.tag != qn("w:commentReference"): + return None + run = element.getparent() + if run is None or run.tag != qn("w:r"): + return None + remaining = [child for child in run if child is not element] + if not remaining: + return run + if len(remaining) != 1 or remaining[0].tag != qn("w:rPr"): + return None + run_properties = remaining[0] + if len(run_properties) != 1 or run_properties[0].tag != qn("w:rStyle"): + return None + return run if run_properties[0].get(qn("w:val")) == "CommentReference" else None diff --git a/src/docx/sanitize/result.py b/src/docx/sanitize/result.py new file mode 100644 index 00000000..d8da1c92 --- /dev/null +++ b/src/docx/sanitize/result.py @@ -0,0 +1,38 @@ +"""Value objects returned by document sanitization.""" + +from __future__ import annotations + +from dataclasses import dataclass + + +@dataclass(frozen=True) +class RemovedRelationship: + """A package relationship removed during sanitization.""" + + source: str + relationship_id: str + relationship_type: str + target: str + + +@dataclass(frozen=True) +class SanitizationReport: + """Immutable summary of changes made by ``Document.sanitize()``.""" + + scrubbed_properties: tuple[str, ...] = () + removed_comment_markers: int = 0 + removed_formatting_revisions: int = 0 + removed_parts: tuple[str, ...] = () + removed_relationships: tuple[RemovedRelationship, ...] = () + warnings: tuple[str, ...] = () + + @property + def changed(self) -> bool: + """Whether the document package was modified.""" + return bool( + self.scrubbed_properties + or self.removed_comment_markers + or self.removed_formatting_revisions + or self.removed_parts + or self.removed_relationships + ) diff --git a/tests/fixtures/README.md b/tests/fixtures/README.md index 3f0b8e05..218d6d43 100644 --- a/tests/fixtures/README.md +++ b/tests/fixtures/README.md @@ -11,6 +11,8 @@ must not rewrite the fixture files in place. | `images/word-svg-image.docx` | SVG image with Word-generated PNG fallback | | `fonts/word-east-asian-fonts.docx` | Separate Latin and East Asian run fonts | | `customxml/multiple-custom-xml-parts.docx` | Generated package with `item1` and `item3` plus data-store properties | +| `comments/word-comments-rich.docx` | Word-created comments preserved across a no-op round trip | The Custom XML fixture is generated by `customxml/generate_fixture.py` from the Word-created blank document. Run that script from the repository root to rebuild it. +The comments fixture is copied from the upstream ``python-docx`` test corpus. diff --git a/tests/fixtures/comments/word-comments-rich.docx b/tests/fixtures/comments/word-comments-rich.docx new file mode 100644 index 0000000000000000000000000000000000000000..245c17224c22d0a6d72958be917d9ef1a899bad6 GIT binary patch literal 20023 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

    @O`g52B)oxZW++>atJ2#U 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", + "second" + "first" + "second" + "", + ) + core_properties = CoreProperties(cast("CT_CoreProperties", parse_xml(xml))) + + changed = core_properties.deduplicate("title", "category") + + assert changed == {"title", "category"} + assert core_properties._element.xml.count("") == 1 + assert core_properties._element.xml.count("") == 1 + # fixtures ------------------------------------------------------- def coreProperties(self, tagname: str, str_val: str, attrs: str = "") -> str: diff --git a/tests/opc/test_part.py b/tests/opc/test_part.py index 50e98976..f9ab4d4d 100644 --- a/tests/opc/test_part.py +++ b/tests/opc/test_part.py @@ -78,6 +78,13 @@ def it_uses_the_load_blob_as_its_blob(self): part = Part(PackURI("/part/name"), "content/type", blob) assert part.blob is blob + def it_can_replace_its_blob(self): + part = Part(PackURI("/part/name"), "content/type", b"before") + + part.replace_blob(b"after") + + assert part.blob == b"after" + # fixtures --------------------------------------------- @pytest.fixture @@ -371,6 +378,10 @@ def it_can_set_its_element(self, part_fixture: XmlPart, new_element_: Mock): part_fixture.element = new_element_ assert part_fixture.element is new_element_ + def it_rejects_raw_blob_replacement(self, part_fixture: XmlPart): + with pytest.raises(TypeError, match="replace its element"): + part_fixture.replace_blob(b"") + @pytest.mark.parametrize( ("part_cxml", "rel_should_be_dropped"), [ diff --git a/tests/test_sanitize.py b/tests/test_sanitize.py new file mode 100644 index 00000000..53ff5e10 --- /dev/null +++ b/tests/test_sanitize.py @@ -0,0 +1,197 @@ +"""Integration tests for package-level document sanitization.""" + +from __future__ import annotations + +import io +from pathlib import Path +from zipfile import ZipFile + +from lxml import etree + +from docx import Document +from docx.opc.packuri import PackURI +from docx.opc.part import Part +from docx.oxml import OxmlElement +from docx.oxml.ns import qn +from docx.oxml.parser import parse_xml + +COMMENTS_FIXTURE = Path(__file__).parent / "fixtures/comments/word-comments-rich.docx" + + +def it_is_noop_without_selected_operations(): + document = Document() + + report = document.sanitize() + + assert report.changed is False + assert report.removed_parts == () + assert report.removed_relationships == () + + +def it_sanitizes_personal_metadata_canonically_and_idempotently(): + document = Document() + root = document.part.package._core_properties_part.element + etree.SubElement(root, qn("dc:creator")).text = "duplicate author" + etree.SubElement(root, qn("cp:lastModifiedBy")).text = "duplicate editor" + etree.SubElement(root, qn("cp:revision")).text = "9" + + first_report = document.sanitize(personal_metadata=True) + second_report = document.sanitize(personal_metadata=True) + reopened = Document(document.to_bytes()) + + assert first_report.scrubbed_properties == ( + "author", + "last_modified_by", + "revision", + ) + assert first_report.changed is True + assert second_report.changed is False + assert reopened.core_properties.author == "" + assert reopened.core_properties.last_modified_by == "" + assert reopened.core_properties.revision == 1 + + +def it_preserves_existing_comments_on_a_roundtrip_without_sanitization(): + document = Document(COMMENTS_FIXTURE) + original_comment_count = len(document.comments) + original_marker_count = _comment_marker_count(COMMENTS_FIXTURE.read_bytes()) + + reopened = Document(document.to_bytes()) + package = reopened.to_bytes() + + assert original_comment_count > 0 + assert original_marker_count > 0 + assert len(reopened.comments) == original_comment_count + assert _comment_marker_count(package) == original_marker_count + + +def it_removes_comment_markers_and_the_comment_part_tree(): + document = Document() + run = document.add_paragraph().add_run("annotated") + document.add_comment(run, text="review", author="Reviewer") + header_paragraph = document.sections[0].header.add_paragraph() + header_paragraph._p.append(OxmlElement("w:commentReference")) + + comments_part = document.part.part_related_by( + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments" + ) + comments_extended = Part( + PackURI("/word/commentsExtended.xml"), + "application/vnd.ms-word.commentsExtended+xml", + b'', + document.part.package, + ) + comments_part.relate_to( + comments_extended, + "http://schemas.microsoft.com/office/2011/relationships/commentsExtended", + ) + + report = document.sanitize(comments=True) + package = document.to_bytes() + second_report = document.sanitize(comments=True) + + assert report.removed_comment_markers == 4 + assert report.removed_parts == ( + "/word/comments.xml", + "/word/commentsExtended.xml", + ) + assert len(report.removed_relationships) == 2 + assert second_report.changed is False + with ZipFile(io.BytesIO(package)) as archive: + assert "word/comments.xml" not in archive.namelist() + assert "word/commentsExtended.xml" not in archive.namelist() + for name in archive.namelist(): + if name.startswith("word/") and name.endswith(".xml"): + xml = archive.read(name) + assert b"commentRangeStart" not in xml + assert b"commentRangeEnd" not in xml + assert b"commentReference" not in xml + assert b"CommentReference" not in archive.read("word/document.xml") + + +def it_removes_the_entire_web_extension_relationship_tree(): + document = Document() + package = document.part.package + taskpanes = Part( + PackURI("/word/webextensions/taskpanes.xml"), + "application/vnd.ms-office.webextensiontaskpanes+xml", + b"", + package, + ) + extension = Part( + PackURI("/word/webextensions/webextension1.xml"), + "application/vnd.ms-office.webextension+xml", + b"", + package, + ) + package.relate_to( + taskpanes, + "http://schemas.microsoft.com/office/2011/relationships/webextensiontaskpanes", + ) + taskpanes.relate_to( + extension, + "http://schemas.microsoft.com/office/2011/relationships/webextension", + ) + + report = document.sanitize(web_extensions=True) + package_bytes = document.to_bytes() + + assert report.removed_parts == ( + "/word/webextensions/taskpanes.xml", + "/word/webextensions/webextension1.xml", + ) + assert len(report.removed_relationships) == 2 + with ZipFile(io.BytesIO(package_bytes)) as archive: + assert not any(name.startswith("word/webextensions/") for name in archive.namelist()) + + +def it_removes_formatting_revisions_and_keeps_current_formatting(): + document = Document() + paragraph = document.add_paragraph() + run = paragraph.add_run("text") + run.bold = True + table = document.add_table(1, 1) + + run._r.get_or_add_rPr().append(OxmlElement("w:rPrChange")) + paragraph._p.get_or_add_pPr().append(OxmlElement("w:pPrChange")) + table._tbl.tblPr.append(OxmlElement("w:tblPrChange")) + table.rows[0]._tr.get_or_add_trPr().append(OxmlElement("w:trPrChange")) + table.cell(0, 0)._tc.get_or_add_tcPr().append(OxmlElement("w:tcPrChange")) + document.sections[0]._sectPr.append(OxmlElement("w:sectPrChange")) + + report = document.sanitize(formatting_revisions=True) + reopened = Document(document.to_bytes()) + + assert report.removed_formatting_revisions == 6 + assert reopened.paragraphs[0].runs[0].bold is True + assert reopened.sanitize(formatting_revisions=True).changed is False + + +def it_counts_only_outermost_nested_formatting_revisions(): + document = Document() + paragraph = document.add_paragraph("text") + outer_change = OxmlElement("w:pPrChange") + nested_properties = OxmlElement("w:pPr") + nested_properties.append(OxmlElement("w:rPrChange")) + outer_change.append(nested_properties) + paragraph._p.get_or_add_pPr().append(outer_change) + + report = document.sanitize(formatting_revisions=True) + + assert report.removed_formatting_revisions == 1 + + +def _comment_marker_count(package: bytes) -> int: + marker_tags = ( + qn("w:commentRangeStart"), + qn("w:commentRangeEnd"), + qn("w:commentReference"), + ) + count = 0 + with ZipFile(io.BytesIO(package)) as archive: + for name in archive.namelist(): + if not name.startswith("word/") or not name.endswith(".xml"): + continue + root = parse_xml(archive.read(name)) + count += sum(len(root.findall(".//" + tag)) for tag in marker_tags) + return count From 5cc15f13957863f9ac29011098c9324a326ca44e Mon Sep 17 00:00:00 2001 From: Ethan Date: Sat, 29 Aug 2026 11:26:47 +0800 Subject: [PATCH 106/115] release: v0.3.0 --- HISTORY.md | 2 ++ src/docx/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 028ef402..ab249451 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,8 @@ **Unreleased** +**0.3.0 (2026-08-29)** + - Added opt-in package-level document sanitization for personal metadata, comments, web extensions, and formatting revision history. - Added structured sanitization reports and real Word comment round-trip coverage. diff --git a/src/docx/__init__.py b/src/docx/__init__.py index 994792a5..9bca648e 100644 --- a/src/docx/__init__.py +++ b/src/docx/__init__.py @@ -13,7 +13,7 @@ if TYPE_CHECKING: from docx.opc.part import Part -__version__ = "0.2.0" +__version__ = "0.3.0" __all__ = ["Document"] From 777d5a5229e8e93ee898e23cc03b2cd74a1a864c Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 31 Aug 2026 15:00:49 +0800 Subject: [PATCH 107/115] test: cover custom XML, numbering, hyperlink, and sanitize round trips --- .../customxml/test_custom_xml_roundtrip.py | 23 ++++++++ tests/integration/test_word_roundtrip.py | 58 +++++++++++++++++++ tests/test_sanitize.py | 51 ++++++++++++++++ 3 files changed, 132 insertions(+) diff --git a/tests/integration/customxml/test_custom_xml_roundtrip.py b/tests/integration/customxml/test_custom_xml_roundtrip.py index 52986397..0bb588ac 100644 --- a/tests/integration/customxml/test_custom_xml_roundtrip.py +++ b/tests/integration/customxml/test_custom_xml_roundtrip.py @@ -11,6 +11,7 @@ from docx import Document from docx.document import Document as DocumentType +from docx.oxml.parser import parse_xml from docx.parts.customxml import CustomXmlPart FIXTURE = ( @@ -83,6 +84,28 @@ def it_round_trips_create_update_and_delete_operations_in_memory(self): assert "customXml/_rels/item1.xml.rels" in names assert "customXml/_rels/item3.xml.rels" in names + def it_round_trips_replacing_a_custom_xml_part_element(self): + document = Document(io.BytesIO(FIXTURE.read_bytes())) + customers = _parts_by_name(document)["/customXml/item1.xml"] + wrapper = parse_xml('') + wrapper.append(customers.element) + customers.element = wrapper + + output = io.BytesIO() + document.save(output) + reopened = Document(io.BytesIO(output.getvalue())) + replaced = _parts_by_name(reopened)["/customXml/item1.xml"] + + assert replaced.tag == "{urn:python-docx-oss:wrapper}wrapper" + assert replaced.attrib["version"] == "1" + assert len(replaced.items) == 1 + assert replaced.items[0].tag == f"{{{CUSTOMERS_NS}}}customers" + assert len(replaced.items[0]) == 2 + with ZipFile(io.BytesIO(output.getvalue())) as package: + names = set(package.namelist()) + assert "customXml/itemProps1.xml" in names + assert "customXml/_rels/item1.xml.rels" in names + def it_rejects_an_explicit_partname_collision(self): document = Document(io.BytesIO(FIXTURE.read_bytes())) diff --git a/tests/integration/test_word_roundtrip.py b/tests/integration/test_word_roundtrip.py index c462bdcc..0ab987fe 100644 --- a/tests/integration/test_word_roundtrip.py +++ b/tests/integration/test_word_roundtrip.py @@ -10,6 +10,10 @@ from lxml import etree from docx import Document +from docx.opc.constants import CONTENT_TYPE as CT +from docx.opc.constants import RELATIONSHIP_TYPE as RT +from docx.oxml import OxmlElement +from docx.oxml.ns import qn FIXTURE_DIR = Path(__file__).parent.parent / "fixtures" TEST_FILE_DIR = Path(__file__).parent.parent / "test_files" @@ -73,6 +77,60 @@ def it_round_trips_a_minimal_word_document_in_memory(self): assert "word/styles.xml" in package assert not any(name.startswith("word/media/") for name in package) + def it_round_trips_a_default_numbering_part_when_the_source_has_none(self): + fixture = _fixture("documents", "word-blank.docx") + with ZipFile(fixture) as source_package: + assert "word/numbering.xml" not in source_package.namelist() + + document = Document(io.BytesIO(fixture.read_bytes())) + numbering_part = document.part.numbering_part + output = document.to_bytes() + reopened = Document(output) + + assert str(numbering_part.partname) == "/word/numbering.xml" + assert str(reopened.part.numbering_part.partname) == "/word/numbering.xml" + with ZipFile(io.BytesIO(output)) as package_file: + package = {name: package_file.read(name) for name in package_file.namelist()} + assert "word/numbering.xml" in package + assert _content_type(package, "/word/numbering.xml") == CT.WML_NUMBERING + relationships = _xml(package, "word/_rels/document.xml.rels") + numbering_relationship = relationships.find( + f"{{{PR_NS}}}Relationship[@Type='{RT.NUMBERING}']" + ) + assert numbering_relationship is not None + assert numbering_relationship.get("Target") == "numbering.xml" + + def it_round_trips_a_changed_external_hyperlink_target(self): + document = Document(_fixture("documents", "word-blank.docx").read_bytes()) + paragraph = document.add_paragraph() + relationship_id = document.part.relate_to( + "https://example.invalid/objects/old-id", + RT.HYPERLINK, + is_external=True, + ) + hyperlink = OxmlElement("w:hyperlink") + hyperlink.set(qn("r:id"), relationship_id) + run = OxmlElement("w:r") + text = OxmlElement("w:t") + text.text = "Business link" + run.append(text) + hyperlink.append(run) + paragraph._p.append(hyperlink) + + new_target = "https://example.invalid/objects/new-id?position=begin" + document.part.rels[relationship_id].target_ref = new_target + output = document.to_bytes() + reopened = Document(output) + + assert reopened.paragraphs[-1].hyperlinks[0].text == "Business link" + assert reopened.paragraphs[-1].hyperlinks[0].address == new_target + with ZipFile(io.BytesIO(output)) as package_file: + relationships = etree.fromstring(package_file.read("word/_rels/document.xml.rels")) + relationship = relationships.find(f"{{{PR_NS}}}Relationship[@Id='{relationship_id}']") + assert relationship is not None + assert relationship.get("Target") == new_target + assert relationship.get("TargetMode") == "External" + def it_creates_independent_document_copies_from_one_snapshot(self): source = Document(_fixture("customxml", "multiple-custom-xml-parts.docx").read_bytes()) source.add_paragraph("Shared snapshot") diff --git a/tests/test_sanitize.py b/tests/test_sanitize.py index 53ff5e10..c38b902c 100644 --- a/tests/test_sanitize.py +++ b/tests/test_sanitize.py @@ -9,6 +9,7 @@ from lxml import etree from docx import Document +from docx.opc.constants import RELATIONSHIP_TYPE as RT from docx.opc.packuri import PackURI from docx.opc.part import Part from docx.oxml import OxmlElement @@ -145,6 +146,56 @@ def it_removes_the_entire_web_extension_relationship_tree(): assert not any(name.startswith("word/webextensions/") for name in archive.namelist()) +def it_round_trips_cleanup_without_removing_application_content(): + document = Document(COMMENTS_FIXTURE) + custom_xml = document.part.add_custom_xml_part( + '' + ) + business_relationship_id = document.part.relate_to( + "https://example.invalid/business/object-id", + RT.HYPERLINK, + is_external=True, + ) + package = document.part.package + taskpanes = Part( + PackURI("/word/webextensions/taskpanes.xml"), + "application/vnd.ms-office.webextensiontaskpanes+xml", + b"", + package, + ) + extension = Part( + PackURI("/word/webextensions/webextension1.xml"), + "application/vnd.ms-office.webextension+xml", + b"", + package, + ) + package.relate_to( + taskpanes, + "http://schemas.microsoft.com/office/2011/relationships/webextensiontaskpanes", + ) + taskpanes.relate_to( + extension, + "http://schemas.microsoft.com/office/2011/relationships/webextension", + ) + + report = document.sanitize(comments=True, web_extensions=True) + output = document.to_bytes() + reopened = Document(output) + + assert report.removed_comment_markers > 0 + assert str(custom_xml.partname) not in report.removed_parts + assert reopened.part.custom_xml_parts[0].tag == ("{urn:python-docx-oss:application}application") + assert reopened.part.rels[business_relationship_id].target_ref == ( + "https://example.invalid/business/object-id" + ) + assert reopened.sanitize(comments=True, web_extensions=True).changed is False + with ZipFile(io.BytesIO(output)) as archive: + names = archive.namelist() + assert "customXml/item1.xml" in names + assert "word/comments.xml" not in names + assert not any(name.startswith("word/webextensions/") for name in names) + + def it_removes_formatting_revisions_and_keeps_current_formatting(): document = Document() paragraph = document.add_paragraph() From 49f27f8aec976d735f4b20a75ca46c34d8efeded Mon Sep 17 00:00:00 2001 From: Ethan Date: Tue, 8 Sep 2026 10:48:36 +0800 Subject: [PATCH 108/115] fix(oxml): restore clean itertext behavior on BaseOxmlElement without duplication --- src/docx/oxml/xmlchemy.py | 23 ++++++++++++++++++++++- tests/oxml/test_xmlchemy.py | 10 ++++++++++ tests/oxml/text/test_run.py | 5 +++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/docx/oxml/xmlchemy.py b/src/docx/oxml/xmlchemy.py index 54237b12..0ef5b138 100644 --- a/src/docx/oxml/xmlchemy.py +++ b/src/docx/oxml/xmlchemy.py @@ -5,7 +5,7 @@ from __future__ import annotations import re -from typing import TYPE_CHECKING, Any, Callable, Sequence, Type, TypeVar +from typing import TYPE_CHECKING, Any, Callable, Iterator, Sequence, Type, TypeVar from lxml import etree from lxml.etree import ElementBase, _Element # pyright: ignore[reportPrivateUsage] @@ -653,6 +653,11 @@ def _remove_choice_group_method_name(self): return "_remove_%s" % self._prop_name +# -- raw lxml text/tail accessors, used to bypass `.text` property overrides -- +_raw_text = _Element.text.__get__ +_raw_tail = _Element.tail.__get__ + + # -- lxml typing isn't quite right here, just ignore this error on _Element -- class BaseOxmlElement(etree.ElementBase, metaclass=MetaOxmlElement): """Effective base class for all custom element classes. @@ -683,6 +688,22 @@ def insert_element_before(self, elm: ElementBase, *tagnames: str): self.append(elm) return elm + def itertext(self, tag: Any | None = None, *tags: Any, with_tail: bool = True) -> Iterator[str]: + """Iterate over text content of this element and its descendants. + + Bypasses the overridden `.text` properties on custom oxml element classes (such as + `CT_P`, `CT_R`, `CT_Hyperlink`), which would otherwise duplicate text, so standard + lxml `itertext()` semantics are preserved. + """ + for node in self.iter(tag, *tags): + text = _raw_text(node) + if text: + yield text + if with_tail and node is not self: + tail = _raw_tail(node) + if tail: + yield tail + def remove_all(self, *tagnames: str) -> None: """Remove child elements with tagname (e.g. "a:p") in `tagnames`.""" for tagname in tagnames: diff --git a/tests/oxml/test_xmlchemy.py b/tests/oxml/test_xmlchemy.py index 9919357e..ed12e107 100644 --- a/tests/oxml/test_xmlchemy.py +++ b/tests/oxml/test_xmlchemy.py @@ -48,6 +48,16 @@ def it_can_remove_all_children_with_name_in_sequence(self, remove_fixture): element.remove_all(*tagnames) assert element.xml == expected_xml + def it_iterates_text_without_duplication_when_text_property_is_overridden(self): + elm = parse_xml( + '' + "foo" + "bar" + "" + ) + assert "".join(elm.itertext()) == "foobar" + assert list(elm.itertext(qn("w:t"))) == ["foo", "bar"] + # fixtures --------------------------------------------- @pytest.fixture( diff --git a/tests/oxml/text/test_run.py b/tests/oxml/text/test_run.py index d4884837..1c9638fe 100644 --- a/tests/oxml/text/test_run.py +++ b/tests/oxml/text/test_run.py @@ -48,3 +48,8 @@ def it_provides_texts_alias_for_text(self): r.texts = "updated" assert r.text == "updated" + + def it_iterates_text_without_duplication(self): + r = cast(CT_R, element('w:r/(w:br,w:t"foo",w:cr,w:t"bar")')) + + assert "".join(r.itertext()) == "foobar" From badb007188414f5bbc8729012a9dfdc12025d0a6 Mon Sep 17 00:00:00 2001 From: Ethan Date: Tue, 8 Sep 2026 10:52:09 +0800 Subject: [PATCH 109/115] docs: fix documentation build with src layout and uv --- Makefile | 2 +- docs/conf.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 47f6e7cd..435d60c2 100644 --- a/Makefile +++ b/Makefile @@ -43,7 +43,7 @@ coverage: uv run pytest --cov-report term-missing --cov=docx tests/ docs: - $(MAKE) -C docs html + $(MAKE) -C docs html SPHINXBUILD="uv run sphinx-build" install: pip install -Ue . diff --git a/docs/conf.py b/docs/conf.py index 81a18b59..e5330679 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -13,7 +13,7 @@ # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # -sys.path.insert(0, os.path.abspath("..")) +sys.path.insert(0, os.path.abspath("../src")) from docx import __version__ # noqa From 894a71ef28eb10b8875091ecbe360e7c75a799a6 Mon Sep 17 00:00:00 2001 From: Ethan Date: Tue, 8 Sep 2026 10:52:09 +0800 Subject: [PATCH 110/115] release: v0.3.1 --- HISTORY.md | 5 +++++ src/docx/__init__.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index ab249451..ef4a6d8c 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,11 @@ **Unreleased** +**0.3.1 (2026-09-08)** + +- Fixed an issue where calling `itertext()` on oxml elements produced duplicated + text due to overridden `.text` properties. + **0.3.0 (2026-08-29)** - Added opt-in package-level document sanitization for personal metadata, diff --git a/src/docx/__init__.py b/src/docx/__init__.py index 9bca648e..26d150d5 100644 --- a/src/docx/__init__.py +++ b/src/docx/__init__.py @@ -13,7 +13,7 @@ if TYPE_CHECKING: from docx.opc.part import Part -__version__ = "0.3.0" +__version__ = "0.3.1" __all__ = ["Document"] From 31c2c5165bb08e3cc821e3e4e270d487c885c160 Mon Sep 17 00:00:00 2001 From: Ethan Date: Tue, 8 Sep 2026 11:05:30 +0800 Subject: [PATCH 111/115] test: fix pyright type check errors in integration tests --- tests/integration/customxml/test_custom_xml_roundtrip.py | 2 +- tests/integration/test_word_roundtrip.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/customxml/test_custom_xml_roundtrip.py b/tests/integration/customxml/test_custom_xml_roundtrip.py index 0bb588ac..9f9a3e1a 100644 --- a/tests/integration/customxml/test_custom_xml_roundtrip.py +++ b/tests/integration/customxml/test_custom_xml_roundtrip.py @@ -97,7 +97,7 @@ def it_round_trips_replacing_a_custom_xml_part_element(self): replaced = _parts_by_name(reopened)["/customXml/item1.xml"] assert replaced.tag == "{urn:python-docx-oss:wrapper}wrapper" - assert replaced.attrib["version"] == "1" + assert replaced.attrib["version"] == "1" # pyright: ignore[reportUnknownMemberType] assert len(replaced.items) == 1 assert replaced.items[0].tag == f"{{{CUSTOMERS_NS}}}customers" assert len(replaced.items[0]) == 2 diff --git a/tests/integration/test_word_roundtrip.py b/tests/integration/test_word_roundtrip.py index 0ab987fe..f0dfb285 100644 --- a/tests/integration/test_word_roundtrip.py +++ b/tests/integration/test_word_roundtrip.py @@ -115,7 +115,7 @@ def it_round_trips_a_changed_external_hyperlink_target(self): text.text = "Business link" run.append(text) hyperlink.append(run) - paragraph._p.append(hyperlink) + paragraph._p.append(hyperlink) # pyright: ignore[reportPrivateUsage] new_target = "https://example.invalid/objects/new-id?position=begin" document.part.rels[relationship_id].target_ref = new_target From 704036fccbb88ea3564e59ffe4d826080d3e1cbd Mon Sep 17 00:00:00 2001 From: Ethan Date: Tue, 8 Sep 2026 15:26:55 +0800 Subject: [PATCH 112/115] fix(oxml): use .texts on oxml elements to preserve lxml text descriptor and itertext semantics --- docs/user/compatibility.rst | 8 ++++++++ src/docx/oxml/text/hyperlink.py | 4 ++-- src/docx/oxml/text/paragraph.py | 4 ++-- src/docx/oxml/text/run.py | 20 ++++++++------------ src/docx/oxml/xmlchemy.py | 23 +---------------------- src/docx/table.py | 2 +- src/docx/text/hyperlink.py | 2 +- src/docx/text/paragraph.py | 2 +- src/docx/text/run.py | 4 ++-- tests/oxml/test_xmlchemy.py | 21 ++++++++++++++++++++- tests/oxml/text/test_hyperlink.py | 5 +++-- tests/oxml/text/test_run.py | 10 +++++++--- 12 files changed, 56 insertions(+), 49 deletions(-) diff --git a/docs/user/compatibility.rst b/docs/user/compatibility.rst index 86498f89..ea2c4771 100644 --- a/docs/user/compatibility.rst +++ b/docs/user/compatibility.rst @@ -43,6 +43,14 @@ public inherited API or its observable behavior. Each record must identify: * the ``python-docx-oss`` behavior and rationale; and * any migration action required by callers. +Preservation of lxml ``_Element.text`` and ``itertext()`` semantics +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* **Affected API**: Low-level OXML element classes (``CT_P``, ``CT_R``, ``CT_Hyperlink`` in ``docx.oxml``) and observable ``element.itertext()`` / ``element.text`` behavior on XML elements. +* **Upstream baseline (v1.2.0)**: Upstream defined ``@property def text`` on ``CT_P``, ``CT_R``, and ``CT_Hyperlink`` to return concatenated run/paragraph text. Overriding the Cython descriptor ``_Element.text`` on ``ElementBase`` subclasses causes standard ``lxml`` C-level tree iteration (``itertext()``) to invoke the Python property. As a consequence, calling ``itertext()`` on parent elements or on bare ``lxml.etree._Element`` nodes (such as revision tags ``w:ins``, ``w:del``, or container tags like ``w:txbxContent``) visits both the container node and child ```` nodes, causing text to be duplicated (e.g., ``"Beta"`` becomes ``"BetaBeta"``). +* **python-docx-oss behavior and rationale**: ``python-docx-oss`` intentionally does not override the ``.text`` property on any ``BaseOxmlElement`` subclass. Rich-text extraction and assignment at the OXML element level is named ``.texts`` (e.g., ``_r.texts``, ``_p.texts``, ``_hyperlink.texts``). Public proxy classes (|Paragraph|, |Run|, |Hyperlink|, and |_Cell|) continue to expose their standard ``.text`` property, delegating internally to ``.texts``. This design preserves standard ``lxml`` descriptor semantics, ensuring that ``itertext()`` produces clean, single-occurrence text across all XML elements. +* **Migration action**: Callers using public proxy objects (such as ``paragraph.text`` or ``run.text``) require no changes. Callers interacting directly with low-level OXML element instances (e.g., ``run._r``) should use ``.texts`` instead of ``.text`` for rich-text assembly, or standard ``lxml`` methods like ``element.itertext()``. + Additive APIs and capabilities do not require individual divergence records; they belong in the API documentation and Capability Matrix. Upstream baseline changes follow the :doc:`../dev/upstream-maintenance` policy. diff --git a/src/docx/oxml/text/hyperlink.py b/src/docx/oxml/text/hyperlink.py index 38a33ff1..39340e15 100644 --- a/src/docx/oxml/text/hyperlink.py +++ b/src/docx/oxml/text/hyperlink.py @@ -37,9 +37,9 @@ def lastRenderedPageBreaks(self) -> List[CT_LastRenderedPageBreak]: return self.xpath("./w:r/w:lastRenderedPageBreak") @property - def text(self) -> str: # pyright: ignore[reportIncompatibleMethodOverride] + def texts(self) -> str: """The textual content of this hyperlink. `CT_Hyperlink` stores the hyperlink-text as one or more `w:r` children. """ - return "".join(r.text for r in self.xpath("w:r")) + return "".join(r.texts for r in self.xpath("w:r")) diff --git a/src/docx/oxml/text/paragraph.py b/src/docx/oxml/text/paragraph.py index 63e96f31..d3aedf5e 100644 --- a/src/docx/oxml/text/paragraph.py +++ b/src/docx/oxml/text/paragraph.py @@ -93,13 +93,13 @@ def style(self, style: str | None): pPr.style = style @property - def text(self): # pyright: ignore[reportIncompatibleMethodOverride] + def texts(self) -> str: """The textual content of this paragraph. Inner-content child elements like `w:r` and `w:hyperlink` are translated to their text equivalent. """ - return "".join(e.text for e in self.xpath("w:r | w:hyperlink")) + return "".join(e.texts for e in self.xpath("w:r | w:hyperlink")) def _insert_pPr(self, pPr: CT_PPr) -> CT_PPr: self.insert(0, pPr) diff --git a/src/docx/oxml/text/run.py b/src/docx/oxml/text/run.py index e6de1bc6..de7bb416 100644 --- a/src/docx/oxml/text/run.py +++ b/src/docx/oxml/text/run.py @@ -127,29 +127,25 @@ def style(self, style: str | None): rPr.style = style @property - def text(self) -> str: + def texts(self) -> str: """The textual content of this run. Inner-content child elements like `w:tab` are translated to their text equivalent. + + Note: We intentionally do NOT define `@property def text` on CT_R or any + other oxml element, because doing so overrides lxml's Cython descriptor + `_Element.text`, which corrupts lxml `itertext()` on parent elements (such + as bare `_Element` revision tags `w:ins`, `w:del`, etc.). """ return "".join( str(e) for e in self.xpath("w:br | w:cr | w:noBreakHyphen | w:ptab | w:t | w:tab") ) - @text.setter - def text(self, text: str): # pyright: ignore[reportIncompatibleMethodOverride] - self.clear_content() - _RunContentAppender.append_to_run_from_text(self, text) - - @property - def texts(self) -> str: - """Alias for `text` property for compatibility with python-docx-oss.""" - return self.text - @texts.setter def texts(self, text: str): - self.text = text + self.clear_content() + _RunContentAppender.append_to_run_from_text(self, text) def _insert_rPr(self, rPr: CT_RPr) -> CT_RPr: self.insert(0, rPr) diff --git a/src/docx/oxml/xmlchemy.py b/src/docx/oxml/xmlchemy.py index 0ef5b138..54237b12 100644 --- a/src/docx/oxml/xmlchemy.py +++ b/src/docx/oxml/xmlchemy.py @@ -5,7 +5,7 @@ from __future__ import annotations import re -from typing import TYPE_CHECKING, Any, Callable, Iterator, Sequence, Type, TypeVar +from typing import TYPE_CHECKING, Any, Callable, Sequence, Type, TypeVar from lxml import etree from lxml.etree import ElementBase, _Element # pyright: ignore[reportPrivateUsage] @@ -653,11 +653,6 @@ def _remove_choice_group_method_name(self): return "_remove_%s" % self._prop_name -# -- raw lxml text/tail accessors, used to bypass `.text` property overrides -- -_raw_text = _Element.text.__get__ -_raw_tail = _Element.tail.__get__ - - # -- lxml typing isn't quite right here, just ignore this error on _Element -- class BaseOxmlElement(etree.ElementBase, metaclass=MetaOxmlElement): """Effective base class for all custom element classes. @@ -688,22 +683,6 @@ def insert_element_before(self, elm: ElementBase, *tagnames: str): self.append(elm) return elm - def itertext(self, tag: Any | None = None, *tags: Any, with_tail: bool = True) -> Iterator[str]: - """Iterate over text content of this element and its descendants. - - Bypasses the overridden `.text` properties on custom oxml element classes (such as - `CT_P`, `CT_R`, `CT_Hyperlink`), which would otherwise duplicate text, so standard - lxml `itertext()` semantics are preserved. - """ - for node in self.iter(tag, *tags): - text = _raw_text(node) - if text: - yield text - if with_tail and node is not self: - tail = _raw_tail(node) - if tail: - yield tail - def remove_all(self, *tagnames: str) -> None: """Remove child elements with tagname (e.g. "a:p") in `tagnames`.""" for tagname in tagnames: diff --git a/src/docx/table.py b/src/docx/table.py index 545c4688..5ff881c0 100644 --- a/src/docx/table.py +++ b/src/docx/table.py @@ -281,7 +281,7 @@ def text(self, text: str): tc.clear_content() p = tc.add_p() r = p.add_r() - r.text = text + r.texts = text @property def vertical_alignment(self): diff --git a/src/docx/text/hyperlink.py b/src/docx/text/hyperlink.py index a23df1c7..0a0ba13b 100644 --- a/src/docx/text/hyperlink.py +++ b/src/docx/text/hyperlink.py @@ -98,7 +98,7 @@ def text(self) -> str: respectively. Note that rendered page-breaks can occur within a hyperlink but they are not reflected in this text. """ - return self._hyperlink.text + return self._hyperlink.texts @property def url(self) -> str: diff --git a/src/docx/text/paragraph.py b/src/docx/text/paragraph.py index 234ea66c..fff2d8b9 100644 --- a/src/docx/text/paragraph.py +++ b/src/docx/text/paragraph.py @@ -160,7 +160,7 @@ def text(self) -> str: character is mapped to a line break. Paragraph-level formatting, such as style, is preserved. All run-level formatting, such as bold or italic, is removed. """ - return self._p.text + return self._p.texts @text.setter def text(self, text: str | None): diff --git a/src/docx/text/run.py b/src/docx/text/run.py index 4adf956e..1643c775 100644 --- a/src/docx/text/run.py +++ b/src/docx/text/run.py @@ -233,11 +233,11 @@ def text(self) -> str: `` element. Any existing run content is replaced. Run formatting is preserved. """ - return self._r.text + return self._r.texts @text.setter def text(self, text: str): - self._r.text = text + self._r.texts = text @property def underline(self) -> bool | WD_UNDERLINE | None: diff --git a/tests/oxml/test_xmlchemy.py b/tests/oxml/test_xmlchemy.py index ed12e107..89c397ce 100644 --- a/tests/oxml/test_xmlchemy.py +++ b/tests/oxml/test_xmlchemy.py @@ -1,6 +1,7 @@ """Test suite for docx.oxml.xmlchemy.""" import pytest +from lxml import etree from docx.oxml.exceptions import InvalidXmlError from docx.oxml.ns import qn @@ -48,7 +49,7 @@ def it_can_remove_all_children_with_name_in_sequence(self, remove_fixture): element.remove_all(*tagnames) assert element.xml == expected_xml - def it_iterates_text_without_duplication_when_text_property_is_overridden(self): + def it_iterates_text_without_duplication_on_oxml_elements(self): elm = parse_xml( '' "foo" @@ -58,6 +59,24 @@ def it_iterates_text_without_duplication_when_text_property_is_overridden(self): assert "".join(elm.itertext()) == "foobar" assert list(elm.itertext(qn("w:t"))) == ["foo", "bar"] + def it_iterates_text_without_duplication_on_unregistered_bare_elements(self): + # Tags like w:ins, w:del, w:txbxContent are not registered in element_class_lookup + # and remain bare lxml.etree._Element instances. + ins = parse_xml( + '' + "Beta" + "" + ) + assert type(ins) is etree._Element + assert list(ins.itertext()) == ["Beta"] + assert "".join(ins.itertext()) == "Beta" + + # Verify CT_R inside it has native None for .text and "Beta" for .texts + r = ins.findall(qn("w:r"))[0] + assert r.text is None + assert r.texts == "Beta" + # fixtures --------------------------------------------- @pytest.fixture( diff --git a/tests/oxml/text/test_hyperlink.py b/tests/oxml/text/test_hyperlink.py index f5cec476..f0f1c833 100644 --- a/tests/oxml/text/test_hyperlink.py +++ b/tests/oxml/text/test_hyperlink.py @@ -41,5 +41,6 @@ def it_has_zero_or_more_runs_containing_the_hyperlink_text(self): rs = hyperlink.r_lst assert [type(r) for r in rs] == [CT_R, CT_R] - assert rs[0].text == "blog" - assert rs[1].text == " post" + assert rs[0].texts == "blog" + assert rs[1].texts == " post" + assert hyperlink.texts == "blog post" diff --git a/tests/oxml/text/test_run.py b/tests/oxml/text/test_run.py index 1c9638fe..6f37f81f 100644 --- a/tests/oxml/text/test_run.py +++ b/tests/oxml/text/test_run.py @@ -38,18 +38,22 @@ def it_can_assemble_the_text_in_the_run(self): cxml = 'w:r/(w:br,w:cr,w:noBreakHyphen,w:ptab,w:t"foobar",w:tab)' r = cast(CT_R, element(cxml)) - assert r.text == "\n\n-\tfoobar\t" + assert r.texts == "\n\n-\tfoobar\t" - def it_provides_texts_alias_for_text(self): + def it_can_replace_its_text(self): r = cast(CT_R, element('w:r/w:t"alias"')) assert r.texts == "alias" r.texts = "updated" - assert r.text == "updated" + assert r.texts == "updated" def it_iterates_text_without_duplication(self): r = cast(CT_R, element('w:r/(w:br,w:t"foo",w:cr,w:t"bar")')) assert "".join(r.itertext()) == "foobar" + + def it_does_not_override_element_text_descriptor(self): + r = cast(CT_R, element('w:r/w:t"foo"')) + assert r.text is None From 9d41d1d5425a80c1e9a752fa991df0ca35a1094b Mon Sep 17 00:00:00 2001 From: Ethan Date: Tue, 8 Sep 2026 15:35:10 +0800 Subject: [PATCH 113/115] release: v0.3.2 --- HISTORY.md | 10 +++++++++- README.md | 5 +++++ src/docx/__init__.py | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index ef4a6d8c..44abb9de 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,7 +2,15 @@ **Unreleased** -**0.3.1 (2026-09-08)** +**0.3.2 (2026-09-08)** + +- Restored the 0.0.12 architecture where OXML elements (`CT_R`, `CT_P`, `CT_Hyperlink`) + do not override lxml's Cython `_Element.text` descriptor, resolving text duplication + when calling `itertext()` on bare `lxml.etree._Element` parent nodes (such as revision + tags `w:ins`, `w:del`, and container tags like `w:txbxContent`). +- Standardized OXML rich-text extraction and assignment on `.texts`, while maintaining full + compatibility for public proxy APIs (`Paragraph.text`, `Run.text`, `Hyperlink.text`, `_Cell.text`). +- Documented the intentional upstream difference in the compatibility guide. - Fixed an issue where calling `itertext()` on oxml elements produced duplicated text due to overridden `.text` properties. diff --git a/README.md b/README.md index 95400aa5..86815496 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,11 @@ available through `Document.add_float_picture()` and `Run.add_float_picture()`. - The project maintains broad compatibility with the public `python-docx` API while following its own versioning and product roadmap. +- Clean lxml integration: Low-level OXML elements avoid shadowing lxml's Cython + `_Element.text` descriptor (using `.texts` internally). This guarantees that standard + `element.itertext()` on parent elements and untyped revision nodes (`w:ins`, `w:del`, + `w:txbxContent`) never duplicates text, while high-level proxy APIs (`paragraph.text`, + `run.text`) remain fully compatible with `python-docx`. - Compatibility does not extend to every private or internal `python-docx` API. Test those integrations before migrating production systems. - The SDK focuses exclusively on DOCX. It is not a general XLSX/PPTX Office suite. diff --git a/src/docx/__init__.py b/src/docx/__init__.py index 26d150d5..7f91a30a 100644 --- a/src/docx/__init__.py +++ b/src/docx/__init__.py @@ -13,7 +13,7 @@ if TYPE_CHECKING: from docx.opc.part import Part -__version__ = "0.3.1" +__version__ = "0.3.2" __all__ = ["Document"] From 13b2ca0640f585f0f820b01fa855ebb2c20b9c81 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 10 Sep 2026 14:12:55 +0800 Subject: [PATCH 114/115] Publish to PyPI via GitHub Actions Trusted Publishing --- .github/workflows/publish-pypi.yml | 149 +++++++++++++++++++++++++++++ .github/workflows/release.yml | 76 --------------- 2 files changed, 149 insertions(+), 76 deletions(-) create mode 100644 .github/workflows/publish-pypi.yml delete mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml new file mode 100644 index 00000000..d8245f91 --- /dev/null +++ b/.github/workflows/publish-pypi.yml @@ -0,0 +1,149 @@ +name: Publish to PyPI + +on: + release: + types: [published] + workflow_dispatch: + inputs: + target: + description: "Target repository" + required: true + default: "testpypi" + type: choice + options: + - testpypi + - pypi + +permissions: + contents: read + +jobs: + build: + name: Build distribution packages + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + ref: ${{ github.event.release.tag_name || github.ref }} + + - name: Set up Python + uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0 + with: + python-version: "3.12" + cache: pip + cache-dependency-path: | + requirements.txt + requirements-test.txt + + - name: Verify release tag matches package version + if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'pypi') + env: + EVENT_NAME: ${{ github.event_name }} + RELEASE_TAG: ${{ github.event.release.tag_name }} + REF_TYPE: ${{ github.ref_type }} + REF_NAME: ${{ github.ref_name }} + run: | + python3 -c " + import ast, os, sys + event = os.environ.get('EVENT_NAME', '') + if event == 'release': + tag = os.environ.get('RELEASE_TAG', '').lstrip('v') + else: + ref_type = os.environ.get('REF_TYPE', '') + if ref_type != 'tag': + sys.exit(f'Manual dispatch to production PyPI requires dispatching from a git tag, got ref_type={ref_type!r}') + tag = os.environ.get('REF_NAME', '').lstrip('v') + + if not tag: + sys.exit('No release tag specified for production PyPI release') + + tree = ast.parse(open('src/docx/__init__.py', 'r', encoding='utf-8').read()) + version = None + for node in tree.body: + if isinstance(node, ast.Assign): + for target in node.targets: + if isinstance(target, ast.Name) and target.id == '__version__': + if isinstance(node.value, ast.Constant): + version = node.value.value + elif hasattr(node.value, 's'): + version = node.value.s + break + if not version: + sys.exit('Could not find __version__ in src/docx/__init__.py') + + if tag != version: + sys.exit(f'Release tag mismatch: tag={tag} vs __version__={version}') + print(f'Release tag matches package version: {version}') + " + + - name: Install build tools and test dependencies + run: | + python -m pip install --upgrade pip build twine + python -m pip install --editable . --requirement requirements-test.txt + + - name: Run unit and integration tests + run: python -m pytest -q + + - name: Run acceptance tests + run: python -m behave --format progress --stop --tags=-wip + + - name: Build sdist and wheel + run: python -m build + + - name: Check package distribution metadata + run: python -m twine check --strict dist/* + + - name: Install and verify distribution + run: | + python -m pip install --force-reinstall dist/python_docx_oss-*-py3-none-any.whl + package_version="$(python -c 'import docx; print(docx.__version__)')" + echo "Verified package install: docx.__version__=${package_version}" + + - name: Store distribution packages + uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1 + with: + name: python-package-distributions + path: dist/ + if-no-files-found: error + + publish-testpypi: + name: Publish to TestPyPI + needs: build + if: github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'testpypi' + runs-on: ubuntu-latest + environment: + name: testpypi + url: https://test.pypi.org/p/python-docx-oss + permissions: + id-token: write + steps: + - name: Download distribution packages + uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9 + with: + name: python-package-distributions + path: dist/ + + - name: Publish to TestPyPI + uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # v1.12.4 + with: + repository-url: https://test.pypi.org/legacy/ + + publish-pypi: + name: Publish to PyPI + needs: build + if: (github.event_name == 'release' && github.event.action == 'published' && !github.event.release.prerelease) || (github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'pypi' && github.ref_type == 'tag') + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/python-docx-oss + permissions: + id-token: write + steps: + - name: Download distribution packages + uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9 + with: + name: python-package-distributions + path: dist/ + + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # v1.12.4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 93a2e717..00000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,76 +0,0 @@ -name: Release - -on: - release: - types: [published] - -permissions: - contents: read - -jobs: - test: - name: Test Python ${{ matrix.python-version }} - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - python-version: ["3.12", "3.13", "3.14"] - - steps: - - uses: actions/checkout@v5 - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v6 - with: - python-version: ${{ matrix.python-version }} - cache: pip - cache-dependency-path: requirements-test.txt - - - name: Install test dependencies - run: | - python -m pip install --upgrade pip - python -m pip install --editable . --requirement requirements-test.txt - - - name: Verify release version - run: | - package_version="$(python -c 'import docx; print(docx.__version__)')" - tag_version="${GITHUB_REF_NAME#v}" - test "$package_version" = "$tag_version" - - - name: Run unit and integration tests - run: python -m pytest -q - - - name: Run acceptance tests - run: python -m behave --format progress --stop --tags=-wip - - package: - name: Verify release distributions - needs: test - runs-on: ubuntu-latest - permissions: - contents: read - - steps: - - uses: actions/checkout@v5 - - - name: Set up Python - uses: actions/setup-python@v6 - with: - python-version: "3.12" - - - name: Build distributions - run: | - python -m pip install --upgrade build twine - python -m build - release_version="${GITHUB_REF_NAME#v}" - python -m twine check \ - "dist/python_docx_oss-${release_version}-py3-none-any.whl" \ - "dist/python_docx_oss-${release_version}.tar.gz" - - - name: Install and verify distribution - run: | - tag_version="${GITHUB_REF_NAME#v}" - python -m pip install --force-reinstall \ - "dist/python_docx_oss-${tag_version}-py3-none-any.whl" - package_version="$(python -c 'import docx; print(docx.__version__)')" - test "$package_version" = "$tag_version" From 7f0cc27bd2e2cea01031c51a4176116ae57d406c Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 10 Sep 2026 14:22:51 +0800 Subject: [PATCH 115/115] release: v0.3.3 --- HISTORY.md | 6 +++++- src/docx/__init__.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 44abb9de..2ce625b8 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,10 @@ ## Release History -**Unreleased** +**0.3.3 (2026-09-10)** + +- Switched PyPI distribution to GitHub Actions automated releases using PyPI Trusted Publishing (OIDC). +- Added support for workflow_dispatch triggers targeting TestPyPI and PyPI. +- Streamlined release validation, test gatekeeping, and distribution verification. **0.3.2 (2026-09-08)** diff --git a/src/docx/__init__.py b/src/docx/__init__.py index 7f91a30a..9385b876 100644 --- a/src/docx/__init__.py +++ b/src/docx/__init__.py @@ -13,7 +13,7 @@ if TYPE_CHECKING: from docx.opc.part import Part -__version__ = "0.3.2" +__version__ = "0.3.3" __all__ = ["Document"]

    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ⅆ318E&`P#>?K3TB z@|zI_R$N++G={6+OP|TfgeQ_+}YN9{hv0PCAtf0$15C?dCO~zg`9-TaYdc`}b-~;;v^8 zL^r+4TT+D9C?mS(C=r1xqF&K7%8FNM&rSu(ZM1HX%&+3qJQ^}I$W6^HMA_>(6S{yA zPVKy~OwdYNX{~Ww8oGLsUf_~sK(p!lG8W&Yz2t?Aq0hUS$QJlgJ}}hCABD2JgaOHs zOXa(GR&K*4aLKYCLx#!@75;_W)%MD?oKndy?|l}Zh96hiTLuq5HqSOLXk67ki7Tih zxO|C%7`z%lY!Av$l*q!AzMghqxH{H$C{Eqvgjd!%*Ek0+>sF_f)F^N~8vyy&xM7>u z4bJ`^E8^LW<(UN6udJh}W%W3}Dcsn=m3H-WR$H_Bdy-ua>#Qh87ZwF@`V>+qhtlL~ z{TKp#Mu{lBwviDO(-z$JZFdX(*U!lyXPLU_7n zqQI|Bxm?@8T?qYzZtYHszs_&pbBdv;Z$1z=-c=hK$WOoEI9~pu-;)vlG-bq*bO=Ti- zN&tbTvF_!SR}_HUbz!DKLHT|NKF1qnSi^%x$6@3%Wk7yy_a*Pt8}jH`Gi8usY$85} zYv#mR@r|i_~eL~|D zN^r+IUG8n+TIkU}hhgKk#RMu@m63k@@VRzl7~b=dHVW*x?LrnbaJX}M9|NKN&^Wtx zl!qDR3VwS&&n|6uA482h8!WqLxk$G-_f&!-f4Y{MWoL=9rm<1}PGZPVwl_EKx5X1P zwA(qx6AXzM#vB`^lZD>oz&J~}hdDPxc)IG^!06!^HqKcU$4`&5TLNRjRTR7+o<)9X z^&C{bp9Ny8oULKIIr+>O?SOFH{WvDP_&Ns}W2D&H+(zL&fg8B}wsIH6Kk-M;&tMcN zqwo@LsWc2x;$g1ha9Kll!ZRbx1zjC;thhih-|ZN+uagZ+&* zf9x!-vSypp99?wUgl5@ka`qUs9XUYBU9R0uJlbrRaZh*afZb{^%=YAWrtLRlGV&r} z%A%LePML6g4~;QuXw;{j+Jlh5U&df+*>;@o2=dv7Yy6Lqk~HSm7@@(V&lj8`BF?b7 z3RmEg-m${I!QCAG4%U|2AM7o(|L%9b-6k1Vbffh4XE)o0X$(+nAF>-`y4~ZDZ+e(~ zS3Gxorro=DuYJxT--Hysz>yxv&A0rRyCyQec;gUdi#^V z{89T~-o4FvaGfhFEQuO1rf`oo&*G%ZKYz1b`SATJ#NppV4jgjesp0^AN#Bb-RpmM? z%pnKCM1p3MZ4k5>?Mm4oT#sPeVwQN2D`{(;h#>>Z!s+;{;QfPK_U zDX)G&3ELIDc0o?6t0$5wN$4kYHCeR`CWwL%I;6)EmC&eSP0&%vi+sfS}wq3kjlmzOe(=OU1F1i zyzq>FRbJvE9Ku(oRpKEmJ-8lbhd1F}UQsA|J%0u~=<}FZ`owL1uGH1wU4EBfCfek} z=AU`ILZfd3`7lq#_3>4X4o??lnx15#@V3!ukP7@UjmBJl1j{-9SD!~1AKHeFvck|0s48BiDfyyY ze6U4CDa5yz2)9Rln#oiAMU!9QaPj?+rN&WG}-5) zFYuvRg-sbYA%jfj@xwm-M*48!bjsJzGfbhzVm7J-1l7J`) zq0_Q@ux+noaIDI>lZu5__#yY@hxJx<2mtev)^VqBm29gB(BLg?0~rC9v8J;P%QpZF z#xVKeW%(j2JO?jhk(V?^>1=uVRrx|f#Y0D!*YSiZt^N2#`is>Srebw1-#Js4R)1o3g9SR5=7n6oq`~bN;~g1}pI?yM_#vkmAx; zdlJdAL7927&=SyJJrj7Zbn>crT=R%MtiDX+xI)P)PJpO%vu*?^|EnEowA7F>hO(5E&#dy+Xs3czgGN85dO*GH zPlJZ;cBEH+crfucMhp3GA7R^Y%!)D_9=a^uLq@{`lr9U$S#?W6Rh(}wuOkl{7&y}b zj!8^ZRkq0{FmKy9mBN~nMP_AFiLLk;GNTvJV>ten=h z*L_wX8|CWb^ts3+B=du7l!M32eZBk3MO^CCgu=I;$pYkAW^70|>kECsq`cTRL;30Lo!?_qcD=DW2DqXcG>l#D= zkZ1X#+=gIbpr{?k(5~Xp^G57DYy+nA2vY47 z;*f85o8a?aCV9yBD82x#1J7WwElx3ZdWbf|4hnpBuE66VTqbR-ZpU?%=XXravU7v> zy@gTDGgs{M#&k;soy&LW>yY2)Uzn!N(Z+7I5*A?jtPt|58DgRPPKD$^X&#k zjGbYOEy(`z+G;zG3#$cJ)l(@Sdg${h``@j$HZsvJ-5bKa&~ST+zF>g^v2S3Y8JT~k zEzZn=W24Qx`3i)*S)_;%^TPulw*Uu}!DmviS% zQ6CfVa-zNR?eDc;|LU{t7X8`3XC?fbKmHN$=i1j^gjNi(sFq{ASXsT>9vq<#!4)~f zh&GNgTE#ol8~V=ic6?#39R;U{H1E)lEztk$-@V#?xy`+Ai`17pHyq#79_=Ig3pr8t z9VcyH&h7hMrMk9L<|FsWu(?1Bbv*H31EYq)J?cW(wuUii&8Saa6Fq4p4=h5x%fp&) zDXMcA8QT2D zy_;5NnR&OnJAJr>4ZdH z)A-?IT$EM@1XZW@;Mp=7=wI`Y*r&ir%z!@Whep!-@$Q7}?_8!ejgvUb)6vkU^F3Qz zLs`K|9Qk_EdYrY=w8}1Zy&gXIqPF`Bgy8Jy=2hG&hfs~L+haIgzyNE-=PzKKgj&WP zr{Thrx4~jL2}>C}DiTLv@xM4)H4vypLwL=*fCI?%PW=rl4utF;X0jHP!pL*d5g~}a z7-r(RFL%l*T4DSof;Dl9z&5+y77@?Wf#f>y+nwNPn#QhP;5L8#OnkYY1IkMUPqmUaUx zFZCa!mNTDb0^us$gS*faqX%4)LVRc!G#CQk0Dr==-S%y^4h~zeNRy8_+K>H{2>ei1xmU_4SAFXuLtw;4S;`}A!=DHLW~D7K<1Wu~CayjRRb+w{>WDqJ?{ylZK;4QLjXKtm8>glU5T4Mz2kk)J9%J#5(Otr3A`TYfDx&P zj0>SLoU1WM^!B|Pip05x@=8Oz3+a_3K7M)53u6)xV>pOMbXb~X;byjva>5+1T! z`QeBBNmBmszu=StU*3%SaUHo;=BmCeRFtB@0KJsgOa2noDc%HD354T|yL!A!i$SRy z9>gh(QgqjNov@5&&`sJHdB|P$1T5rIer%)A?hQb?5b_e63Mcs>F6&FfMU;UGO-I)t zv5-jHD^bPaB|RqA9gT9SLcezd6QdRKrV`WCrc5sWn9qNPbVW~Ojol^NM5f&GzZ#|C=LfjDTSbWSqoT6L@lYA1Wwk%?7tQ+Gx4r7B z$DL56ct-JqQdMQC@189XLkD4!or`|qAZG@MpZcTxF^nX#6r3tr$AP)!IT+BbqSkUo zAr9Trs&PoAs6NV#(;y}sC4Ooag9>z=ImfDac5Q6q(uOFMkYgOw%ozpLjePN^!c^i^ z>Zvr|LE$T$xw*-=?Bucq;dk1deJ~53zaYM zb##g-V~sM>(Ut?{VU~(!=}}g5<`FdItO7KTFUpW#sQ?98UTx{A^* zr#mbrXiF-NCD3t8gUk^Qvi7`;>f=yIV-SI~$jJ`vYJO>oTF_t#lPT8{hfup)N*=f) z$a>a&qDBpkgL|~Q#S`ob;v9@EaPQGBhp5+MoNe*)=|$2$Xdm3!piB?jru7j_Gekx)U|ItKyY1qI z^X*v=Bj;f6iMge=iBXb?3Bonrjx8R()B*A-`Y{K^l1v;FY3=h{_V#Qm#3{`2oWkNlImk@7&j`A2q>1qGxBn&;j(ilhKaJrd+w1L*Z#`=N`S1K%J3$|O z1lj)EE7v*LeWJa(_eFbWYq;HN>;Sag1OMFdg?6yH+&;-6-!+cL*w?{?|%L_b6!5ZvE0@kV0e*cNHiV)F)R+Z6UfXQJh{T5?+7b#@J;@hfK>9#Jo3|W4gm0& zzKC#A6fdANJSH>QkaT|XaB8N#IPIGGa1BV=V+Bk4% z$avan^sqcn1qZ(Qm9v>NXnb%E=VZyLg%dh=Wz;mIj1#UNG>sojnU}x;CoC!woVRFL z=#>{voSew?ik?jVoScxs6<)Q=gO7YBQ5rq=nJk(m1`N`P+sT`Bn8(Rm!SXYqF4H?< zlp;TfvMrQ!9qQbjIOd9in!M6z0Do$7<%Ehb-V0Wu5*Nh@NmCZ$nNx9@KM;K3jr1YB zv=W*0Lc5pgj88@o$fqc^4ExeWD(EW`d8P~`%%o1jf}dcasYEE(B;po&Lb+8PJY+IP zHSrD&VZ@V&`m{s=U!Hn7p-jDn07H8EC4)lqYQ6OQ`aAI?5M32kUXnKGC8TH^K=c9J z$&gIE=TfG?MaCy#<)tc`RM5|}w0^m0)`=iR%74@F{1|&-=mA$bo$G4yo&GGEVw{<-24VGx(~A|IsT31woiRauL=$25XGsf`Uh zd1|y}16J`cudrHP)`!d^>Q~Z+P#V-KVBS;bLh{#Lf#>ImAA=?T3V(tFzZBDbT_tZ3 zQ%Efjc%Ce~nWMlJ$d|4TK4JDiRo|7y{Ps~^eXf+xk1&;?C?WS*F&kwGtGx7s?ZLJ? zD0h^1Kl+8JQpFEB6`>jlR3=xSLo#9UK^)~y+6jF%A9RJVmy{}xyD!p9Ld*;&dQP(< zRQEC(A?9!`U|+9$sYk3vLst}~j|!S>#itAtlN=7o>PeZS1U>YSW5h`pBDF#rLkn^F zu!XLyDo({RW=Io>%K%f#)V?3J@}m@|uYTakukwu#aN!8obmoxx+KDHrjMOm;HnF)(Mj#371yO=zukp-42B#k^B)?;Hr${-7&0R`7aMjE`gB? zr5R^)SYdm(QmFofh@i66=C}SUy)I&W5`C1UNmnE)H?}8hS3mK}dlH(yqq&SFrOa_9 z;}9SE2ds9q4y2PJCy($8R>?~BsstL*@yivFqSy6Ib{O$&UHg;2UOlf&7tjeMo$_Gr zLd4xZ!gZP*f4U5VHVFO20oYERC7WRh>|-7yF}r;0`|Y~p_6UW$e%OatD!Q_|g946~ zpSUrpIw|@?GpsA42X#j~Q5hzG(~eQtJw&Njh7xeoH&vT~9_1yM?T5J!LRC9;q^S7O z9~Mng`#$61E1>{K{RrX5bs<>cT!Wjk%N{UR&Co>7g?b# zj&XKRcs|D_%1M>9)9%uOPboUR{;n z@0|Clx+Ou7z6iujz3%$I_wI7;x#ym{ymRh7=lzeO?PLrE+v}X(a2`}>Z$GO0M;m6q zx;fpUz`7M-n7p8(O(kwilgeOC5$%>|Ui>`i`pc`|{RVKsADY{0DX^9ARN5&xS0Mzi zFz!eL+b72RXlwb`?p%#~Kyb{Heum3u@>lQ+&oohlDX5cm+G!`1Alq9J5&glFJq|W1 z4Wj>3Ty#|6cyhsd+Lpqul{wB8uJOVI74)#*%NHtN92>;nlSwKn6i|zY%8%$GOB*BJ`wP`uiKph>nxt2OSXKyg5%lqxDM@|G5+||RFsm_mo9Wm(YZ9Ld$ODyxEHY|JLnWWe_LfPfU%#OE5+U0%jB$os5^7 z9x`nFaIIXqH(#zDbkh%9DfMrhL;mKSy8W&Ax5Fa4Z$S2knF9B4)2{a{^** zVJ?)%<{~mqV422#reaPQ_EqNw`?t#17&C~deJz;2{tlHFy&zqT8$Qc#^|!JxbcB8F z=G}5*^2PGser~d0b*ya8-7R-eD13RCzI*?AdA(s6UZSr9&kZV%4Y!pW)O!vlanql0 zEZ4hcs(3`frIH1F!EGF6Q}=@v%x}@pIDO$b9eDyFztJ7fr~~iP#pgI-7~%GnAV)mJ zcO(IpmzQ#Pv?PKE2ad$`T9HMSKqi%HkalYXVWZRgEYfzUQg40nfdVDa_jo_tm4V< z2?b6l@FPV5#%)H0lk0>6ClvTZQQ*Z3lPs28xVV7efeBxQguT^;m7Ug)a{k8x&5w{+ z>~VKd;(|f56E2L*;|E(TN?F}_ER*#XFwNy+&P6S2V(vN=_j1vuV8Ydoi=+(8bYzS& zTtLMlk4V$_krKj(NL?*@NaIdfmp?9=#6|3V_p;n5pJ!sL&{$&yEP^7;IRAUaq6?ZB zrhp~`i4MBBXd{e2yaas9N&JMAv~xLEEffu` zVEBP#eass}E2!iMn{^hxc*X~p=>m$d2%}C(8}nrPXz4`CQmW)tTmn7{_QAS86dW0B zQa=u}J^_(hWtrw7I^agS2sgm+<1|@thDBsuh`5>7a=H8QYlzQzio)`I%Xia7TSlq~ zu6{DtQTrr>jI%7u380oCt@1sB;yKHyX&4#JW(P45SCkz>S6Vahcd;+OB!52)H!JZd ztpaw`PZ~o|%FT8Z_(OQ{`Y0@EL;8wl!tr`IjVRi8U_oQ}1E6=)R`rjY(N$D^_cgDK zkQ@QxC^Xx#?sFkTIcfzzn(Fe*VCF!=>cx&%g+#4$)zcOX?H}WME ze?>XlsBZg*!z`g5JED)0GjI#MGygG-6xt9Qm8#$h-yDX)v_V@-PXwX{mS=q6!Pw;e zD9o|Vk6-N1YX&2Co#HUHLwocs2ov4GrpW>6AX1EWv_&LCa6go>mEWE=Oo^>+wTrig?G^h$>BWdc&~86wr@hXrXWsJ1T`Gz06*00%l5KG zo%^I)&1c^0wiM1jN(ym?8otHTYeuApDQG&Ty0q)|`dL7Sj^z;-UF+JW~JI3b)v zQE=wWSXsrt#eGf=gpUZ7IgZJur|2-t2FdNW@}>Oc>4@+>1KnJUIPM!B^Sa1A*=qaCBmAdi#dLaTOXh<|Cs+_#D8oH+9t<)C@bV^@Cuad;B~mP7z*z zeEnXzaPCyOa~DAoxNXrN&ObI)o_^{)g34a#(Ohm4clFwJ6dSE&Vtg3E@+PpB%3XwX z`zl>+7zj2wIf3G)wcNgaKLn`upD_fScW>MeVRrDftU(=Y8-?{feO>HmXNNAdvrRRz z)P_(w`<*9qcFN@WC(HBCeY$+@xBeM@!t$UwJg%c_cj7DX1T210RD30GghO`fX}da> zJAQb@FF(G9V9&9^zRWl#&xAt40vM-l4{0SXmZw=F1?+Lz-{29)Q<89!n(>N&C`SAg zs760X<)wmO$9l&A(|GE_EAWuNm}(!6a!GA@Mtj0g0l##zAL$E5p5Mihbt}$v zZF9$X$0au{sRVUbv*h_zqW#) zAEgGm5W+l7hd`Z^6OaPsJ|-7Yo;YVVpcwI6!+z!|r8NYi!q?%seYmfm69HVS@R6n) z55czyCClgt3L(tTsBrJc9Mtujvp5>(nZDE0ITC!lhRH4KI>&hPh zEZK&imgsv=y)aVX`qIrQs5$t;u008#OV``b>+Z}d4vl-trRj0{AAUPJ2a?8(n3|%^ z`&o~)>~n&trMo<6>_FJtfs%?%6;06Ufg3IkF*^m$)N#KJg(LXmS-sp{!r}2=Q#m_z zI@(kGiR2abYp~rpgRyZ{Kw8-k|Lq zi&ZFgkDM;g)A#S8n0fP!H_AW$$G=jZXB>Fu=}TdXZj*LYpx;JcaJRnmuMWi9F`;w{ z<>!MY%IqFuz2%86Ph0Gl9tN<(xf|uR4OKcS1K~gFt4SfpEcrirRP?!=dpv#Ny2deB zA^RRC#-6xvuC(;_mUr&2m(CUZ{;Vx9meXH}x8{!d_8l+jxd-FeKAy%1g(r2^SDJMd zH)$5-%WORJKkugCITWGLNYhU~H*K$#U%9$o{>@+f+456EDB|c>m#Ugpt@MMvg&9o+bmGsnM$f$q_7Hb8PdwfkP9gntMM^k<z0mHIg1?^dcm15k7BbtFBC8d>xPp{3w)qv1sLPI^p^ha3eiG z5#gQGM?fM~lxZ&CGH>+;Uhz&;P0z?1V6yzIj|t44chja|B|t_LPk~R+K7wmZlLmF! ziDs1_I>7<~mdq8L%vUc=kKk4{m(GEVG<~F=BKSwIg!KqbsybL+7Fg#qZC-VVIHv%P zkN}l+spAcjhoX&5!2hhjDU3DDJmPF|gbT{DeV2~$6v2s74V>_Yt7x7Sh-HR+ugj@3 ziAln$KajG>I-Pm5#6%%eCtUfd;@ujwdPKuBhfEDLtAxDgt z&@-*i*(V+uFEUA0m!xIghLSVtXj_W(L;X*>)MM09#i|OL$B*&ITa{VEY*CTGz~YB% zCw8~pxvj!x3&EE{9)-J>BPIb~B=~cz5Qgn}$Sz^cY=kKuhPg-wFDi_YCUskzFHETL zVcylNxdnk@bDtf~3ZXRZV_8zqv0gJ5eyF?KHE^H|cd4eJE8A0iEiXRusHeLab7y(| z;h(z~vs{2ym-G^U1)KF1!d%LW9k|wm`6Y$zq#%RBM1>*lj8&kgDF+2cfwuxYgaeu= z5_Zx%Kgy+8mIq8~7tX7psPj%-(zl*dBCXVphnVZkD+`4{g)9w}D}Qxkw|j*h#Ub3L zF1AT#BLnql>z^oH{X=DK<~j-?Y&Fv!F^T}A<|Cj%2ZEz5vt0Y2SNsyLP@#=oeY@=P z+r?q0^i4&G0y7=eGGBTkfI7q&1{i5k(@wfMztsXE+cK0AR4n0GF0>?1JUPkpl)eC@ zccmbKUde;9O}34~`VdCIhZ4D_fo&uV`73yxxO!}fnvq@ssM%BoIkyJPAhvlWiT(4K z4$>_8s%ie%l{AYojU%u49ObXlN8hLZM+`xl>__IQ%Hko~$MIZR2`jEF*Es3!X$ut; zt|K(jBfZ0~hoHz~TPX0Y6+jA4g{N@eHjL9Ff(C5zJ~V}HAsCkCQJlit6jIyo+Sq9w zPSc6=#6#q>EZ}GwPN&?ten6Ow;sDm6Ja(|hVhkQef!EE6jQ*jH5T?6pUnR0a`7vze zdm76VSPJ{&;vI&|)&@3@hWf@}U=>nW1Q=U8VH?Sw~$v00Zgwhm~NVa_+f^MDNZfGuuo#t({ zs~dE-P-OHWSo`efezN@Qum45}PgMqaB1RJ~a8tCC0&IsHO#{WLGwA5bB2Gd?qsxEE zi*=rQZ408&&wV$AJmg6O#|UYbica~P@&FR!nk9pSV`Uq{TE|GT!W#%rX=lwog>M>Y zZ^7G~TnS+-Y2|5$BmGmDMxm}dv^ABcbMrU_3=Wz>vMlEjPc_K1I740t3{5-k?=r5zQ|@@KFZ+;ln%z~taGY@r(+RtML50o^Cv&8Pz9JMdwxB4< zG15N6e8Fh~PjOfed0!gA?%-{ESIQ}r6qe{vwJ{#;Vzl(p1AH2C-x`sN-PdqdlN^mr7}wcbD%%Tp3qGMy z6i5k9Z_)P-TZYOrPd&w)xKKX$2*X93j!{9`iqglvB5!!g$OenkEY1z&Z>K$NpPFa4 z@vX7EvKrw%_{~W^2L^4kOPcmWN?(iQ#zPyE^XBJaQG5%AsbGuzF%)`Nd z@~E9S`WE4BC`M=^_=Z=qaj+bg}Zm&*?eN@LG60MPZ_W22ndnVTzjR`B}(GSORbNO?DlY5Amn5b%-K^`iPrp#MOIEciT0}5oi8P>%X{&2s)G5dD;IF6KVM|KJq&T zv2G);m(QARI>gt>`N8hey}ev^#?A&knn*v7^Z1#T!7|;#i9r0$#l{#E7rW3}g>MTA zk0wrI_)Vdi)E(x41Mb^xePw)PxHO`Cn&aeQ6MapYMy$SpyAM9CoJjVRlN*n0H+goO zIilrYw|x7p56b`dG0y2#q_Uphg?IERwn3Y=;`3+bjqjJ46GcX};mOYl1%A{haH7cg zQESnY`us>x;M0#!#^Qsym_>7}E<&*5hqA|h`HqQ2NqlhRI)r-XLd6poE{YV!84~u$ zW9IjxEd>&>Aj$Pgl;eWOoq8@9e2xztpINy09=j8P<^TAwBRmBgu7OBEgbO2rW0B$R z7Q@552Vq{BD(?Y3n~-1NV0%PX+SPsYXPu$L;=Q-%nv?4j6$--&1``ScT0ES z8Q_eoE@8N!QvedFqD-DxkP0h4wg?lafF(M#K|mHR?-3Np2!gi?=20Hrt5kV6O<)v& zc*;CxjOE6IazUV2F&1Yi`PeTF7irfU`cBk_!IC zOigzeyH*kA8L0rx9lVa8)-45B(#Gv8KY*RR@*e;H#(ROwJ5)frNrmFbRPPTK`wx>FvmH$!+Lt9CN0LBmh1!-KD#6{3r~Cgn^Uq;z8A;JOFw?g}>jUOw$lv7Z|wnZuuF`jXWuUNqW`_Dbq%} zEG`6xG53N??B)h+n3ED8@i3iN^=^Q$>$+M`(}+$c^3GKyFuo3V9`XW%s-0_~ncO_4 z&$%~qMfrq@chI7Oq42k-uLt4gW(Z+p_quBhXz3WHkRt>(cTp^sna(>H>P{O{P|~4F0^Cn={*FmC^X)^6@p#+ou>oDX>L}5CAis- zp`B(tvJYE8K~eEEW_Ir4vtYfPJw1U5oOO0qJ9fCccDD>8e06>I*%zKJr^Y7A%KCbF z{f&3Z^*i^=_}Fl{MP3z`w!UR*)~BbxtNho0>u;7{|J`qwTeA!7&|POf*$I=V{0?KIieZ&R zsUVC~In-VAI?~>L7(7RNhw_GYQV3Z0yWm*T1w!8W%XxsHU`_;vC|BgiZT&3CTttNM z515Y2rn8UP?ruQRVYTm$32-~}0gkPqr^*bK1fDwZ)SqUXq73qzuLA{|?X$rNr0{z| zenzh-L$iY_%S14ha|n)6ig$z%nz0dqdy^A6!qW}fPp914rr$@&;kqo8fhs(hXQYSq zx31J6c+D_z_HxcqsU+=GqVLiVJdx)Z+1ie?Zv>Rq+g8+<$=3Qx&{XBK%6{{;B76>b zq|=<3eX|GO3G48fJGH4Ucwp{{6BW`_6K9(UHd8r^AeTcW-R$=6KykQ=uYqPxCOA)I zdoe~syG`n^l4^3YFZ_p$aJoR}++7IJyF1&4Ld z;^u_ML3^2=94l8bN28)fhsE>weCX+J0bl6ADT+me&nnaV@JGANvxxDg&_sYQ8OXc$~ zK3C2?_8jeq6KKpa?QAYEZn92jK0vXvR5oX>mQ7Dc;(uV5wZRnT+jcN1b!z&_Xz$rM zoFr2}Pe4e|;Q=K>;db(KJe{?-(U*_ z(fA_4Jlw*ao8?{VOV^3AEHoTESFm!<&AD0@b**Cmku#&ub`O+iE?y`%c2MY|1RdLh zpV*o2Nf!O(m_PE+cT5kb#d>6qHQ9x!QA|3-TEK zK?VL1{)EN%K6H}@j=tNeqqxLX-Gk1;v;H;)>4h2oGUXvC;cv&lXn6`};`%yi7(SKj zGd7IOEu)M=kulZ6*uZ$(=DL!_H#`vl06+jqL_t)wnx}NqXGxA}&71_%@q5f?@WmFV zkcR2gD+}{w1D`Siy4yl{tTf1W)V~2dC?~G06jyBrtW#*lKa(RiQl3!YgaUsN6gW|2 z{6$dtq>K{^{5dJ`)#pyLiy@ZhES6Y0uwd|`&4nZ{EMQn<Fm`8PajJz(0Op%MhDBYsts@6L39I06J z!~%$r5Dbvl#b20lU{N9tKF6XaK?E$N4rIsFrp%sg&u)oW7+@`iF}l{ zEJ}$<)O_+U@r`&x4C1m)^HErjUR9C^tWZc?jzg*pHH@s=Q5hf*^rD1-F2KN>2maeG zUJsWO0gwFDu?Z<@YS?kO&&TBiro`J$(!yBNl0v%F*#d$KQttQx>|SmghB)Ts6NS$@XLe*)bvbbt=rKRnauA;k9EqJOqtJ?6%-eD zo-_Y(3hCmT^!Q_!0L^FCU_evUG$Nnj4`oW&RnH(U1RHj&EP=Gii{hIXiMX=uZ6Dj@ zp*RHmtq9uOfmz$-RtOUgSCO4OP@w_rP*(c!74%HHif^{3RS1RdbQxb@jV|r^|r{N{xM>=3rfU!|uK6Z%YEw7qh*)A1cjIW*DID2G6s=_Ki zpdB-Jx8X@XRK<25N3kiSN}T+dvJ~yc>t8}M8}2R^w^R_=4qObP%}t%8X)2%j+|QP` z-~T=6$446F81FcxA|jj(BV_ZV-<_ojTWaY+;A7N->3O)?){g0&U$m9v(d%ZL>CetL))OGutK=4N)xZpA#_6x#PjDl1%1> z0?i14q>Wr+n^iASo~TB8;-uS=GRSvul4oL9DeYiW80Me#;sy-Y1H9X|{HuLrSa;)t z2;35(yhRhju>8Sw1OH4T-G~Q%adC)ZKOB8r(dT3&zw=Cj#cy$GV zC70vJ06WvWI3eP0^kGgeeCs>!B9PUef(k1f@*-fJ<3xtLd~HL`F3A%?7T#5YJoC&G z<-PZ>;DCImJa%@X+?!o0Pd<63+`l_pMyICA#m7#UJ9loCQFg_T43Cu`zV~7I@aoOd zi)pFPeCp})?eD%ucz+1uy76uD+M6HnK3snCrB9b{y!=|2&5_P3%2$_G>0b~41mr;# zAHg@^vgPR)+QePS3gEjCfa^fG2mc=m{uMIo*QmRn-O7{G<@ML!M)>B=X6nN~>F7xa z$01MIImXGtQ5^7XTgNoZwQt19Gw#9X1lq@A%^FHF1ecU&d*@h|{X2L8MN62wqiyXk z^0syGB#h?tHu2TqyK|_5cpc5JVLN{v1%;DGPPRDKm7h5mP=1xpl@^X1Z7?ury1s<@$kescF5yzf>RvK zl(Yqk7TUlfXaw5slA(`T+0tGk4G19-Al=hld8JJEpJ5vx5nr zd3+K*{`3pw#q*P81~XJ2e0a57y?QN9SDdBZ@{vjsO#rFH%zg$?_ykli+0|3};Ai