#200 odf writer fails when run with Python3.3b1

sandbox
closed-fixed
nobody
None
5
2014-08-28
2012-08-07
Anonymous
No

A few of the tests in test_writers.test_odt.DocutilsOdtTestCase fail when run against Python 3.3b1, with tracebacks of the form:

======================================================================
ERROR: test_odt_basic (test_writers.test_odt.DocutilsOdtTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/david/coding/python3.3/python-docutils/python3-python-docutils-0.10-0.2.20120730svn7490.fc18/test3/test_writers/test_odt.py", line 151, in test_odt_basic
self.process_test('odt_basic.txt', 'odt_basic.odt',
File "/home/david/coding/python3.3/python-docutils/python3-python-docutils-0.10-0.2.20120730svn7490.fc18/test3/test_writers/test_odt.py", line 104, in process_test
settings_overrides=settings_overrides)
File "/home/david/coding/python3.3/python-docutils/python3-python-docutils-0.10-0.2.20120730svn7490.fc18/build/lib/docutils/core.py", line 414, in publish_string
enable_exit_status=enable_exit_status)
File "/home/david/coding/python3.3/python-docutils/python3-python-docutils-0.10-0.2.20120730svn7490.fc18/build/lib/docutils/core.py", line 662, in publish_programmatically
output = pub.publish(enable_exit_status=enable_exit_status)
File "/home/david/coding/python3.3/python-docutils/python3-python-docutils-0.10-0.2.20120730svn7490.fc18/build/lib/docutils/core.py", line 219, in publish
output = self.writer.write(self.document, self.destination)
File "/home/david/coding/python3.3/python-docutils/python3-python-docutils-0.10-0.2.20120730svn7490.fc18/build/lib/docutils/writers/__init__.py", line 80, in write
self.translate()
File "/home/david/coding/python3.3/python-docutils/python3-python-docutils-0.10-0.2.20120730svn7490.fc18/build/lib/docutils/writers/odf_odt/__init__.py", line 548, in translate
self.visitor = self.translator_class(self.document)
File "/home/david/coding/python3.3/python-docutils/python3-python-docutils-0.10-0.2.20120730svn7490.fc18/build/lib/docutils/writers/odf_odt/__init__.py", line 822, in __init__
SubElement(root, 'office:scripts')
File "/home/david/coding/python3.3/python-docutils/python3-python-docutils-0.10-0.2.20120730svn7490.fc18/build/lib/docutils/writers/odf_odt/__init__.py", line 287, in SubElement
parent.append(el)
File "/usr/lib64/python3.3/xml/etree/ElementTree.py", line 280, in append
self._assert_is_element(element)
File "/usr/lib64/python3.3/xml/etree/ElementTree.py", line 305, in _assert_is_element
raise TypeError('expected an Element, not %s' % type(e).__name__)
TypeError: expected an Element, not _ElementInterfaceWrapper

These assertions are due to type-checking that was added in Python 3.3 to xml.etree - this was http://bugs.python.org/issue13782 ("xml.etree.ElementTree: Element.append doesn't type-check its argument").

What I think is happening is that _ElementInterfaceWrapper is a subclass of the Element class defined in xml/etree/ElementTree.py, but that file later has this code:
# Import the C accelerators
try:
# Element, SubElement, ParseError, TreeBuilder, XMLParser
from _elementtree import *
except ImportError:
pass
which happens after _ElementInterfaceWrapper has been set; hence that type-checking is expecting Element to be a _elementree.Element, rather than the pure-python Element implementation.

Discussion

  • Jakub Wilk
    Jakub Wilk
    2012-11-05

    Debian's python3.3_3.3.0-2 has 7bd9626d8b4f backported, but I can still see this failure.

     
  • Jakub Wilk
    Jakub Wilk
    2012-11-05

    This in unpatched source. Look at /usr/lib/python3.3/xml/etree/ElementTree.py, which has:
    if not isinstance(e, _Element):

     
  • Ah, you are right. But now I don't understand why that fails:

    Python 3.3.0 (default, Oct 21 2012, 20:31:18)
    [GCC 4.7.2] on linux
    ...
    >>> issubclass(docutils.writers.odf_odt._ElementInterfaceWrapper, xml.etree.ElementTree.Element)
    False
    >>> issubclass(docutils.writers.odf_odt._ElementInterfaceWrapper, xml.etree.ElementTree._Element)
    True
    >>> isinstance(docutils.writers.odf_odt._ElementInterfaceWrapper(tag='mytag', attrib={}), xml.etree.ElementTree._Element)
    True

     
  • Jakub Wilk
    Jakub Wilk
    2012-11-05

    Oh, I just realized that the traceback is slightly different (though exception message is the same):

    | ======================================================================
    | ERROR: test_odt_basic (test_writers.test_odt.DocutilsOdtTestCase)
    | ----------------------------------------------------------------------
    | Traceback (most recent call last):
    | File "/build/python-docutils-4yaKmK/python-docutils-0.9.1/test3/test_writers/test_odt.py", line 152, in test_odt_basic
    | self.process_test('odt_basic.txt', 'odt_basic.odt',
    | File "/build/python-docutils-4yaKmK/python-docutils-0.9.1/test3/test_writers/test_odt.py", line 105, in process_test
    | settings_overrides=settings_overrides)
    | File "/build/python-docutils-4yaKmK/python-docutils-0.9.1/build/py3/docutils/core.py", line 418, in publish_string
    | enable_exit_status=enable_exit_status)
    | File "/build/python-docutils-4yaKmK/python-docutils-0.9.1/build/py3/docutils/core.py", line 666, in publish_programmatically
    | output = pub.publish(enable_exit_status=enable_exit_status)
    | File "/build/python-docutils-4yaKmK/python-docutils-0.9.1/build/py3/docutils/core.py", line 223, in publish
    | output = self.writer.write(self.document, self.destination)
    | File "/build/python-docutils-4yaKmK/python-docutils-0.9.1/build/py3/docutils/writers/__init__.py", line 80, in write
    | self.translate()
    | File "/build/python-docutils-4yaKmK/python-docutils-0.9.1/build/py3/docutils/writers/odf_odt/__init__.py", line 552, in translate
    | self.assemble_my_parts()
    | File "/build/python-docutils-4yaKmK/python-docutils-0.9.1/build/py3/docutils/writers/odf_odt/__init__.py", line 569, in assemble_my_parts
    | s1 = self.get_stylesheet()
    | File "/build/python-docutils-4yaKmK/python-docutils-0.9.1/build/py3/docutils/writers/odf_odt/__init__.py", line 616, in get_stylesheet
    | s1 = self.visitor.setup_page()
    | File "/build/python-docutils-4yaKmK/python-docutils-0.9.1/build/py3/docutils/writers/odf_odt/__init__.py", line 968, in setup_page
    | self.add_header_footer(self.dom_stylesheet)
    | File "/build/python-docutils-4yaKmK/python-docutils-0.9.1/build/py3/docutils/writers/odf_odt/__init__.py", line 1027, in add_header_footer
    | nsdict=STYLES_NAMESPACE_DICT,
    | File "/build/python-docutils-4yaKmK/python-docutils-0.9.1/build/py3/docutils/writers/odf_odt/__init__.py", line 287, in SubElement
    | parent.append(el)
    | TypeError: must be Element, not _ElementInterfaceWrapper

    So it's C code raising the exception, not Python code.

     
  • Jakub Wilk
    Jakub Wilk
    2013-05-12

    test_odt failures are still reproducible with Python 3.3.1, both with Docutils 0.10 and svn snapshot (r7661):

    ======================================================================
    ERROR: test_odt_basic (test_writers.test_odt.DocutilsOdtTestCase)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/home/jwilk/docutils-0.10/test3/test_writers/test_odt.py", line 151, in test_odt_basic
        self.process_test('odt_basic.txt', 'odt_basic.odt',
      File "/home/jwilk/docutils-0.10/test3/test_writers/test_odt.py", line 104, in process_test
        settings_overrides=settings_overrides)
      File "/home/jwilk/docutils-0.10/build/lib/docutils/core.py", line 414, in publish_string
        enable_exit_status=enable_exit_status)
      File "/home/jwilk/docutils-0.10/build/lib/docutils/core.py", line 662, in publish_programmatically
        output = pub.publish(enable_exit_status=enable_exit_status)
      File "/home/jwilk/docutils-0.10/build/lib/docutils/core.py", line 219, in publish
        output = self.writer.write(self.document, self.destination)
      File "/home/jwilk/docutils-0.10/build/lib/docutils/writers/__init__.py", line 80, in write
        self.translate()
      File "/home/jwilk/docutils-0.10/build/lib/docutils/writers/odf_odt/__init__.py", line 550, in translate
        self.assemble_my_parts()
      File "/home/jwilk/docutils-0.10/build/lib/docutils/writers/odf_odt/__init__.py", line 567, in assemble_my_parts
        s1 = self.get_stylesheet()
      File "/home/jwilk/docutils-0.10/build/lib/docutils/writers/odf_odt/__init__.py", line 614, in get_stylesheet
        s1 = self.visitor.setup_page()
      File "/home/jwilk/docutils-0.10/build/lib/docutils/writers/odf_odt/__init__.py", line 1005, in setup_page
        self.add_header_footer(self.dom_stylesheet)
      File "/home/jwilk/docutils-0.10/build/lib/docutils/writers/odf_odt/__init__.py", line 1071, in add_header_footer
        nsdict=STYLES_NAMESPACE_DICT,
      File "/home/jwilk/docutils-0.10/build/lib/docutils/writers/odf_odt/__init__.py", line 285, in SubElement
        parent.append(el)
    TypeError: must be xml.etree.ElementTree.Element, not _ElementInterfaceWrapper
    
    ======================================================================
    ERROR: test_odt_custom_headfoot (test_writers.test_odt.DocutilsOdtTestCase)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/home/jwilk/docutils-0.10/test3/test_writers/test_odt.py", line 166, in test_odt_custom_headfoot
        settings_overrides=settings_overrides,
      File "/home/jwilk/docutils-0.10/test3/test_writers/test_odt.py", line 104, in process_test
        settings_overrides=settings_overrides)
      File "/home/jwilk/docutils-0.10/build/lib/docutils/core.py", line 414, in publish_string
        enable_exit_status=enable_exit_status)
      File "/home/jwilk/docutils-0.10/build/lib/docutils/core.py", line 662, in publish_programmatically
        output = pub.publish(enable_exit_status=enable_exit_status)
      File "/home/jwilk/docutils-0.10/build/lib/docutils/core.py", line 219, in publish
        output = self.writer.write(self.document, self.destination)
      File "/home/jwilk/docutils-0.10/build/lib/docutils/writers/__init__.py", line 80, in write
        self.translate()
      File "/home/jwilk/docutils-0.10/build/lib/docutils/writers/odf_odt/__init__.py", line 550, in translate
        self.assemble_my_parts()
      File "/home/jwilk/docutils-0.10/build/lib/docutils/writers/odf_odt/__init__.py", line 567, in assemble_my_parts
        s1 = self.get_stylesheet()
      File "/home/jwilk/docutils-0.10/build/lib/docutils/writers/odf_odt/__init__.py", line 614, in get_stylesheet
        s1 = self.visitor.setup_page()
      File "/home/jwilk/docutils-0.10/build/lib/docutils/writers/odf_odt/__init__.py", line 1005, in setup_page
        self.add_header_footer(self.dom_stylesheet)
      File "/home/jwilk/docutils-0.10/build/lib/docutils/writers/odf_odt/__init__.py", line 1056, in add_header_footer
        nsdict=STYLES_NAMESPACE_DICT,
      File "/home/jwilk/docutils-0.10/build/lib/docutils/writers/odf_odt/__init__.py", line 285, in SubElement
        parent.append(el)
    TypeError: must be xml.etree.ElementTree.Element, not _ElementInterfaceWrapper
    
    ======================================================================
    ERROR: test_odt_tables1 (test_writers.test_odt.DocutilsOdtTestCase)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/home/jwilk/docutils-0.10/test3/test_writers/test_odt.py", line 156, in test_odt_tables1
        self.process_test('odt_tables1.txt', 'odt_tables1.odt',
      File "/home/jwilk/docutils-0.10/test3/test_writers/test_odt.py", line 104, in process_test
        settings_overrides=settings_overrides)
      File "/home/jwilk/docutils-0.10/build/lib/docutils/core.py", line 414, in publish_string
        enable_exit_status=enable_exit_status)
      File "/home/jwilk/docutils-0.10/build/lib/docutils/core.py", line 662, in publish_programmatically
        output = pub.publish(enable_exit_status=enable_exit_status)
      File "/home/jwilk/docutils-0.10/build/lib/docutils/core.py", line 219, in publish
        output = self.writer.write(self.document, self.destination)
      File "/home/jwilk/docutils-0.10/build/lib/docutils/writers/__init__.py", line 80, in write
        self.translate()
      File "/home/jwilk/docutils-0.10/build/lib/docutils/writers/odf_odt/__init__.py", line 550, in translate
        self.assemble_my_parts()
      File "/home/jwilk/docutils-0.10/build/lib/docutils/writers/odf_odt/__init__.py", line 567, in assemble_my_parts
        s1 = self.get_stylesheet()
      File "/home/jwilk/docutils-0.10/build/lib/docutils/writers/odf_odt/__init__.py", line 614, in get_stylesheet
        s1 = self.visitor.setup_page()
      File "/home/jwilk/docutils-0.10/build/lib/docutils/writers/odf_odt/__init__.py", line 1005, in setup_page
        self.add_header_footer(self.dom_stylesheet)
      File "/home/jwilk/docutils-0.10/build/lib/docutils/writers/odf_odt/__init__.py", line 1071, in add_header_footer
        nsdict=STYLES_NAMESPACE_DICT,
      File "/home/jwilk/docutils-0.10/build/lib/docutils/writers/odf_odt/__init__.py", line 285, in SubElement
        parent.append(el)
    TypeError: must be xml.etree.ElementTree.Element, not _ElementInterfaceWrapper
    
     
  • Jakub Wilk
    Jakub Wilk
    2013-05-16

    Here's a patch I'm going to use in Debian, as a temporary(?) work-around.

     
  • Günter Milde
    Günter Milde
    2013-05-16

    Can we just import etree.Element instead of etree._ElementInterface?

    Would this solve the issue?

     
  • Günter Milde
    Günter Milde
    2013-08-21

    • status: open --> open-fixed
    • Group: --> sandbox
     
  • Günter Milde
    Günter Milde
    2013-08-21

    Applied the patch. Thank you for analysing and fixing.

     
  • Günter Milde
    Günter Milde
    2013-08-21

    • status: open-fixed --> closed-fixed