[pypy-svn] r55937 - in pypy/dist/pypy/lib: . app_test

fijal at codespeak.net fijal at codespeak.net
Wed Jun 18 00:05:13 CEST 2008


Author: fijal
Date: Wed Jun 18 00:05:12 2008
New Revision: 55937

Modified:
   pypy/dist/pypy/lib/app_test/test_pyexpat.py
   pypy/dist/pypy/lib/pyexpat.py
Log:
More tests for pyexpat (thanks therve). fix pyexpat.py to pass those.


Modified: pypy/dist/pypy/lib/app_test/test_pyexpat.py
==============================================================================
--- pypy/dist/pypy/lib/app_test/test_pyexpat.py	(original)
+++ pypy/dist/pypy/lib/app_test/test_pyexpat.py	Wed Jun 18 00:05:12 2008
@@ -10,6 +10,7 @@
 
 from test.test_support import sortdict, run_unittest
 
+
 class TestSetAttribute:
     def setup_method(self, meth):
         self.parser = expat.ParserCreate(namespace_separator='!')
@@ -42,6 +43,7 @@
 <!-- comment data -->
 <!DOCTYPE quotations SYSTEM "quotations.dtd" [
 <!ELEMENT root ANY>
+<!ATTLIST root attr1 CDATA #REQUIRED attr2 CDATA #IMPLIED>
 <!NOTATION notation SYSTEM "notation.jpeg">
 <!ENTITY acirc "&#226;">
 <!ENTITY external_entity SYSTEM "entity.file">
@@ -55,9 +57,11 @@
 </myns:subelement>
 <sub2><![CDATA[contents of CDATA section]]></sub2>
 &external_entity;
+&skipped_entity;
 </root>
 '''
 
+
 # Produce UTF-8 output
 class TestParse:
     class Outputter:
@@ -102,7 +106,7 @@
             entityName, base, systemId, publicId, notationName = args
             self.out.append('Unparsed entity decl: %s' %(args,))
 
-        def NotStandaloneHandler(self, userData):
+        def NotStandaloneHandler(self):
             self.out.append('Not standalone')
             return 1
 
@@ -111,6 +115,34 @@
             self.out.append('External entity ref: %s' %(args[1:],))
             return 1
 
+        def StartDoctypeDeclHandler(self, *args):
+            self.out.append(('Start doctype', args))
+            return 1
+
+        def EndDoctypeDeclHandler(self):
+            self.out.append("End doctype")
+            return 1
+
+        def EntityDeclHandler(self, *args):
+            self.out.append(('Entity declaration', args))
+            return 1
+
+        def XmlDeclHandler(self, *args):
+            self.out.append(('XML declaration', args))
+            return 1
+
+        def ElementDeclHandler(self, *args):
+            self.out.append(('Element declaration', args))
+            return 1
+
+        def AttlistDeclHandler(self, *args):
+            self.out.append(('Attribute list declaration', args))
+            return 1
+
+        def SkippedEntityHandler(self, *args):
+            self.out.append(("Skipped entity", args))
+            return 1
+
         def DefaultHandler(self, userData):
             pass
 
@@ -118,15 +150,15 @@
             pass
 
     handler_names = [
-        'StartElementHandler', 'EndElementHandler',
-        'CharacterDataHandler', 'ProcessingInstructionHandler',
-        'UnparsedEntityDeclHandler', 'NotationDeclHandler',
-        'StartNamespaceDeclHandler', 'EndNamespaceDeclHandler',
-        'CommentHandler', 'StartCdataSectionHandler',
-        'EndCdataSectionHandler',
-        'DefaultHandler', 'DefaultHandlerExpand',
-        #'NotStandaloneHandler',
-        'ExternalEntityRefHandler'
+        'StartElementHandler', 'EndElementHandler', 'CharacterDataHandler',
+        'ProcessingInstructionHandler', 'UnparsedEntityDeclHandler',
+        'NotationDeclHandler', 'StartNamespaceDeclHandler',
+        'EndNamespaceDeclHandler', 'CommentHandler',
+        'StartCdataSectionHandler', 'EndCdataSectionHandler', 'DefaultHandler',
+        'DefaultHandlerExpand', 'NotStandaloneHandler',
+        'ExternalEntityRefHandler', 'StartDoctypeDeclHandler',
+        'EndDoctypeDeclHandler', 'EntityDeclHandler', 'XmlDeclHandler',
+        'ElementDeclHandler', 'AttlistDeclHandler', 'SkippedEntityHandler',
         ]
 
     def test_utf8(self):
@@ -139,24 +171,42 @@
         parser.Parse(data, 1)
 
         # Verify output
-        op = out.out
-        assert op[0] == 'PI: \'xml-stylesheet\' \'href="stylesheet.css"\''
-        assert op[1] == "Comment: ' comment data '"
-        assert op[2] == "Notation declared: ('notation', None, 'notation.jpeg', None)"
-        assert op[3] == "Unparsed entity decl: ('unparsed_entity', None, 'entity.file', None, 'notation')"
-        assert op[4] == "Start element: 'root' {'attr1': 'value1', 'attr2': 'value2\\xe1\\xbd\\x80'}"
-        assert op[5] == "NS decl: 'myns' 'http://www.python.org/namespace'"
-        assert op[6] == "Start element: 'http://www.python.org/namespace!subelement' {}"
-        assert op[7] == "Character data: 'Contents of subelements'"
-        assert op[8] == "End element: 'http://www.python.org/namespace!subelement'"
-        assert op[9] == "End of NS decl: 'myns'"
-        assert op[10] == "Start element: 'sub2' {}"
-        assert op[11] == 'Start of CDATA section'
-        assert op[12] == "Character data: 'contents of CDATA section'"
-        assert op[13] == 'End of CDATA section'
-        assert op[14] == "End element: 'sub2'"
-        assert op[15] == "External entity ref: (None, 'entity.file', None)"
-        assert op[16] == "End element: 'root'"
+        operations = out.out
+        expected_operations = [
+            ('XML declaration', (u'1.0', u'iso-8859-1', 0)),
+            'PI: \'xml-stylesheet\' \'href="stylesheet.css"\'',
+            "Comment: ' comment data '",
+            "Not standalone",
+            ("Start doctype", ('quotations', 'quotations.dtd', None, 1)),
+            ('Element declaration', (u'root', (2, 0, None, ()))),
+            ('Attribute list declaration', ('root', 'attr1', 'CDATA', None,
+                1)),
+            ('Attribute list declaration', ('root', 'attr2', 'CDATA', None,
+                0)),
+            "Notation declared: ('notation', None, 'notation.jpeg', None)",
+            ('Entity declaration', ('acirc', 0, '\xc3\xa2', None, None, None, None)),
+            ('Entity declaration', ('external_entity', 0, None, None,
+                'entity.file', None, None)),
+            "Unparsed entity decl: ('unparsed_entity', None, 'entity.file', None, 'notation')",
+            "Not standalone",
+            "End doctype",
+            "Start element: 'root' {'attr1': 'value1', 'attr2': 'value2\\xe1\\xbd\\x80'}",
+            "NS decl: 'myns' 'http://www.python.org/namespace'",
+            "Start element: 'http://www.python.org/namespace!subelement' {}",
+            "Character data: 'Contents of subelements'",
+            "End element: 'http://www.python.org/namespace!subelement'",
+            "End of NS decl: 'myns'",
+            "Start element: 'sub2' {}",
+            'Start of CDATA section',
+            "Character data: 'contents of CDATA section'",
+            'End of CDATA section',
+            "End element: 'sub2'",
+            "External entity ref: (None, 'entity.file', None)",
+            ('Skipped entity', ('skipped_entity', 0)),
+            "End element: 'root'",
+        ]
+        for operation, expected_operation in zip(operations, expected_operations):
+            assert operation == expected_operation
 
     def test_unicode(self):
         # Try the parse again, this time producing Unicode output
@@ -168,24 +218,43 @@
 
         parser.Parse(data, 1)
 
-        op = out.out
-        assert op[0] == 'PI: u\'xml-stylesheet\' u\'href="stylesheet.css"\''
-        assert op[1] == "Comment: u' comment data '"
-        assert op[2] == "Notation declared: (u'notation', None, u'notation.jpeg', None)"
-        assert op[3] == "Unparsed entity decl: (u'unparsed_entity', None, u'entity.file', None, u'notation')"
-        assert op[4] == "Start element: u'root' {u'attr1': u'value1', u'attr2': u'value2\\u1f40'}"
-        assert op[5] == "NS decl: u'myns' u'http://www.python.org/namespace'"
-        assert op[6] == "Start element: u'http://www.python.org/namespace!subelement' {}"
-        assert op[7] == "Character data: u'Contents of subelements'"
-        assert op[8] == "End element: u'http://www.python.org/namespace!subelement'"
-        assert op[9] == "End of NS decl: u'myns'"
-        assert op[10] == "Start element: u'sub2' {}"
-        assert op[11] == 'Start of CDATA section'
-        assert op[12] == "Character data: u'contents of CDATA section'"
-        assert op[13] == 'End of CDATA section'
-        assert op[14] == "End element: u'sub2'"
-        assert op[15] == "External entity ref: (None, u'entity.file', None)"
-        assert op[16] == "End element: u'root'"
+        operations = out.out
+        expected_operations = [
+            ('XML declaration', (u'1.0', u'iso-8859-1', 0)),
+            'PI: u\'xml-stylesheet\' u\'href="stylesheet.css"\'',
+            "Comment: u' comment data '",
+            "Not standalone",
+            ("Start doctype", ('quotations', 'quotations.dtd', None, 1)),
+            ('Element declaration', (u'root', (2, 0, None, ()))),
+            ('Attribute list declaration', ('root', 'attr1', 'CDATA', None,
+                1)),
+            ('Attribute list declaration', ('root', 'attr2', 'CDATA', None,
+                0)),
+            "Notation declared: (u'notation', None, u'notation.jpeg', None)",
+            ('Entity declaration', (u'acirc', 0, u'\xe2', None, None, None,
+                None)),
+            ('Entity declaration', (u'external_entity', 0, None, None,
+                 u'entity.file', None, None)),
+            "Unparsed entity decl: (u'unparsed_entity', None, u'entity.file', None, u'notation')",
+            "Not standalone",
+            "End doctype",
+            "Start element: u'root' {u'attr1': u'value1', u'attr2': u'value2\\u1f40'}",
+            "NS decl: u'myns' u'http://www.python.org/namespace'",
+            "Start element: u'http://www.python.org/namespace!subelement' {}",
+            "Character data: u'Contents of subelements'",
+            "End element: u'http://www.python.org/namespace!subelement'",
+            "End of NS decl: u'myns'",
+            "Start element: u'sub2' {}",
+            'Start of CDATA section',
+            "Character data: u'contents of CDATA section'",
+            'End of CDATA section',
+            "End element: u'sub2'",
+            "External entity ref: (None, u'entity.file', None)",
+            ('Skipped entity', ('skipped_entity', 0)),
+            "End element: u'root'",
+        ]
+        for operation, expected_operation in zip(operations, expected_operations):
+            assert operation == expected_operation
 
     def test_parse_file(self):
         # Try parsing a file
@@ -198,24 +267,41 @@
 
         parser.ParseFile(file)
 
-        op = out.out
-        assert op[0] == 'PI: u\'xml-stylesheet\' u\'href="stylesheet.css"\''
-        assert op[1] == "Comment: u' comment data '"
-        assert op[2] == "Notation declared: (u'notation', None, u'notation.jpeg', None)"
-        assert op[3] == "Unparsed entity decl: (u'unparsed_entity', None, u'entity.file', None, u'notation')"
-        assert op[4] == "Start element: u'root' {u'attr1': u'value1', u'attr2': u'value2\\u1f40'}"
-        assert op[5] == "NS decl: u'myns' u'http://www.python.org/namespace'"
-        assert op[6] == "Start element: u'http://www.python.org/namespace!subelement' {}"
-        assert op[7] == "Character data: u'Contents of subelements'"
-        assert op[8] == "End element: u'http://www.python.org/namespace!subelement'"
-        assert op[9] == "End of NS decl: u'myns'"
-        assert op[10] == "Start element: u'sub2' {}"
-        assert op[11] == 'Start of CDATA section'
-        assert op[12] == "Character data: u'contents of CDATA section'"
-        assert op[13] == 'End of CDATA section'
-        assert op[14] == "End element: u'sub2'"
-        assert op[15] == "External entity ref: (None, u'entity.file', None)"
-        assert op[16] == "End element: u'root'"
+        operations = out.out
+        expected_operations = [
+            ('XML declaration', (u'1.0', u'iso-8859-1', 0)),
+            'PI: u\'xml-stylesheet\' u\'href="stylesheet.css"\'',
+            "Comment: u' comment data '",
+            "Not standalone",
+            ("Start doctype", ('quotations', 'quotations.dtd', None, 1)),
+            ('Element declaration', (u'root', (2, 0, None, ()))),
+            ('Attribute list declaration', ('root', 'attr1', 'CDATA', None,
+                1)),
+            ('Attribute list declaration', ('root', 'attr2', 'CDATA', None,
+                0)),
+            "Notation declared: (u'notation', None, u'notation.jpeg', None)",
+            ('Entity declaration', ('acirc', 0, u'\xe2', None, None, None, None)),
+            ('Entity declaration', (u'external_entity', 0, None, None, u'entity.file', None, None)),
+            "Unparsed entity decl: (u'unparsed_entity', None, u'entity.file', None, u'notation')",
+            "Not standalone",
+            "End doctype",
+            "Start element: u'root' {u'attr1': u'value1', u'attr2': u'value2\\u1f40'}",
+            "NS decl: u'myns' u'http://www.python.org/namespace'",
+            "Start element: u'http://www.python.org/namespace!subelement' {}",
+            "Character data: u'Contents of subelements'",
+            "End element: u'http://www.python.org/namespace!subelement'",
+            "End of NS decl: u'myns'",
+            "Start element: u'sub2' {}",
+            'Start of CDATA section',
+            "Character data: u'contents of CDATA section'",
+            'End of CDATA section',
+            "End element: u'sub2'",
+            "External entity ref: (None, u'entity.file', None)",
+            ('Skipped entity', ('skipped_entity', 0)),
+            "End element: u'root'",
+        ]
+        for operation, expected_operation in zip(operations, expected_operations):
+            assert operation == expected_operation
 
 
 class TestNamespaceSeparator:
@@ -312,7 +398,8 @@
         # Make sure buffering is turned on
         assert self.parser.buffer_text
         self.parser.Parse("<a>1<b/>2<c/>3</a>", 1)
-        assert self.stuff == ['123']
+        assert self.stuff == ['123'], (
+                          "buffered text not properly collapsed")
 
     def test1(self):
         # XXX This test exposes more detail of Expat's text chunking than we
@@ -401,7 +488,7 @@
                 'Expected position %s, got position %s' %(pos, expected))
         self.upto += 1
 
-    def test_x(self):
+    def test(self):
         self.parser = expat.ParserCreate()
         self.parser.StartElementHandler = self.StartElementHandler
         self.parser.EndElementHandler = self.EndElementHandler
@@ -415,11 +502,6 @@
 
 class Testsf1296433:
     def test_parse_only_xml_data(self):
-        try:
-            import __pypy__
-        except ImportError:
-            import py
-            py.test.skip("segfaults cpython")
         # http://python.org/sf/1296433
         #
         xml = "<?xml version='1.0' encoding='iso8859'?><s>%s</s>" % ('a' * 1025)
@@ -441,13 +523,6 @@
     """
     test setting of chardata buffer size
     """
-    def setup_class(cls):
-        import py
-        try:
-            import __pypy__
-        except ImportError:
-            pass
-            #py.test.skip("Doesn't work on cpy 2.5")
 
     def test_1025_bytes(self):
         assert self.small_buffer_test(1025) == 2

Modified: pypy/dist/pypy/lib/pyexpat.py
==============================================================================
--- pypy/dist/pypy/lib/pyexpat.py	(original)
+++ pypy/dist/pypy/lib/pyexpat.py	Wed Jun 18 00:05:12 2008
@@ -27,6 +27,13 @@
                                     ('convert', c_void_p),
                                     ('release', c_void_p),
                                     ('map', c_int * 256)])
+    XML_Content = configure.Struct('XML_Content',[
+        ('numchildren', c_int),
+        ('children', c_void_p),
+        ('name', c_char_p),
+        ('type', c_int),
+        ('quant', c_int),
+    ])
     # this is insanely stupid
     XML_FALSE = configure.ConstantInteger('XML_FALSE')
     XML_TRUE = configure.ConstantInteger('XML_TRUE')
@@ -34,6 +41,8 @@
 info = configure.configure(CConfigure)
 for k, v in info.items():
     globals()[k] = v
+
+XML_Content.children = POINTER(XML_Content)
 XML_Parser = ctypes.c_void_p # an opaque pointer
 assert XML_Char is ctypes.c_char # this assumption is everywhere in
 # cpython's expat, let's explode
@@ -65,6 +74,8 @@
 
 declare_external('XML_SetUnknownEncodingHandler', [XML_Parser, c_void_p,
                                                    c_void_p], None)
+declare_external('XML_FreeContentModel', [XML_Parser, POINTER(XML_Content)],
+                 None)
 
 def XML_ErrorString(code):
     res = lib.XML_ErrorString(code)
@@ -262,11 +273,21 @@
         CB = ctypes.CFUNCTYPE(None, c_void_p, POINTER(c_char), c_int)
         return CB(CharacterData)
 
+    def get_cb_for_NotStandaloneHandler(self, real_cb):
+        def NotStandaloneHandler(unused):
+            return real_cb()
+        NotStandaloneHandler = self._wrap_cb(NotStandaloneHandler)
+        CB = ctypes.CFUNCTYPE(c_int, c_void_p)
+        return CB(NotStandaloneHandler)
+
     def get_cb_for_EntityDeclHandler(self, real_cb):
-        def EntityDecl(unused, ename, is_param, value, _, base, system_id,
-                       pub_id, not_name):
-            
+        def EntityDecl(unused, ename, is_param, value, value_len, base,
+                       system_id, pub_id, not_name):
             self._flush_character_buffer()
+            if not value:
+                value = None
+            else:
+                value = value[:value_len]
             args = [ename, is_param, value, base, system_id,
                     pub_id, not_name]
             args = [self.conv(arg) for arg in args]
@@ -276,12 +297,21 @@
                                c_int, c_char_p, c_char_p, c_char_p, c_char_p)
         return CB(EntityDecl)
 
+    def _conv_content_model(self, model):
+        children = tuple([self._conv_content_model(model.children[i])
+                          for i in range(model.numchildren)])
+        return (model.type, model.quant, self.conv(model.name),
+                children)
+
     def get_cb_for_ElementDeclHandler(self, real_cb):
-        # XXX this is broken, needs tests
-        def ElementDecl(unused, *args):
-            print "WARNING! ElementDeclHandler Not supported"
+        def ElementDecl(unused, name, model):
+            self._flush_character_buffer()
+            modelobj = self._conv_content_model(model[0])
+            real_cb(name, modelobj)
+            XML_FreeContentModel(self.itself, model)
+
         ElementDecl = self._wrap_cb(ElementDecl)
-        CB = ctypes.CFUNCTYPE(None, c_void_p, c_char_p, c_void_p)
+        CB = ctypes.CFUNCTYPE(None, c_void_p, c_char_p, POINTER(XML_Content))
         return CB(ElementDecl)
 
     def _new_callback_for_string_len(name, sign):
@@ -342,7 +372,7 @@
     def conv_unicode(self, s):
         if s is None or isinstance(s, int):
             return s
-        return s.decode(self.encoding)
+        return s.decode(self.encoding, "strict")
 
     def __setattr__(self, name, value):
         # forest of ifs...



More information about the Pypy-commit mailing list