[Lxml-checkins] r55087 - in lxml/trunk: . doc src/lxml src/lxml/tests

scoder at codespeak.net scoder at codespeak.net
Wed May 21 21:45:49 CEST 2008


Author: scoder
Date: Wed May 21 21:45:48 2008
New Revision: 55087

Modified:
   lxml/trunk/   (props changed)
   lxml/trunk/doc/objectify.txt
   lxml/trunk/src/lxml/extensions.pxi
   lxml/trunk/src/lxml/lxml.objectify.pyx
   lxml/trunk/src/lxml/nsclasses.pxi
   lxml/trunk/src/lxml/objectpath.pxi
   lxml/trunk/src/lxml/python.pxd
   lxml/trunk/src/lxml/tests/test_objectify.py
Log:
 r4252 at delle:  sbehnel | 2008-05-20 22:09:08 +0200
 lots of Py3 fixes


Modified: lxml/trunk/doc/objectify.txt
==============================================================================
--- lxml/trunk/doc/objectify.txt	(original)
+++ lxml/trunk/doc/objectify.txt	Wed May 21 21:45:48 2008
@@ -67,6 +67,14 @@
 Imported from within a doctest, this relieves us from caring about the exact
 formatting of XML output.
 
+..
+    >>> try: from StringIO import StringIO
+    ... except ImportError:
+    ...     from io import BytesIO # Python 3
+    ...     def StringIO(s):
+    ...         if isinstance(s, str): s = s.encode('UTF-8')
+    ...         return BytesIO(s)
+
 
 The lxml.objectify API
 ======================
@@ -85,15 +93,14 @@
 
 .. sourcecode:: pycon
 
-    >>> from StringIO import StringIO
     >>> fileobject = StringIO('<test/>')
 
     >>> tree = objectify.parse(fileobject)
-    >>> print isinstance(tree.getroot(), objectify.ObjectifiedElement)
+    >>> print(isinstance(tree.getroot(), objectify.ObjectifiedElement))
     True
 
     >>> root = objectify.fromstring('<test/>')
-    >>> print isinstance(root, objectify.ObjectifiedElement)
+    >>> print(isinstance(root, objectify.ObjectifiedElement))
     True
 
 To build a new tree in memory, ``objectify`` replicates the standard
@@ -102,7 +109,7 @@
 .. sourcecode:: pycon
 
     >>> obj_el = objectify.Element("new")
-    >>> print isinstance(obj_el, objectify.ObjectifiedElement)
+    >>> print(isinstance(obj_el, objectify.ObjectifiedElement))
     True
 
 After creating such an Element, you can use the `usual API`_ of
@@ -122,11 +129,11 @@
 .. sourcecode:: pycon
 
     >>> subel = etree.SubElement(obj_el, "sub")
-    >>> print isinstance(subel, objectify.ObjectifiedElement)
+    >>> print(isinstance(subel, objectify.ObjectifiedElement))
     True
 
     >>> independent_el = etree.Element("new")
-    >>> print isinstance(independent_el, objectify.ObjectifiedElement)
+    >>> print(isinstance(independent_el, objectify.ObjectifiedElement))
     False
 
 
@@ -141,14 +148,14 @@
 
     >>> root = objectify.Element("root")
     >>> b = etree.SubElement(root, "b")
-    >>> print root.b[0].tag
+    >>> print(root.b[0].tag)
     b
     >>> root.index(root.b[0])
     0
     >>> b = etree.SubElement(root, "b")
-    >>> print root.b[0].tag
+    >>> print(root.b[0].tag)
     b
-    >>> print root.b[1].tag
+    >>> print(root.b[1].tag)
     b
     >>> root.index(root.b[1])
     1
@@ -157,7 +164,7 @@
 
 .. sourcecode:: pycon
 
-    >>> print root.b.tag
+    >>> print(root.b.tag)
     b
     >>> root.index(root.b)
     0
@@ -204,11 +211,11 @@
 .. sourcecode:: pycon
 
     >>> c = etree.SubElement(root, "c", myattr="someval")
-    >>> print root.c.get("myattr")
+    >>> print(root.c.get("myattr"))
     someval
 
     >>> root.c.set("c", "oh-oh")
-    >>> print root.c.get("c")
+    >>> print(root.c.get("c"))
     oh-oh
 
 In addition to the normal ElementTree API for appending elements to trees,
@@ -220,9 +227,9 @@
 
     >>> el = objectify.Element("yet_another_child")
     >>> root.new_child = el
-    >>> print root.new_child.tag
+    >>> print(root.new_child.tag)
     new_child
-    >>> print el.tag
+    >>> print(el.tag)
     yet_another_child
 
     >>> root.y = [ objectify.Element("y"), objectify.Element("y") ]
@@ -249,25 +256,25 @@
     >>> subel = etree.SubElement(el, "sub")
 
     >>> root.child = el
-    >>> print root.child.sub.tag
+    >>> print(root.child.sub.tag)
     sub
 
     >>> root.child[2] = el
-    >>> print root.child[2].sub.tag
+    >>> print(root.child[2].sub.tag)
     sub
 
 Note that special care must be taken when changing the tag name of an element:
 
 .. sourcecode:: pycon
 
-    >>> print root.b.tag
+    >>> print(root.b.tag)
     b
     >>> root.b.tag = "notB"
     >>> root.b
     Traceback (most recent call last):
       ...
     AttributeError: no such child: b
-    >>> print root.notB.tag
+    >>> print(root.notB.tag)
     notB
 
 
@@ -280,15 +287,15 @@
 
     >>> E = objectify.E
     >>> root = E.root(
-    ...   E.a(5L),
+    ...   E.a(5),
     ...   E.b(6.1),
     ...   E.c(True),
     ...   E.d("how", tell="me")
     ... )
 
-    >>> print etree.tostring(root, pretty_print=True)
+    >>> print(etree.tostring(root, pretty_print=True))
     <root xmlns:py="http://codespeak.net/lxml/objectify/pytype">
-      <a py:pytype="long">5</a>
+      <a py:pytype="int">5</a>
       <b py:pytype="float">6.1</b>
       <c py:pytype="bool">true</c>
       <d py:pytype="str" tell="me">how</d>
@@ -307,7 +314,7 @@
     ...   HOWMANY(5)
     ... )
 
-    >>> print etree.tostring(root, pretty_print=True)
+    >>> print(etree.tostring(root, pretty_print=True))
     <root xmlns:py="http://codespeak.net/lxml/objectify/pytype">
       <title py:pytype="str">The title</title>
       <how-many py:pytype="int">5</how-many>
@@ -325,7 +332,7 @@
 
     >>> root = myE.root( myE.someint(2) )
 
-    >>> print etree.tostring(root, pretty_print=True)
+    >>> print(etree.tostring(root, pretty_print=True))
     <root xmlns="http://my/ns">
       <someint>2</someint>
     </root>
@@ -344,9 +351,9 @@
     >>> b = etree.SubElement(root, "{ns}b")
     >>> c = etree.SubElement(root, "{other}c")
 
-    >>> print root.b.tag
+    >>> print(root.b.tag)
     {ns}b
-    >>> print root.c
+    >>> print(root.c)
     Traceback (most recent call last):
         ...
     AttributeError: no such child: {ns}c
@@ -355,14 +362,14 @@
 
 .. sourcecode:: pycon
 
-    >>> print getattr(root, "{other}c").tag
+    >>> print(getattr(root, "{other}c").tag)
     {other}c
 
 For convenience, there is also a quick way through item access:
 
 .. sourcecode:: pycon
 
-    >>> print root["{other}c"].tag
+    >>> print(root["{other}c"].tag)
     {other}c
 
 The same approach must be used to access children with tag names that are not
@@ -371,7 +378,7 @@
 .. sourcecode:: pycon
 
     >>> el = etree.SubElement(root, "{ns}tag-name")
-    >>> print root["tag-name"].tag
+    >>> print(root["tag-name"].tag)
     {ns}tag-name
 
     >>> new_el = objectify.Element("{ns}new-element")
@@ -380,16 +387,16 @@
     >>> el = etree.SubElement(new_el, "{ns}child")
 
     >>> root["tag-name"] = [ new_el, new_el ]
-    >>> print len(root["tag-name"])
+    >>> print(len(root["tag-name"]))
     2
-    >>> print root["tag-name"].tag
+    >>> print(root["tag-name"].tag)
     {ns}tag-name
 
-    >>> print len(root["tag-name"].child)
+    >>> print(len(root["tag-name"].child))
     3
-    >>> print root["tag-name"].child.tag
+    >>> print(root["tag-name"].child.tag)
     {ns}child
-    >>> print root["tag-name"][1].child.tag
+    >>> print(root["tag-name"][1].child.tag)
     {ns}child
 
 or for names that have a special meaning in lxml.objectify:
@@ -398,12 +405,12 @@
 
     >>> root = objectify.XML("<root><text>TEXT</text></root>")
 
-    >>> print root.text.text
+    >>> print(root.text.text)
     Traceback (most recent call last):
       ...
     AttributeError: 'NoneType' object has no attribute 'text'
 
-    >>> print root["text"].text
+    >>> print(root["text"].text)
     TEXT
 
 
@@ -425,7 +432,6 @@
 
 .. sourcecode:: pycon
 
-    >>> from StringIO import StringIO
     >>> f = StringIO('''\
     ...   <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
     ...     <xsd:element name="a" type="AType"/>
@@ -455,7 +461,7 @@
     >>> xml = "<a><b>test</b></a>"
     >>> a = objectify.fromstring(xml, parser)
 
-    >>> print a.b
+    >>> print(a.b)
     test
 
 Or an invalid document:
@@ -486,39 +492,39 @@
     >>> d  = etree.SubElement(root, "{other}d")
 
     >>> path = objectify.ObjectPath("root.b.c")
-    >>> print path
+    >>> print(path)
     root.b.c
     >>> path.hasattr(root)
     True
-    >>> print path.find(root).tag
+    >>> print(path.find(root).tag)
     {ns}c
 
     >>> find = objectify.ObjectPath("root.b.c")
-    >>> print find(root).tag
+    >>> print(find(root).tag)
     {ns}c
 
     >>> find = objectify.ObjectPath("root.{other}d")
-    >>> print find(root).tag
+    >>> print(find(root).tag)
     {other}d
 
     >>> find = objectify.ObjectPath("root.{not}there")
-    >>> print find(root).tag
+    >>> print(find(root).tag)
     Traceback (most recent call last):
       ...
     AttributeError: no such child: {not}there
 
     >>> find = objectify.ObjectPath("{not}there")
-    >>> print find(root).tag
+    >>> print(find(root).tag)
     Traceback (most recent call last):
       ...
     ValueError: root element does not match: need {not}there, got {ns}root
 
     >>> find = objectify.ObjectPath("root.b[1]")
-    >>> print find(root).tag
+    >>> print(find(root).tag)
     {ns}b
 
     >>> find = objectify.ObjectPath("root.{ns}b[1]")
-    >>> print find(root).tag
+    >>> print(find(root).tag)
     {ns}b
 
 Apart from strings, ObjectPath also accepts lists of path segments:
@@ -526,11 +532,11 @@
 .. sourcecode:: pycon
 
     >>> find = objectify.ObjectPath(['root', 'b', 'c'])
-    >>> print find(root).tag
+    >>> print(find(root).tag)
     {ns}c
 
     >>> find = objectify.ObjectPath(['root', '{ns}b[1]'])
-    >>> print find(root).tag
+    >>> print(find(root).tag)
     {ns}b
 
 You can also use relative paths starting with a '.' to ignore the actual root
@@ -539,21 +545,21 @@
 .. sourcecode:: pycon
 
     >>> find = objectify.ObjectPath(".b[1]")
-    >>> print find(root).tag
+    >>> print(find(root).tag)
     {ns}b
 
     >>> find = objectify.ObjectPath(['', 'b[1]'])
-    >>> print find(root).tag
+    >>> print(find(root).tag)
     {ns}b
 
     >>> find = objectify.ObjectPath(".unknown[1]")
-    >>> print find(root).tag
+    >>> print(find(root).tag)
     Traceback (most recent call last):
       ...
     AttributeError: no such child: {ns}unknown
 
     >>> find = objectify.ObjectPath(".{other}unknown[1]")
-    >>> print find(root).tag
+    >>> print(find(root).tag)
     Traceback (most recent call last):
       ...
     AttributeError: no such child: {other}unknown
@@ -563,7 +569,7 @@
 .. sourcecode:: pycon
 
     >>> find = objectify.ObjectPath(".")
-    >>> print find(root).tag
+    >>> print(find(root).tag)
     {ns}root
 
 ObjectPath objects can be used to manipulate trees:
@@ -583,15 +589,15 @@
     >>> path.setattr(root, "my value") # creates children as necessary
     >>> path.hasattr(root)
     True
-    >>> print path.find(root).text
+    >>> print(path.find(root).text)
     my value
-    >>> print root.some.child["{other}unknown"].text
+    >>> print(root.some.child["{other}unknown"].text)
     my value
 
-    >>> print len( path.find(root) )
+    >>> print(len( path.find(root) ))
     1
     >>> path.addattr(root, "my new value")
-    >>> print len( path.find(root) )
+    >>> print(len( path.find(root) ))
     2
     >>> [ el.text for el in path.find(root) ]
     ['my value', 'my new value']
@@ -636,26 +642,26 @@
     >>> root.a + root.b
     16
     >>> root.a += root.b
-    >>> print root.a
+    >>> print(root.a)
     16
 
     >>> root.a = 2
-    >>> print root.a + 2
+    >>> print(root.a + 2)
     4
-    >>> print 1 + root.a
+    >>> print(1 + root.a)
     3
 
-    >>> print root.c
+    >>> print(root.c)
     True
     >>> root.c = False
     >>> if not root.c:
-    ...     print "false!"
+    ...     print("false!")
     false!
 
-    >>> print root.d + " test !"
+    >>> print(root.d + " test !")
     hoi test !
     >>> root.d = "%s - %s"
-    >>> print root.d % (1234, 12345)
+    >>> print(root.d % (1234, 12345))
     1234 - 12345
 
 However, data elements continue to provide the objectify API.  This means that
@@ -666,16 +672,16 @@
 .. sourcecode:: pycon
 
     >>> root = objectify.fromstring("<root><a>test</a><b>toast</b></root>")
-    >>> print root.a + ' me' # behaves like a string, right?
+    >>> print(root.a + ' me') # behaves like a string, right?
     test me
     >>> len(root.a) # but there's only one 'a' element!
     1
     >>> [ a.tag for a in root.a ]
     ['a']
-    >>> print root.a[0].tag
+    >>> print(root.a[0].tag)
     a
 
-    >>> print root.a
+    >>> print(root.a)
     test
     >>> [ str(a) for a in root.a[:1] ]
     ['test']
@@ -714,9 +720,9 @@
     TypeError: attribute 'pyval' of 'StringElement' objects is not writable
 
     >>> root.a = 25
-    >>> print root.a
+    >>> print(root.a)
     25
-    >>> print root.a.pyval
+    >>> print(root.a.pyval)
     25
 
 In other words, ``objectify`` data elements behave like immutable Python
@@ -743,7 +749,7 @@
     ... </root>
     ... """)
 
-    >>> print objectify.dump(root)
+    >>> print(objectify.dump(root))
     root = None [ObjectifiedElement]
         a = 1 [IntElement]
           * attr1 = 'foo'
@@ -760,24 +766,24 @@
 .. sourcecode:: pycon
 
     >>> root = objectify.fromstring("<root><a>5</a></root>")
-    >>> print objectify.dump(root)
+    >>> print(objectify.dump(root))
     root = None [ObjectifiedElement]
         a = 5 [IntElement]
 
     >>> root.a = 'nice string!'
-    >>> print objectify.dump(root)
+    >>> print(objectify.dump(root))
     root = None [ObjectifiedElement]
         a = 'nice string!' [StringElement]
           * py:pytype = 'str'
 
     >>> root.a = True
-    >>> print objectify.dump(root)
+    >>> print(objectify.dump(root))
     root = None [ObjectifiedElement]
         a = True [BoolElement]
           * py:pytype = 'bool'
 
     >>> root.a = [1, 2, 3]
-    >>> print objectify.dump(root)
+    >>> print(objectify.dump(root))
     root = None [ObjectifiedElement]
         a = 1 [IntElement]
           * py:pytype = 'int'
@@ -787,7 +793,7 @@
           * py:pytype = 'int'
 
     >>> root.a = (1, 2, 3)
-    >>> print objectify.dump(root)
+    >>> print(objectify.dump(root))
     root = None [ObjectifiedElement]
         a = 1 [IntElement]
           * py:pytype = 'int'
@@ -819,7 +825,7 @@
     ... </root>
     ... """)
 
-    >>> print str(root)
+    >>> print(str(root))
     root = None [ObjectifiedElement]
         a = 1 [IntElement]
           * attr1 = 'foo'
@@ -884,7 +890,7 @@
 
 .. sourcecode:: pycon
 
-    >>> print objectify.PYTYPE_ATTRIBUTE
+    >>> print(objectify.PYTYPE_ATTRIBUTE)
     {http://codespeak.net/lxml/objectify/pytype}pytype
     >>> ns, name = objectify.PYTYPE_ATTRIBUTE[1:].split('}')
 
@@ -896,11 +902,11 @@
     ... </root>
     ... """ % ns)
 
-    >>> print root.a + 10
+    >>> print(root.a + 10)
     510
-    >>> print root.b + 10
+    >>> print(root.b + 10)
     15
-    >>> print root.c
+    >>> print(root.c)
     None
 
 Note that you can change the name and namespace used for this
@@ -912,14 +918,14 @@
 .. sourcecode:: pycon
 
     >>> root = objectify.fromstring("<root><a>test</a><b>5</b></root>")
-    >>> print objectify.dump(root)
+    >>> print(objectify.dump(root))
     root = None [ObjectifiedElement]
         a = 'test' [StringElement]
         b = 5 [IntElement]
 
     >>> objectify.annotate(root)
 
-    >>> print objectify.dump(root)
+    >>> print(objectify.dump(root))
     root = None [ObjectifiedElement]
         a = 'test' [StringElement]
           * py:pytype = 'str'
@@ -940,16 +946,16 @@
     ...    <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     ...          xmlns:xsd="http://www.w3.org/2001/XMLSchema">
     ...      <d xsi:type="xsd:double">5</d>
-    ...      <l xsi:type="xsd:long"  >5</l>
+    ...      <i xsi:type="xsd:int"   >5</i>
     ...      <s xsi:type="xsd:string">5</s>
     ...    </root>
     ...    ''')
-    >>> print objectify.dump(root)
+    >>> print(objectify.dump(root))
     root = None [ObjectifiedElement]
         d = 5.0 [FloatElement]
           * xsi:type = 'xsd:double'
-        l = 5L [LongElement]
-          * xsi:type = 'xsd:long'
+        i = 5 [IntElement]
+          * xsi:type = 'xsd:int'
         s = '5' [StringElement]
           * xsi:type = 'xsd:string'
 
@@ -961,7 +967,7 @@
     >>> root = objectify.fromstring('''\
     ...    <root><a>test</a><b>5</b><c>true</c></root>
     ...    ''')
-    >>> print objectify.dump(root)
+    >>> print(objectify.dump(root))
     root = None [ObjectifiedElement]
         a = 'test' [StringElement]
         b = 5 [IntElement]
@@ -969,12 +975,12 @@
 
     >>> objectify.xsiannotate(root)
 
-    >>> print objectify.dump(root)
+    >>> print(objectify.dump(root))
     root = None [ObjectifiedElement]
         a = 'test' [StringElement]
           * xsi:type = 'xsd:string'
         b = 5 [IntElement]
-          * xsi:type = 'xsd:int'
+          * xsi:type = 'xsd:integer'
         c = True [BoolElement]
           * xsi:type = 'xsd:boolean'
 
@@ -991,26 +997,26 @@
     ... <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     ...       xmlns:xsd="http://www.w3.org/2001/XMLSchema">
     ...   <d xsi:type="xsd:double">5</d>
-    ...   <l xsi:type="xsd:long"  >5</l>
+    ...   <i xsi:type="xsd:int"   >5</i>
     ...   <s xsi:type="xsd:string">5</s>
     ... </root>''')
     >>> objectify.annotate(root)
-    >>> print objectify.dump(root)
+    >>> print(objectify.dump(root))
     root = None [ObjectifiedElement]
         d = 5.0 [FloatElement]
           * xsi:type = 'xsd:double'
           * py:pytype = 'float'
-        l = 5L [LongElement]
-          * xsi:type = 'xsd:long'
-          * py:pytype = 'long'
+        i = 5 [IntElement]
+          * xsi:type = 'xsd:int'
+          * py:pytype = 'int'
         s = '5' [StringElement]
           * xsi:type = 'xsd:string'
           * py:pytype = 'str'
     >>> objectify.deannotate(root)
-    >>> print objectify.dump(root)
+    >>> print(objectify.dump(root))
     root = None [ObjectifiedElement]
         d = 5 [IntElement]
-        l = 5 [IntElement]
+        i = 5 [IntElement]
         s = 5 [IntElement]
 
 
@@ -1024,24 +1030,24 @@
 .. sourcecode:: pycon
 
     >>> root = objectify.Element("root")
-    >>> root.x = objectify.DataElement(5, _pytype="long")
-    >>> print objectify.dump(root)
+    >>> root.x = objectify.DataElement(5, _pytype="int")
+    >>> print(objectify.dump(root))
     root = None [ObjectifiedElement]
-        x = 5L [LongElement]
-          * py:pytype = 'long'
+        x = 5 [IntElement]
+          * py:pytype = 'int'
 
     >>> root.x = objectify.DataElement(5, _pytype="str", myattr="someval")
-    >>> print objectify.dump(root)
+    >>> print(objectify.dump(root))
     root = None [ObjectifiedElement]
         x = '5' [StringElement]
           * py:pytype = 'str'
           * myattr = 'someval'
 
     >>> root.x = objectify.DataElement(5, _xsi="integer")
-    >>> print objectify.dump(root)
+    >>> print(objectify.dump(root))
     root = None [ObjectifiedElement]
-        x = 5L [LongElement]
-          * py:pytype = 'long'
+        x = 5 [IntElement]
+          * py:pytype = 'int'
           * xsi:type = 'xsd:integer'
 
 XML Schema types reside in the XML schema namespace thus ``DataElement()`` 
@@ -1053,7 +1059,7 @@
     >>> root.s = objectify.DataElement(5, _xsi="string")
 
     >>> objectify.deannotate(root, xsi=False)
-    >>> print etree.tostring(root, pretty_print=True)
+    >>> print(etree.tostring(root, pretty_print=True))
     <root xmlns:py="http://codespeak.net/lxml/objectify/pytype" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
       <s xsi:type="xsd:string">5</s>
     </root>
@@ -1063,15 +1069,15 @@
 .. sourcecode:: pycon
 
     >>> el = objectify.DataElement('5', _xsi='string')
-    >>> namespaces = el.nsmap.items()
+    >>> namespaces = list(el.nsmap.items())
     >>> namespaces.sort()
     >>> for prefix, namespace in namespaces:
-    ...     print prefix, '-', namespace
+    ...     print("%s - %s" % (prefix, namespace))
     py - http://codespeak.net/lxml/objectify/pytype
     xsd - http://www.w3.org/2001/XMLSchema
     xsi - http://www.w3.org/2001/XMLSchema-instance
 
-    >>> print el.get("{http://www.w3.org/2001/XMLSchema-instance}type")
+    >>> print(el.get("{http://www.w3.org/2001/XMLSchema-instance}type"))
     xsd:string
 
 While you can set custom namespace prefixes, it is necessary to provide valid
@@ -1081,15 +1087,15 @@
 
     >>> el = objectify.DataElement('5', _xsi='foo:string',
     ...          nsmap={'foo': 'http://www.w3.org/2001/XMLSchema'})
-    >>> namespaces = el.nsmap.items()
+    >>> namespaces = list(el.nsmap.items())
     >>> namespaces.sort()
     >>> for prefix, namespace in namespaces:
-    ...     print prefix, '-', namespace
+    ...     print("%s - %s" % (prefix, namespace))
     foo - http://www.w3.org/2001/XMLSchema
     py - http://codespeak.net/lxml/objectify/pytype
     xsi - http://www.w3.org/2001/XMLSchema-instance
 
-    >>> print el.get("{http://www.w3.org/2001/XMLSchema-instance}type")
+    >>> print(el.get("{http://www.w3.org/2001/XMLSchema-instance}type"))
     foo:string
 
 Note how lxml chose a default prefix for the XML Schema Instance
@@ -1100,15 +1106,15 @@
     >>> el = objectify.DataElement('5', _xsi='foo:string',
     ...          nsmap={'foo': 'http://www.w3.org/2001/XMLSchema',
     ...                 'myxsi': 'http://www.w3.org/2001/XMLSchema-instance'})
-    >>> namespaces = el.nsmap.items()
+    >>> namespaces = list(el.nsmap.items())
     >>> namespaces.sort()
     >>> for prefix, namespace in namespaces:
-    ...     print prefix, '-', namespace
+    ...     print("%s - %s" % (prefix, namespace))
     foo - http://www.w3.org/2001/XMLSchema
     myxsi - http://www.w3.org/2001/XMLSchema-instance
     py - http://codespeak.net/lxml/objectify/pytype
 
-    >>> print el.get("{http://www.w3.org/2001/XMLSchema-instance}type")
+    >>> print(el.get("{http://www.w3.org/2001/XMLSchema-instance}type"))
     foo:string
 
 Care must be taken if different namespace prefixes have been used for the same
@@ -1119,15 +1125,15 @@
 .. sourcecode:: pycon
 
     >>> root = objectify.fromstring("""<root xmlns:schema="http://www.w3.org/2001/XMLSchema"/>""")
-    >>> print etree.tostring(root, pretty_print=True)
+    >>> print(etree.tostring(root, pretty_print=True))
     <root xmlns:schema="http://www.w3.org/2001/XMLSchema"/>
 
     >>> s = objectify.DataElement("17", _xsi="string")
-    >>> print etree.tostring(s, pretty_print=True)
+    >>> print(etree.tostring(s, pretty_print=True))
     <value xmlns:py="http://codespeak.net/lxml/objectify/pytype" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" py:pytype="str" xsi:type="xsd:string">17</value>
 
     >>> root.s = s
-    >>> print etree.tostring(root, pretty_print=True)
+    >>> print(etree.tostring(root, pretty_print=True))
     <root xmlns:schema="http://www.w3.org/2001/XMLSchema">
       <s xmlns:py="http://codespeak.net/lxml/objectify/pytype" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" py:pytype="str" xsi:type="xsd:string">17</s>
     </root>
@@ -1139,7 +1145,7 @@
 .. sourcecode:: pycon
 
     >>> objectify.xsiannotate(root)
-    >>> print etree.tostring(root, pretty_print=True)
+    >>> print(etree.tostring(root, pretty_print=True))
     <root xmlns:schema="http://www.w3.org/2001/XMLSchema">
       <s xmlns:py="http://codespeak.net/lxml/objectify/pytype" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" py:pytype="str" xsi:type="schema:string">17</s>
     </root>
@@ -1165,7 +1171,7 @@
 
     >>> class ChristmasDate(objectify.ObjectifiedDataElement):
     ...     def call_santa(self):
-    ...         print "Ho ho ho!"
+    ...         print("Ho ho ho!")
 
     >>> def checkChristmasDate(date_string):
     ...     if not date_string.startswith('24.12.'):
@@ -1225,7 +1231,7 @@
     ...      <a xsi:type="date">12.24.2000</a>
     ...    </root>
     ...    ''')
-    >>> print root.a
+    >>> print(root.a)
     12.24.2000
     >>> root.a.call_santa()
     Ho ho ho!

Modified: lxml/trunk/src/lxml/extensions.pxi
==============================================================================
--- lxml/trunk/src/lxml/extensions.pxi	(original)
+++ lxml/trunk/src/lxml/extensions.pxi	Wed May 21 21:45:48 2008
@@ -262,11 +262,11 @@
             c_dict = python.PyDict_GetItem(
                 self._function_cache, None)
         else:
-            c_dict = python.PyDict_GetItemString(
+            c_dict = python.PyDict_GetItem(
                 self._function_cache, c_ns_uri)
 
         if c_dict is not NULL:
-            dict_result = python.PyDict_GetItemString(
+            dict_result = python.PyDict_GetItem(
                 <object>c_dict, c_name)
             if dict_result is not NULL:
                 return <object>dict_result

Modified: lxml/trunk/src/lxml/lxml.objectify.pyx
==============================================================================
--- lxml/trunk/src/lxml/lxml.objectify.pyx	(original)
+++ lxml/trunk/src/lxml/lxml.objectify.pyx	Wed May 21 21:45:48 2008
@@ -1,10 +1,10 @@
-"""The ``lxml.objectify`` module implements a Python object API for
+u"""The ``lxml.objectify`` module implements a Python object API for
 XML.  It is based on `lxml.etree`.
 """
 
 from etreepublic cimport _Document, _Element, ElementBase
 from etreepublic cimport _ElementIterator, ElementClassLookup
-from etreepublic cimport elementFactory, import_lxml__etree, textOf
+from etreepublic cimport elementFactory, import_lxml__etree, textOf, pyunicode
 from python cimport callable, _cstr
 cimport etreepublic as cetree
 cimport python
@@ -21,15 +21,21 @@
 cdef object re
 import re
 
-cdef object __builtin__
-import __builtin__
+try:
+    import __builtin__
+except ImportError:
+    # Python 3
+    import builtins as __builtin__
 
 cdef object set
 try:
     set = __builtin__.set
 except AttributeError:
+    # Python 2.3
     from sets import Set as set
 
+del __builtin__
+
 cdef object IGNORABLE_ERRORS
 IGNORABLE_ERRORS = (ValueError, TypeError)
 
@@ -41,25 +47,29 @@
     cdef char* s
     c_name = python._fqtypename(t)
     s = cstd.strrchr(c_name, c'.')
-    if s == NULL:
-        return c_name
-    else:
-        return (s+1)
+    if s is not NULL:
+        c_name = s + 1
+    return pyunicode(c_name)
 
 # namespace/name for "pytype" hint attribute
 cdef object PYTYPE_NAMESPACE
+cdef object PYTYPE_NAMESPACE_UTF8
 cdef char* _PYTYPE_NAMESPACE
 
 cdef object PYTYPE_ATTRIBUTE_NAME
+cdef object PYTYPE_ATTRIBUTE_NAME_UTF8
 cdef char* _PYTYPE_ATTRIBUTE_NAME
 
 PYTYPE_ATTRIBUTE = None
 
 cdef object TREE_PYTYPE_NAME
-TREE_PYTYPE_NAME = "TREE"
+TREE_PYTYPE_NAME = u"TREE"
+
+cdef _unicodeAndUtf8(s):
+    return (s, python.PyUnicode_AsUTF8String(s))
 
 def set_pytype_attribute_tag(attribute_tag=None):
-    """set_pytype_attribute_tag(attribute_tag=None)
+    u"""set_pytype_attribute_tag(attribute_tag=None)
     Change name and namespace of the XML attribute that holds Python type
     information.
 
@@ -70,14 +80,23 @@
     Default: "{http://codespeak.net/lxml/objectify/pytype}pytype"
     """
     global PYTYPE_ATTRIBUTE, _PYTYPE_NAMESPACE, _PYTYPE_ATTRIBUTE_NAME
-    global PYTYPE_NAMESPACE, PYTYPE_ATTRIBUTE_NAME
+    global PYTYPE_NAMESPACE, PYTYPE_NAMESPACE_UTF8
+    global PYTYPE_ATTRIBUTE_NAME, PYTYPE_ATTRIBUTE_NAME_UTF8
     if attribute_tag is None:
-        PYTYPE_NAMESPACE      = "http://codespeak.net/lxml/objectify/pytype"
-        PYTYPE_ATTRIBUTE_NAME = "pytype"
+        PYTYPE_NAMESPACE, PYTYPE_NAMESPACE_UTF8 = \
+            _unicodeAndUtf8(u"http://codespeak.net/lxml/objectify/pytype")
+        PYTYPE_ATTRIBUTE_NAME, PYTYPE_ATTRIBUTE_NAME_UTF8 = \
+            _unicodeAndUtf8(u"pytype")
     else:
-        PYTYPE_NAMESPACE, PYTYPE_ATTRIBUTE_NAME = cetree.getNsTag(attribute_tag)
-    _PYTYPE_NAMESPACE      = _cstr(PYTYPE_NAMESPACE)
-    _PYTYPE_ATTRIBUTE_NAME = _cstr(PYTYPE_ATTRIBUTE_NAME)
+        PYTYPE_NAMESPACE_UTF8, PYTYPE_ATTRIBUTE_NAME_UTF8 = \
+            cetree.getNsTag(attribute_tag)
+        PYTYPE_NAMESPACE = python.PyUnicode_FromEncodedObject(
+            PYTYPE_NAMESPACE_UTF8, 'UTF-8', NULL)
+        PYTYPE_ATTRIBUTE_NAME = python.PyUnicode_FromEncodedObject(
+            PYTYPE_ATTRIBUTE_NAME_UTF8, 'UTF-8', NULL)
+
+    _PYTYPE_NAMESPACE      = _cstr(PYTYPE_NAMESPACE_UTF8)
+    _PYTYPE_ATTRIBUTE_NAME = _cstr(PYTYPE_ATTRIBUTE_NAME_UTF8)
     PYTYPE_ATTRIBUTE = cetree.namespacedNameFromNsName(
         _PYTYPE_NAMESPACE, _PYTYPE_ATTRIBUTE_NAME)
 
@@ -85,20 +104,22 @@
 
 
 # namespaces for XML Schema
-cdef object XML_SCHEMA_NS
-XML_SCHEMA_NS = "http://www.w3.org/2001/XMLSchema"
+cdef object XML_SCHEMA_NS, XML_SCHEMA_NS_UTF8
+XML_SCHEMA_NS, XML_SCHEMA_NS_UTF8 = \
+    _unicodeAndUtf8(u"http://www.w3.org/2001/XMLSchema")
 cdef char* _XML_SCHEMA_NS
-_XML_SCHEMA_NS = _cstr(XML_SCHEMA_NS)
+_XML_SCHEMA_NS = _cstr(XML_SCHEMA_NS_UTF8)
 
-cdef object XML_SCHEMA_INSTANCE_NS
-XML_SCHEMA_INSTANCE_NS = "http://www.w3.org/2001/XMLSchema-instance"
+cdef object XML_SCHEMA_INSTANCE_NS, XML_SCHEMA_INSTANCE_NS_UTF8
+XML_SCHEMA_INSTANCE_NS, XML_SCHEMA_INSTANCE_NS_UTF8 = \
+    _unicodeAndUtf8(u"http://www.w3.org/2001/XMLSchema-instance")
 cdef char* _XML_SCHEMA_INSTANCE_NS
-_XML_SCHEMA_INSTANCE_NS = _cstr(XML_SCHEMA_INSTANCE_NS)
+_XML_SCHEMA_INSTANCE_NS = _cstr(XML_SCHEMA_INSTANCE_NS_UTF8)
 
 cdef object XML_SCHEMA_INSTANCE_NIL_ATTR
-XML_SCHEMA_INSTANCE_NIL_ATTR = "{%s}nil" % XML_SCHEMA_INSTANCE_NS
+XML_SCHEMA_INSTANCE_NIL_ATTR = u"{%s}nil" % XML_SCHEMA_INSTANCE_NS
 cdef object XML_SCHEMA_INSTANCE_TYPE_ATTR
-XML_SCHEMA_INSTANCE_TYPE_ATTR = "{%s}type" % XML_SCHEMA_INSTANCE_NS
+XML_SCHEMA_INSTANCE_TYPE_ATTR = u"{%s}type" % XML_SCHEMA_INSTANCE_NS
 
 
 # Forward declaration
@@ -108,7 +129,7 @@
 # Element class for the main API
 
 cdef class ObjectifiedElement(ElementBase):
-    """Main XML Element class.
+    u"""Main XML Element class.
 
     Element children are accessed as object attributes.  Multiple children
     with the same name are available through a list index.  Example:
@@ -120,7 +141,7 @@
     subclasses.
     """
     def __iter__(self):
-        """Iterate over self and all siblings with the same tag.
+        u"""Iterate over self and all siblings with the same tag.
         """
         parent = self.getparent()
         if parent is None:
@@ -131,14 +152,14 @@
         if __RECURSIVE_STR:
             return _dump(self, 0)
         else:
-            return textOf(self._c_node) or ''
+            return textOf(self._c_node) or u''
 
     property text:
         def __get__(self):
             return textOf(self._c_node)
 
     property __dict__:
-        """A fake implementation for __dict__ to support dir() etc.
+        u"""A fake implementation for __dict__ to support dir() etc.
 
         Note that this only considers the first child with a given name.
         """
@@ -150,23 +171,23 @@
             if c_ns is NULL:
                 tag = None
             else:
-                tag = "{%s}*" % c_ns
+                tag = u"{%s}*" % pyunicode(c_ns)
             children = {}
             for child in etree.ElementChildIterator(self, tag=tag):
                 if c_ns is NULL and tree._getNs(child._c_node) is not NULL:
                     continue
-                name = child._c_node.name
+                name = pyunicode(child._c_node.name)
                 if python.PyDict_GetItem(children, name) is NULL:
                     python.PyDict_SetItem(children, name, child)
             return children
 
     def __len__(self):
-        """Count self and siblings with the same tag.
+        u"""Count self and siblings with the same tag.
         """
         return _countSiblings(self._c_node)
 
     def countchildren(self):
-        """countchildren(self)
+        u"""countchildren(self)
 
         Return the number of children of this element, regardless of their
         name.
@@ -183,7 +204,7 @@
         return c
 
     def getchildren(self):
-        """getchildren(self)
+        u"""getchildren(self)
 
         Returns a sequence of all direct children.  The elements are
         returned in document order.
@@ -199,26 +220,26 @@
         return result
 
     def __getattr__(self, tag):
-        """Return the (first) child with the given tag name.  If no namespace
+        u"""Return the (first) child with the given tag name.  If no namespace
         is provided, the child will be looked up in the same one as self.
         """
         return _lookupChildOrRaise(self, tag)
 
     def __setattr__(self, tag, value):
-        """Set the value of the (first) child with the given tag name.  If no
+        u"""Set the value of the (first) child with the given tag name.  If no
         namespace is provided, the child will be looked up in the same one as
         self.
         """
         cdef _Element element
         # properties are looked up /after/ __setattr__, so we must emulate them
-        if tag == 'text' or tag == 'pyval':
+        if tag == u'text' or tag == u'pyval':
             # read-only !
-            raise TypeError, "attribute '%s' of '%s' objects is not writable" % \
+            raise TypeError, u"attribute '%s' of '%s' objects is not writable" % \
                             (tag, _typename(self))
-        elif tag == 'tail':
+        elif tag == u'tail':
             cetree.setTailText(self._c_node, value)
             return
-        elif tag == 'tag':
+        elif tag == u'tag':
             ElementBase.tag.__set__(self, value)
             return
 
@@ -234,7 +255,7 @@
         self.remove(child)
 
     def addattr(self, tag, value):
-        """addattr(self, tag, value)
+        u"""addattr(self, tag, value)
 
         Add a child value to the element.
 
@@ -243,7 +264,7 @@
         _appendValue(self, _buildChildTag(self, tag), value)
 
     def __getitem__(self, key):
-        """Return a sibling, counting from the first child of the parent.  The
+        u"""Return a sibling, counting from the first child of the parent.  The
         method behaves like both a dict and a sequence.
 
         * If argument is an integer, returns the sibling at that position.
@@ -269,7 +290,7 @@
             if key == 0:
                 return self
             else:
-                raise IndexError, str(key)
+                raise IndexError, unicode(key)
         if key < 0:
             c_node = c_parent.last
         else:
@@ -277,11 +298,11 @@
         c_node = _findFollowingSibling(
             c_node, tree._getNs(c_self_node), c_self_node.name, key)
         if c_node is NULL:
-            raise IndexError, str(key)
+            raise IndexError, unicode(key)
         return elementFactory(self._doc, c_node)
 
     def __setitem__(self, key, value):
-        """Set the value of a sibling, counting from the first child of the
+        u"""Set the value of a sibling, counting from the first child of the
         parent.  Implements key assignment, item assignment and slice
         assignment.
 
@@ -306,7 +327,7 @@
 
         if self._c_node.parent is NULL:
             # the 'root[i] = ...' case
-            raise TypeError, "assignment to root element is invalid"
+            raise TypeError, u"assignment to root element is invalid"
 
         if python.PySlice_Check(key):
             # slice assignment
@@ -320,7 +341,7 @@
             c_node = _findFollowingSibling(
                 c_node, tree._getNs(self._c_node), self._c_node.name, key)
             if c_node is NULL:
-                raise IndexError, str(key)
+                raise IndexError, unicode(key)
             element = elementFactory(self._doc, c_node)
             _replaceElement(element, value)
 
@@ -328,7 +349,7 @@
         cdef Py_ssize_t start, stop, step, slicelength
         parent = self.getparent()
         if parent is None:
-            raise TypeError, "deleting items not supported by root element"
+            raise TypeError, u"deleting items not supported by root element"
         if python.PySlice_Check(key):
             # slice deletion
             del_items = list(self)[key]
@@ -341,21 +362,21 @@
             parent.remove(sibling)
 
     def iterfind(self, path):
-        "iterfind(self, path)"
+        u"iterfind(self, path)"
         # Reimplementation of Element.iterfind() to make it work without child
         # iteration.
         xpath = etree.ETXPath(path)
         return iter(xpath(self))
 
     def findall(self, path):
-        "findall(self, path)"
+        u"findall(self, path)"
         # Reimplementation of Element.findall() to make it work without child
         # iteration.
         xpath = etree.ETXPath(path)
         return xpath(self)
 
     def find(self, path):
-        "find(self, path)"
+        u"find(self, path)"
         # Reimplementation of Element.find() to make it work without child
         # iteration.
         result = self.findall(path)
@@ -367,22 +388,22 @@
             return None
 
     def findtext(self, path, default=None):
-        "findtext(self, path, default=None)"
+        u"findtext(self, path, default=None)"
         # Reimplementation of Element.findtext() to make it work without child
         # iteration.
         result = self.find(path)
         if isinstance(result, _Element):
-            return result.text or ""
+            return result.text or u""
         else:
             return default
 
     def descendantpaths(self, prefix=None):
-        """descendantpaths(self, prefix=None)
+        u"""descendantpaths(self, prefix=None)
 
         Returns a list of object path expressions for all descendants.
         """
         if prefix is not None and not python._isString(prefix):
-            prefix = '.'.join(prefix)
+            prefix = u'.'.join(prefix)
         return _buildDescendantPaths(self._c_node, prefix)
 
 cdef inline bint _tagMatches(tree.xmlNode* c_node, char* c_href, char* c_name):
@@ -460,7 +481,7 @@
     element = _lookupChild(parent, tag)
     if element is None:
         raise AttributeError, \
-            "no such child: " + _buildChildTag(parent, tag)
+            u"no such child: " + _buildChildTag(parent, tag)
     return element
 
 cdef object _buildChildTag(_Element parent, tag):
@@ -509,15 +530,15 @@
     cdef python.PyObject* _pytype
     if value is None:
         cetree.setAttributeValue(
-            element, XML_SCHEMA_INSTANCE_NIL_ATTR, "true")
+            element, XML_SCHEMA_INSTANCE_NIL_ATTR, u"true")
     elif isinstance(value, _Element):
         _replaceElement(element, value)
         return
     else:
         cetree.delAttributeFromNsName(
-            element._c_node, _XML_SCHEMA_INSTANCE_NS, "nil")
+            element._c_node, _XML_SCHEMA_INSTANCE_NS, u"nil")
         if python._isString(value):
-            pytype_name = "str"
+            pytype_name = u"str"
             _pytype = python.PyDict_GetItem(_PYTYPE_DICT, pytype_name)
         else:
             pytype_name = _typename(value)
@@ -525,12 +546,12 @@
             if _pytype is not NULL:
                 value = (<PyType>_pytype).stringify(value)
             else:
-                value = str(value)
+                value = unicode(value)
         if _pytype is not NULL:
             cetree.setAttributeValue(element, PYTYPE_ATTRIBUTE, pytype_name)
         else:
-            cetree.delAttributeFromNsName(element._c_node, PYTYPE_NAMESPACE,
-                                          PYTYPE_ATTRIBUTE_NAME)
+            cetree.delAttributeFromNsName(
+                element._c_node, _PYTYPE_NAMESPACE, _PYTYPE_ATTRIBUTE_NAME)
     cetree.setNodeText(element._c_node, value)
 
 cdef _setSlice(slice, _Element target, items):
@@ -543,7 +564,7 @@
     else:
         c_step = (<python.slice>slice).step
     if c_step == 0:
-        raise ValueError, "Invalid slice"
+        raise ValueError, u"Invalid slice"
     del_items = target[slice]
 
     # collect new values
@@ -565,7 +586,7 @@
     if c_step != 1 and \
             python.PyList_GET_SIZE(del_items) != python.PyList_GET_SIZE(new_items):
         raise ValueError, \
-            "attempt to assign sequence of size %d to extended slice of size %d" % (
+            u"attempt to assign sequence of size %d to extended slice of size %d" % (
             python.PyList_GET_SIZE(new_items),
             python.PyList_GET_SIZE(del_items))
 
@@ -612,7 +633,7 @@
 # Data type support in subclasses
 
 cdef class ObjectifiedDataElement(ObjectifiedElement):
-    """This is the base class for all data type Elements.  Subclasses should
+    u"""This is the base class for all data type Elements.  Subclasses should
     override the 'pyval' property and possibly the __str__ method.
     """
     property pyval:
@@ -620,13 +641,13 @@
             return textOf(self._c_node)
 
     def __str__(self):
-        return textOf(self._c_node) or ''
+        return textOf(self._c_node) or u''
 
     def __repr__(self):
-        return textOf(self._c_node) or ''
+        return textOf(self._c_node) or u''
 
     def _setText(self, s):
-        """For use in subclasses only. Don't use unless you know what you are
+        u"""For use in subclasses only. Don't use unless you know what you are
         doing.
         """
         cetree.setNodeText(self._c_node, s)
@@ -634,7 +655,7 @@
 cdef class NumberElement(ObjectifiedDataElement):
     cdef object _parse_value
     def _setValueParser(self, function):
-        """Set the function that parses the Python value from a string.
+        u"""Set the function that parses the Python value from a string.
 
         Do not use this unless you know what you are doing.
         """
@@ -657,7 +678,7 @@
         return complex(_parseNumber(self))
 
     def __str__(self):
-        return str(_parseNumber(self))
+        return unicode(_parseNumber(self))
 
     def __repr__(self):
         return repr(_parseNumber(self))
@@ -738,7 +759,7 @@
         self._parse_value = float
 
 cdef class StringElement(ObjectifiedDataElement):
-    """String data class.
+    u"""String data class.
 
     Note that this class does *not* support the sequence protocol of strings:
     len(), iter(), str_attr[0], str_attr[0:1], etc. are *not* supported.
@@ -746,10 +767,10 @@
     """
     property pyval:
         def __get__(self):
-            return textOf(self._c_node) or ''
+            return textOf(self._c_node) or u''
 
     def __repr__(self):
-        return repr(textOf(self._c_node) or '')
+        return repr(textOf(self._c_node) or u'')
 
     def strlen(self):
         text = textOf(self._c_node)
@@ -782,7 +803,7 @@
         elif isinstance(other, StringElement):
             return _numericValueOf(self) * textOf((<StringElement>other)._c_node)
         else:
-            raise TypeError, "invalid types for * operator"
+            raise TypeError, u"invalid types for * operator"
 
     def __mod__(self, other):
         return _strValueOf(self) % other
@@ -801,10 +822,10 @@
 
 cdef class NoneElement(ObjectifiedDataElement):
     def __str__(self):
-        return "None"
+        return u"None"
 
     def __repr__(self):
-        return "None"
+        return u"None"
 
     def __nonzero__(self):
         return False
@@ -822,7 +843,7 @@
             return None
 
 cdef class BoolElement(IntElement):
-    """Boolean type base on string values: 'true' or 'false'.
+    u"""Boolean type base on string values: 'true' or 'false'.
 
     Note that this inherits from IntElement to mimic the behaviour of
     Python's bool type.
@@ -837,7 +858,7 @@
         return _richcmpPyvals(self, other, op)
 
     def __str__(self):
-        return str(__parseBool(textOf(self._c_node)))
+        return unicode(__parseBool(textOf(self._c_node)))
 
     def __repr__(self):
         return repr(__parseBool(textOf(self._c_node)))
@@ -859,21 +880,22 @@
         return False
     value = __parseBoolAsInt(s)
     if value == -1:
-        raise ValueError, "Invalid boolean value: '%s'" % s
+        raise ValueError, u"Invalid boolean value: '%s'" % s
     return <bint>value
 
 cdef inline int __parseBoolAsInt(text):
     cdef char* c_str
-    c_str = _cstr(text)
-    if c_str[0] == c'0' or c_str[0] == c'f' or c_str[0] == c'F':
-        if c_str[1] == c'\0' or text == "false" or text.lower() == "false":
-            # '0' or 'f' or 'false'
-            return 0
-    elif c_str[0] == c'1' or c_str[0] == c't' or c_str[0] == c'T':
-        if c_str[1] == c'\0' or text == "true" or text.lower() == "true":
-            # '1' or 't' or 'true'
-            return 1
-    return -1
+    if text == u'0':
+        return 0
+    elif text == u'1':
+        return 1
+    text = text.lower()
+    if text == u'f' or text == u'false':
+        return 0
+    elif text == u't' or text == u'true':
+        return 1
+    else:
+        return -1
 
 cdef inline _parseNumber(NumberElement element):
     return element._parse_value(textOf(element._c_node))
@@ -882,22 +904,22 @@
     if python._isString(obj):
         return obj
     if isinstance(obj, _Element):
-        return textOf((<_Element>obj)._c_node) or ''
+        return textOf((<_Element>obj)._c_node) or u''
     if obj is None:
-        return ''
-    return str(obj)
+        return u''
+    return unicode(obj)
 
 cdef inline object _numericValueOf(obj):
     if isinstance(obj, NumberElement):
         return _parseNumber(<NumberElement>obj)
-    elif hasattr(obj, 'pyval'):
+    elif hasattr(obj, u'pyval'):
         # not always numeric, but Python will raise the right exception
         return obj.pyval
     return obj
 
 cdef inline _richcmpPyvals(left, right, int op):
-    left  = getattr3(left,  'pyval', left)
-    right = getattr3(right, 'pyval', right)
+    left  = getattr3(left,  u'pyval', left)
+    right = getattr3(right, u'pyval', right)
     return python.PyObject_RichCompare(left, right, op)
 
 
@@ -905,7 +927,7 @@
 # Python type registry
 
 cdef class PyType:
-    """PyType(self, name, type_check, type_class, stringify=None)
+    u"""PyType(self, name, type_check, type_class, stringify=None)
     User defined type.
 
     Named type that contains a type check function and a type class that
@@ -928,26 +950,26 @@
     cdef object _schema_types
     def __init__(self, name, type_check, type_class, stringify=None):
         if not python._isString(name):
-            raise TypeError, "Type name must be a string"
+            raise TypeError, u"Type name must be a string"
         if type_check is not None and not callable(type_check):
-            raise TypeError, "Type check function must be callable (or None)"
+            raise TypeError, u"Type check function must be callable (or None)"
         if name != TREE_PYTYPE_NAME and \
                not issubclass(type_class, ObjectifiedDataElement):
             raise TypeError, \
-                "Data classes must inherit from ObjectifiedDataElement"
+                u"Data classes must inherit from ObjectifiedDataElement"
         self.name  = name
         self._type = type_class
         self.type_check = type_check
         if stringify is None:
-            stringify = str
+            stringify = unicode
         self.stringify = stringify
         self._schema_types = []
 
     def __repr__(self):
-        return "PyType(%s, %s)" % (self.name, self._type.__name__)
+        return u"PyType(%s, %s)" % (self.name, self._type.__name__)
 
     def register(self, before=None, after=None):
-        """register(self, before=None, after=None)
+        u"""register(self, before=None, after=None)
 
         Register the type.
 
@@ -957,7 +979,7 @@
         ignored.  Raises ValueError if the dependencies cannot be fulfilled.
         """
         if self.name == TREE_PYTYPE_NAME:
-            raise ValueError, "Cannot register tree type"
+            raise ValueError, u"Cannot register tree type"
         if self.type_check is not None:
             for item in _TYPE_CHECKS:
                 if item[0] is self.type_check:
@@ -979,7 +1001,7 @@
             if last_pos == -1:
                 _TYPE_CHECKS.append(entry)
             elif first_pos > last_pos:
-                raise ValueError, "inconsistent before/after dependencies"
+                raise ValueError, u"inconsistent before/after dependencies"
             else:
                 _TYPE_CHECKS.insert(last_pos, entry)
 
@@ -988,10 +1010,10 @@
             _SCHEMA_TYPE_DICT[xs_type] = self
 
     def unregister(self):
-        "unregister(self)"
+        u"unregister(self)"
         if _PYTYPE_DICT.get(self.name) is self:
             del _PYTYPE_DICT[self.name]
-        for xs_type, pytype in _SCHEMA_TYPE_DICT.items():
+        for xs_type, pytype in list(_SCHEMA_TYPE_DICT.items()):
             if pytype is self:
                 del _SCHEMA_TYPE_DICT[xs_type]
         if self.type_check is None:
@@ -1002,7 +1024,7 @@
             pass
 
     property xmlSchemaTypes:
-        """The list of XML Schema datatypes this Python type maps to.
+        u"""The list of XML Schema datatypes this Python type maps to.
 
         Note that this must be set before registering the type!
         """
@@ -1023,59 +1045,58 @@
 
 cdef _lower_bool(b):
     if b:
-        return "true"
+        return u"true"
     else:
-        return "false"
+        return u"false"
 
 def __lower_bool(b):
     return _lower_bool(b)
 
 cdef _pytypename(obj):
     if python._isString(obj):
-        return "str"
+        return u"str"
     else:
         return _typename(obj)
 
 def pytypename(obj):
-    """pytypename(obj)
+    u"""pytypename(obj)
 
     Find the name of the corresponding PyType for a Python object.
     """
     return _pytypename(obj)
 
 cdef _registerPyTypes():
-    pytype = PyType('int', int, IntElement)
-    pytype.xmlSchemaTypes = ("int", "short", "byte", "unsignedShort",
-                             "unsignedByte",)
-    
+    pytype = PyType(u'int', int, IntElement)
+    pytype.xmlSchemaTypes = (u"integer", u"int", u"short", u"byte", u"unsignedShort",
+                             u"unsignedByte", u"nonPositiveInteger",
+                             u"negativeInteger", u"long", u"nonNegativeInteger",
+                             u"unsignedLong", u"unsignedInt", u"positiveInteger",)
     pytype.register()
 
-    pytype = PyType('long', long, LongElement)
-    pytype.xmlSchemaTypes = ("integer", "nonPositiveInteger", "negativeInteger",
-                             "long", "nonNegativeInteger", "unsignedLong",
-                             "unsignedInt", "positiveInteger",)
+    # 'long' type just for backwards compatibility
+    pytype = PyType(u'long', None, IntElement)
     pytype.register()
 
-    pytype = PyType('float', float, FloatElement)
-    pytype.xmlSchemaTypes = ("double", "float")
+    pytype = PyType(u'float', float, FloatElement)
+    pytype.xmlSchemaTypes = (u"double", u"float")
     pytype.register()
 
-    pytype = PyType('bool', __checkBool, BoolElement, __lower_bool)
-    pytype.xmlSchemaTypes = ("boolean",)
+    pytype = PyType(u'bool', __checkBool, BoolElement, __lower_bool)
+    pytype.xmlSchemaTypes = (u"boolean",)
     pytype.register()
 
-    pytype = PyType('str', None, StringElement)
-    pytype.xmlSchemaTypes = ("string", "normalizedString", "token", "language",
-                             "Name", "NCName", "ID", "IDREF", "ENTITY",
-                             "NMTOKEN", )
+    pytype = PyType(u'str', None, StringElement)
+    pytype.xmlSchemaTypes = (u"string", u"normalizedString", u"token", u"language",
+                             u"Name", u"NCName", u"ID", u"IDREF", u"ENTITY",
+                             u"NMTOKEN", )
     pytype.register()
 
     # since lxml 2.0
-    pytype = PyType('NoneType', None, NoneElement)
+    pytype = PyType(u'NoneType', None, NoneElement)
     pytype.register()
 
     # backwards compatibility
-    pytype = PyType('none', None, NoneElement)
+    pytype = PyType(u'none', None, NoneElement)
     pytype.register()
 
 # non-registered PyType for inner tree elements
@@ -1085,7 +1106,7 @@
 _registerPyTypes()
 
 def getRegisteredTypes():
-    """getRegisteredTypes()
+    u"""getRegisteredTypes()
 
     Returns a list of the currently registered PyType objects.
 
@@ -1107,7 +1128,7 @@
         if name not in known:
             add_to_known(name)
             python.PyList_Append(types, pytype)
-    for pytype in _PYTYPE_DICT.itervalues():
+    for pytype in _PYTYPE_DICT.values():
         name = pytype.name
         if name not in known:
             add_to_known(name)
@@ -1130,7 +1151,7 @@
     value = textOf(c_node)
     if value is None:
         return None
-    if value == '':
+    if value == u'':
         return StringElement
     
     for type_check, pytype in _TYPE_CHECKS:
@@ -1151,7 +1172,7 @@
     cdef _ObjectifyElementMakerCaller NEW_ELEMENT_MAKER "PY_NEW" (object t)
 
 cdef class ElementMaker:
-    """ElementMaker(self, namespace=None, nsmap=None, annotate=True, makeelement=None)
+    u"""ElementMaker(self, namespace=None, nsmap=None, annotate=True, makeelement=None)
     """
     cdef object _makeelement
     cdef object _namespace
@@ -1165,7 +1186,7 @@
         if namespace is None:
             self._namespace = None
         else:
-            self._namespace = "{%s}" % namespace
+            self._namespace = u"{%s}" % namespace
         self._annotate = annotate
         if makeelement is not None:
             assert callable(makeelement)
@@ -1175,7 +1196,7 @@
 
     def __getattr__(self, tag):
         cdef _ObjectifyElementMakerCaller element_maker
-        if self._namespace is not None and tag[0] != "{":
+        if self._namespace is not None and tag[0] != u"{":
             tag = self._namespace + tag
         element_maker = NEW_ELEMENT_MAKER(_ObjectifyElementMakerCaller)
         element_maker._tag = tag
@@ -1191,7 +1212,7 @@
     cdef bint _annotate
 
     def __call__(self, *children, **attrib):
-        "__call__(self, *children, **attrib)"
+        u"__call__(self, *children, **attrib)"
         cdef _ObjectifyElementMakerCaller elementMaker
         cdef python.PyObject* pytype
         cdef _Element element
@@ -1210,7 +1231,7 @@
             if child is None:
                 if python.PyTuple_GET_SIZE(children) == 1:
                     cetree.setAttributeValue(
-                        element, XML_SCHEMA_INSTANCE_NIL_ATTR, "true")
+                        element, XML_SCHEMA_INSTANCE_NIL_ATTR, u"true")
             elif python._isString(child):
                 _add_text(element, child)
                 has_string_value = 1
@@ -1237,12 +1258,12 @@
                     _add_text(element, (<PyType>pytype).stringify(child))
                 else:
                     has_string_value = 1
-                    child = str(child)
+                    child = unicode(child)
                     _add_text(element, child)
 
         if self._annotate and not has_children:
             if has_string_value:
-                cetree.setAttributeValue(element, PYTYPE_ATTRIBUTE, "str")
+                cetree.setAttributeValue(element, PYTYPE_ATTRIBUTE, u"str")
             elif pytype_name is not None:
                 cetree.setAttributeValue(element, PYTYPE_ATTRIBUTE, pytype_name)
 
@@ -1269,7 +1290,7 @@
 __RECURSIVE_STR = 0 # default: off
 
 def enableRecursiveStr(on=True):
-    """enableRecursiveStr(on=True)
+    u"""enableRecursiveStr(on=True)
 
     Enable a recursively generated tree representation for str(element),
     based on objectify.dump(element).
@@ -1280,7 +1301,7 @@
     __RECURSIVE_STR = on
 
 def enable_recursive_str(on=True):
-    """enableRecursiveStr(on=True)
+    u"""enableRecursiveStr(on=True)
 
     Enable a recursively generated tree representation for str(element),
     based on objectify.dump(element).
@@ -1289,36 +1310,36 @@
     __RECURSIVE_STR = on
 
 def dump(_Element element not None):
-    """dump(_Element element not None)
+    u"""dump(_Element element not None)
 
     Return a recursively generated string representation of an element.
     """
     return _dump(element, 0)
 
 cdef object _dump(_Element element, int indent):
-    indentstr = "    " * indent
+    indentstr = u"    " * indent
     if isinstance(element, ObjectifiedDataElement):
         value = repr(element)
     else:
         value = textOf(element._c_node)
         if value is not None:
-            if python.PyString_GET_SIZE( value.strip() ) == 0:
+            if not value.strip():
                 value = None
             else:
                 value = repr(value)
-    result = "%s%s = %s [%s]\n" % (indentstr, element.tag,
-                                   value, _typename(element))
-    xsi_ns    = "{%s}" % XML_SCHEMA_INSTANCE_NS
-    pytype_ns = "{%s}" % PYTYPE_NAMESPACE
+    result = u"%s%s = %s [%s]\n" % (indentstr, element.tag,
+                                    value, _typename(element))
+    xsi_ns    = u"{%s}" % XML_SCHEMA_INSTANCE_NS
+    pytype_ns = u"{%s}" % PYTYPE_NAMESPACE
     for name, value in cetree.iterattributes(element, 3):
-        if '{' in name:
+        if u'{' in name:
             if name == PYTYPE_ATTRIBUTE:
                 if value == TREE_PYTYPE_NAME:
                     continue
                 else:
-                    name = name.replace(pytype_ns, 'py:')
-            name = name.replace(xsi_ns, 'xsi:')
-        result = result + "%s  * %s = %r\n" % (indentstr, name, value)
+                    name = name.replace(pytype_ns, u'py:')
+            name = name.replace(xsi_ns, u'xsi:')
+        result = result + u"%s  * %s = %r\n" % (indentstr, name, value)
 
     indent = indent + 1
     for child in element.iterchildren():
@@ -1338,7 +1359,7 @@
     copy_reg.pickle(ObjectifiedElement, reduceFunction, fromstring)
 
 def pickleReduce(obj):
-    "pickleReduce(obj)"
+    u"pickleReduce(obj)"
     return (fromstring, (etree.tostring(obj),))
 
 _setupPickle(pickleReduce)
@@ -1348,13 +1369,13 @@
 # Element class lookup
 
 cdef class ObjectifyElementClassLookup(ElementClassLookup):
-    """ObjectifyElementClassLookup(self, tree_class=None, empty_data_class=None)
+    u"""ObjectifyElementClassLookup(self, tree_class=None, empty_data_class=None)
     Element class lookup method that uses the objectify classes.
     """
     cdef object empty_data_class
     cdef object tree_class
     def __init__(self, tree_class=None, empty_data_class=None):
-        """Lookup mechanism for objectify.
+        u"""Lookup mechanism for objectify.
 
         The default Element classes can be replaced by passing subclasses of
         ObjectifiedElement and ObjectifiedDataElement as keyword arguments.
@@ -1379,7 +1400,7 @@
         return lookup.tree_class
 
     # if element is defined as xsi:nil, return NoneElement class
-    if "true" == cetree.attributeValueFromNsName(
+    if u"true" == cetree.attributeValueFromNsName(
         c_node, _XML_SCHEMA_INSTANCE_NS, "nil"):
         return NoneElement
 
@@ -1400,8 +1421,8 @@
 
     if value is not None:
         dict_result = python.PyDict_GetItem(_SCHEMA_TYPE_DICT, value)
-        if dict_result is NULL and ':' in value:
-            prefix, value = value.split(':', 1)
+        if dict_result is NULL and u':' in value:
+            prefix, value = value.split(u':', 1)
             dict_result = python.PyDict_GetItem(_SCHEMA_TYPE_DICT, value)
         if dict_result is not NULL:
             return (<PyType>dict_result)._type
@@ -1435,7 +1456,7 @@
 
 def pyannotate(element_or_tree, *, ignore_old=False, ignore_xsi=False,
              empty_pytype=None):
-    """pyannotate(element_or_tree, ignore_old=False, ignore_xsi=False, empty_pytype=None)
+    u"""pyannotate(element_or_tree, ignore_old=False, ignore_xsi=False, empty_pytype=None)
 
     Recursively annotates the elements of an XML tree with 'pytype'
     attributes.
@@ -1458,7 +1479,7 @@
 
 def xsiannotate(element_or_tree, *, ignore_old=False, ignore_pytype=False,
                 empty_type=None):
-    """xsiannotate(element_or_tree, ignore_old=False, ignore_pytype=False, empty_type=None)
+    u"""xsiannotate(element_or_tree, ignore_old=False, ignore_pytype=False, empty_type=None)
 
     Recursively annotates the elements of an XML tree with 'xsi:type'
     attributes.
@@ -1487,7 +1508,7 @@
 def annotate(element_or_tree, *, ignore_old=True, ignore_xsi=False,
              empty_pytype=None, empty_type=None, annotate_xsi=0,
              annotate_pytype=1):
-    """annotate(element_or_tree, ignore_old=True, ignore_xsi=False, empty_pytype=None, empty_type=None, annotate_xsi=0, annotate_pytype=1)
+    u"""annotate(element_or_tree, ignore_old=True, ignore_xsi=False, empty_pytype=None, empty_type=None, annotate_xsi=0, annotate_pytype=1)
 
     Recursively annotates the elements of an XML tree with 'xsi:type'
     and/or 'py:pytype' attributes.
@@ -1538,8 +1559,14 @@
     doc = element._doc
 
     if empty_type_name is not None:
+        if python.PyString_Check(empty_type_name):
+            empty_type_name = python.PyUnicode_FromEncodedObject(
+                empty_type_name, "ASCII", NULL)
         dict_result = python.PyDict_GetItem(_SCHEMA_TYPE_DICT, empty_type_name)
     elif empty_pytype_name is not None:
+        if python.PyString_Check(empty_pytype_name):
+            empty_pytype_name = python.PyUnicode_FromEncodedObject(
+                empty_pytype_name, "ASCII", NULL)
         dict_result = python.PyDict_GetItem(_PYTYPE_DICT, empty_pytype_name)
     else:
         dict_result = NULL
@@ -1548,8 +1575,8 @@
     else:
         empty_pytype = None
 
-    StrType  = _PYTYPE_DICT.get('str')
-    NoneType = _PYTYPE_DICT.get('NoneType')
+    StrType  = _PYTYPE_DICT.get(u'str')
+    NoneType = _PYTYPE_DICT.get(u'NoneType')
     c_node = element._c_node
     tree.BEGIN_FOR_EACH_ELEMENT_FROM(c_node, c_node, 1)
     if c_node.type == tree.XML_ELEMENT_NODE:
@@ -1559,7 +1586,7 @@
         istree = 0
         # if element is defined as xsi:nil, represent it as None
         if cetree.attributeValueFromNsName(
-            c_node, _XML_SCHEMA_INSTANCE_NS, "nil") == "true":
+            c_node, _XML_SCHEMA_INSTANCE_NS, "nil") == u"true":
             pytype = NoneType
 
         if  pytype is None and not ignore_xsi:
@@ -1569,8 +1596,8 @@
             if typename is not None:
                 dict_result = python.PyDict_GetItem(
                     _SCHEMA_TYPE_DICT, typename)
-                if dict_result is NULL and ':' in typename:
-                    prefix, typename = typename.split(':', 1)
+                if dict_result is NULL and u':' in typename:
+                    prefix, typename = typename.split(u':', 1)
                     dict_result = python.PyDict_GetItem(
                         _SCHEMA_TYPE_DICT, typename)
                 if dict_result is not NULL:
@@ -1594,9 +1621,9 @@
                         # everything else is clear enough
                         pytype = TREE_PYTYPE
                 else:
-                    if old_pytypename == 'none':
+                    if old_pytypename == u'none':
                         # transition from lxml 1.x
-                        old_pytypename = "NoneType"
+                        old_pytypename = u"NoneType"
                     dict_result = python.PyDict_GetItem(
                         _PYTYPE_DICT, old_pytypename)
                     if dict_result is not NULL:
@@ -1640,22 +1667,23 @@
                     c_node, _XML_SCHEMA_INSTANCE_NS, "type")
             else:
                 # update or create attribute
+                typename_utf8 = cetree.utf8(typename)
                 c_ns = cetree.findOrBuildNodeNsPrefix(
                     doc, c_node, _XML_SCHEMA_NS, 'xsd')
                 if c_ns is not NULL:
-                    if ':' in typename:
-                        prefix, name = typename.split(':', 1)
+                    if ':' in typename_utf8:
+                        prefix, name = typename_utf8.split(':', 1)
                         if c_ns.prefix is NULL or c_ns.prefix[0] == c'\0':
-                            typename = name
+                            typename_utf8 = name
                         elif cstd.strcmp(_cstr(prefix), c_ns.prefix) != 0:
                             prefix = c_ns.prefix
-                            typename = prefix + ':' + name
+                            typename_utf8 = prefix + ':' + name
                     elif c_ns.prefix is not NULL or c_ns.prefix[0] != c'\0':
                         prefix = c_ns.prefix
-                        typename = prefix + ':' + typename
+                        typename_utf8 = prefix + ':' + typename_utf8
                 c_ns = cetree.findOrBuildNodeNsPrefix(
                     doc, c_node, _XML_SCHEMA_INSTANCE_NS, 'xsi')
-                tree.xmlSetNsProp(c_node, c_ns, "type", _cstr(typename))
+                tree.xmlSetNsProp(c_node, c_ns, "type", _cstr(typename_utf8))
 
         if annotate_pytype:
             if pytype is None:
@@ -1666,8 +1694,9 @@
                 # update or create attribute
                 c_ns = cetree.findOrBuildNodeNsPrefix(
                     doc, c_node, _PYTYPE_NAMESPACE, 'py')
+                pytype_name = cetree.utf8(pytype.name)
                 tree.xmlSetNsProp(c_node, c_ns, _PYTYPE_ATTRIBUTE_NAME,
-                                  _cstr(pytype.name))
+                                  _cstr(pytype_name))
                 if pytype is NoneType:
                     c_ns = cetree.findOrBuildNodeNsPrefix(
                         doc, c_node, _XML_SCHEMA_INSTANCE_NS, 'xsi')
@@ -1675,7 +1704,7 @@
     tree.END_FOR_EACH_ELEMENT_FROM(c_node)
 
 def deannotate(element_or_tree, *, pytype=True, xsi=True):
-    """deannotate(element_or_tree, pytype=True, xsi=True)
+    u"""deannotate(element_or_tree, pytype=True, xsi=True)
 
     Recursively de-annotate the elements of an XML tree by removing 'pytype'
     and/or 'type' attributes.
@@ -1722,7 +1751,7 @@
 objectify_parser = __DEFAULT_PARSER
 
 def set_default_parser(new_parser = None):
-    """set_default_parser(new_parser = None)
+    u"""set_default_parser(new_parser = None)
 
     Replace the default parser used by objectify's Element() and
     fromstring() functions.
@@ -1737,10 +1766,10 @@
     elif isinstance(new_parser, etree.XMLParser):
         objectify_parser = new_parser
     else:
-        raise TypeError, "parser must inherit from lxml.etree.XMLParser"
+        raise TypeError, u"parser must inherit from lxml.etree.XMLParser"
 
 def makeparser(**kw):
-    """makeparser(remove_blank_text=True, **kw)
+    u"""makeparser(remove_blank_text=True, **kw)
 
     Create a new XML parser for objectify trees.
 
@@ -1749,8 +1778,12 @@
     blank text.  You can disable this by passing the
     ``remove_blank_text`` boolean keyword option yourself.
     """
-    if 'remove_blank_text' not in kw:
-        kw['remove_blank_text'] = True
+    if python.IS_PYTHON3:
+        remove_blank_text = u'remove_blank_text'
+    else:
+        remove_blank_text = 'remove_blank_text'
+    if remove_blank_text not in kw:
+        kw[remove_blank_text] = True
     parser = etree.XMLParser(**kw)
     parser.set_element_class_lookup( ObjectifyElementClassLookup() )
     return parser
@@ -1765,7 +1798,7 @@
 _fromstring = etree.fromstring
 
 def fromstring(xml, parser=None):
-    """fromstring(xml, parser=None)
+    u"""fromstring(xml, parser=None)
 
     Objectify specific version of the lxml.etree fromstring() function
     that uses the objectify parser.
@@ -1777,7 +1810,7 @@
     return _fromstring(xml, parser)
 
 def XML(xml, parser=None):
-    """XML(xml, parser=None)
+    u"""XML(xml, parser=None)
 
     Objectify specific version of the lxml.etree XML() literal factory
     that uses the objectify parser.
@@ -1792,7 +1825,7 @@
 _parse = etree.parse
 
 def parse(f, parser=None):
-    """parse(f, parser=None)
+    u"""parse(f, parser=None)
 
     Parse a file or file-like object with the objectify parser.
 
@@ -1803,14 +1836,14 @@
     return _parse(f, parser)
 
 cdef object _DEFAULT_NSMAP
-_DEFAULT_NSMAP = { "py"  : PYTYPE_NAMESPACE,
-                   "xsi" : XML_SCHEMA_INSTANCE_NS,
-                   "xsd" : XML_SCHEMA_NS}
+_DEFAULT_NSMAP = { u"py"  : PYTYPE_NAMESPACE,
+                   u"xsi" : XML_SCHEMA_INSTANCE_NS,
+                   u"xsd" : XML_SCHEMA_NS}
 
 E = ElementMaker()
 
 def Element(_tag, attrib=None, nsmap=None, *, _pytype=None, **_attributes):
-    """Element(_tag, attrib=None, nsmap=None, _pytype=None, **_attributes)
+    u"""Element(_tag, attrib=None, nsmap=None, _pytype=None, **_attributes)
 
     Objectify specific version of the lxml.etree Element() factory that
     always creates a structural (tree) element.
@@ -1830,7 +1863,7 @@
 
 def DataElement(_value, attrib=None, nsmap=None, *, _pytype=None, _xsi=None,
                 **_attributes):
-    """DataElement(_value, attrib=None, nsmap=None, _pytype=None, _xsi=None, **_attributes)
+    u"""DataElement(_value, attrib=None, nsmap=None, _pytype=None, _xsi=None, **_attributes)
 
     Create a new element from a Python value and XML attributes taken from
     keyword arguments or a dictionary passed as second argument.
@@ -1881,23 +1914,23 @@
                 _pytype = <object>dict_result
 
     if _xsi is not None:
-        if ':' in _xsi:
-            prefix, name = _xsi.split(':', 1)
+        if u':' in _xsi:
+            prefix, name = _xsi.split(u':', 1)
             ns = nsmap.get(prefix)
             if ns != XML_SCHEMA_NS:
-                raise ValueError, "XSD types require the XSD namespace"
+                raise ValueError, u"XSD types require the XSD namespace"
         elif nsmap is _DEFAULT_NSMAP:
             name = _xsi
-            _xsi = 'xsd:' + _xsi
+            _xsi = u'xsd:' + _xsi
         else:
             name = _xsi
             for prefix, ns in nsmap.items():
                 if ns == XML_SCHEMA_NS:
                     if prefix is not None and prefix:
-                        _xsi = prefix + ':' + _xsi
+                        _xsi = prefix + u':' + _xsi
                     break
             else:
-                raise ValueError, "XSD types require the XSD namespace"
+                raise ValueError, u"XSD types require the XSD namespace"
         python.PyDict_SetItem(_attributes, XML_SCHEMA_INSTANCE_TYPE_ATTR, _xsi)
         if _pytype is None:
             # allow using unregistered or even wrong xsi:type names
@@ -1907,26 +1940,26 @@
             if dict_result is not NULL:
                 _pytype = (<PyType>dict_result).name
 
-    if _value is None and _pytype != "str":
-        _pytype = _pytype or "NoneType"
+    if _value is None and _pytype != u"str":
+        _pytype = _pytype or u"NoneType"
         strval = None
     elif python._isString(_value):
         strval = _value
     elif python.PyBool_Check(_value):
         if _value:
-            strval = "true"
+            strval = u"true"
         else:
-            strval = "false"
+            strval = u"false"
     else:
-        strval = str(_value)
+        strval = unicode(_value)
 
     if _pytype is None:
         _pytype = _pytypename(_value)
     
     if _pytype is not None: 
-        if _pytype == "NoneType" or _pytype == "none":
+        if _pytype == u"NoneType" or _pytype == u"none":
             strval = None
-            python.PyDict_SetItem(_attributes, XML_SCHEMA_INSTANCE_NIL_ATTR, "true")
+            python.PyDict_SetItem(_attributes, XML_SCHEMA_INSTANCE_NIL_ATTR, u"true")
         else:
             # check if type information from arguments is valid
             dict_result = python.PyDict_GetItem(_PYTYPE_DICT, _pytype)
@@ -1937,7 +1970,7 @@
 
                 python.PyDict_SetItem(_attributes, PYTYPE_ATTRIBUTE, _pytype)
 
-    return _makeElement("value", strval, _attributes, nsmap)
+    return _makeElement(u"value", strval, _attributes, nsmap)
 
 
 ################################################################################

Modified: lxml/trunk/src/lxml/nsclasses.pxi
==============================================================================
--- lxml/trunk/src/lxml/nsclasses.pxi	(original)
+++ lxml/trunk/src/lxml/nsclasses.pxi	Wed May 21 21:45:48 2008
@@ -36,10 +36,10 @@
         registry, or if their name starts with '_', they will be
         silently discarded. This allows registrations at the module or
         class level using vars(), globals() etc."""
-        if hasattr(class_dict_iterable, 'items'):
+        if hasattr(class_dict_iterable, u'items'):
             class_dict_iterable = class_dict_iterable.items()
         for name, item in class_dict_iterable:
-            if (name is None or name[:1] != '_') and callable(item):
+            if (name is None or name[:1] != u'_') and callable(item):
                 self[name] = item
 
     def __getitem__(self, name):
@@ -61,7 +61,7 @@
 
     cdef object _getForString(self, char* name):
         cdef python.PyObject* dict_result
-        dict_result = python.PyDict_GetItemString(self._entries, name)
+        dict_result = python.PyDict_GetItem(self._entries, name)
         if dict_result is NULL:
             raise KeyError, u"Name not registered."
         return <object>dict_result
@@ -70,7 +70,7 @@
         return iter(self._entries)
 
     def items(self):
-        return self._entries.items()
+        return list(self._entries.items())
 
     def iteritems(self):
         return iter(self._entries.items())
@@ -135,7 +135,7 @@
 
     c_namespace_utf = _getNs(c_node)
     if c_namespace_utf is not NULL:
-        dict_result = python.PyDict_GetItemString(
+        dict_result = python.PyDict_GetItem(
             lookup._namespace_registries, c_namespace_utf)
     else:
         dict_result = python.PyDict_GetItem(
@@ -145,7 +145,7 @@
         classes = registry._entries
 
         if c_node.name is not NULL:
-            dict_result = python.PyDict_GetItemString(
+            dict_result = python.PyDict_GetItem(
                 classes, c_node.name)
         else:
             dict_result = NULL

Modified: lxml/trunk/src/lxml/objectpath.pxi
==============================================================================
--- lxml/trunk/src/lxml/objectpath.pxi	(original)
+++ lxml/trunk/src/lxml/objectpath.pxi	Wed May 21 21:45:48 2008
@@ -8,7 +8,7 @@
 
 
 cdef class ObjectPath:
-    """ObjectPath(path)
+    u"""ObjectPath(path)
     Immutable object that represents a compiled object path.
 
     Example for a path: 'root.child[1].{other}child[25]'
@@ -24,7 +24,7 @@
             self._path_str = path
         else:
             self._path = _parseObjectPathList(path)
-            self._path_str = '.'.join(path)
+            self._path_str = u'.'.join(path)
         self._path_len = python.PyList_GET_SIZE(self._path)
         self._c_path = _buildObjectPathSegments(self._path)
         self.find = self.__call__
@@ -37,7 +37,7 @@
         return self._path_str
 
     def __call__(self, _Element root not None, *default):
-        """Follow the attribute path in the object structure and return the
+        u"""Follow the attribute path in the object structure and return the
         target attribute value.
 
         If it it not found, either returns a default value (if one was passed
@@ -50,12 +50,12 @@
             python.Py_INCREF(default)
             use_default = 1
         elif use_default > 1:
-            raise TypeError, "invalid number of arguments: needs one or two"
+            raise TypeError, u"invalid number of arguments: needs one or two"
         return _findObjectPath(root, self._c_path, self._path_len,
                                default, use_default)
 
     def hasattr(self, _Element root not None):
-        "hasattr(self, root)"
+        u"hasattr(self, root)"
         try:
             _findObjectPath(root, self._c_path, self._path_len, None, 0)
         except AttributeError:
@@ -63,7 +63,7 @@
         return True
 
     def setattr(self, _Element root not None, value):
-        """setattr(self, root, value)
+        u"""setattr(self, root, value)
 
         Set the value of the target element in a subtree.
 
@@ -72,7 +72,7 @@
         _createObjectPath(root, self._c_path, self._path_len, 1, value)
 
     def addattr(self, _Element root not None, value):
-        """addattr(self, root, value)
+        u"""addattr(self, root, value)
 
         Append a value to the target element in a subtree.
 
@@ -82,50 +82,55 @@
 
 cdef object __MATCH_PATH_SEGMENT
 __MATCH_PATH_SEGMENT = re.compile(
-    r"(\.?)\s*(?:\{([^}]*)\})?\s*([^.{}\[\]\s]+)\s*(?:\[\s*([-0-9]+)\s*\])?",
+    ur"(\.?)\s*(?:\{([^}]*)\})?\s*([^.{}\[\]\s]+)\s*(?:\[\s*([-0-9]+)\s*\])?",
     re.U).match
 
 cdef object _RELATIVE_PATH_SEGMENT
 _RELATIVE_PATH_SEGMENT = (None, None, 0)
 
 cdef _parseObjectPathString(path):
-    """Parse object path string into a (ns, name, index) list.
+    u"""Parse object path string into a (ns, name, index) list.
     """
     cdef bint has_dot
     new_path = []
-    path = cetree.utf8(path.strip())
-    if path == '.':
+    path = path.strip()
+    if python.PyString_Check(path):
+        path = python.PyUnicode_FromEncodedObject(path, 'ASCII', NULL)
+    if path == u'.':
         return [_RELATIVE_PATH_SEGMENT]
     path_pos = 0
-    while python.PyString_GET_SIZE(path) > 0:
+    while python.PyUnicode_GET_SIZE(path) > 0:
         match = __MATCH_PATH_SEGMENT(path, path_pos)
         if match is None:
             break
 
         dot, ns, name, index = match.groups()
-        if index is None or python.PyString_GET_SIZE(index) == 0:
+        if index is None or python.PyUnicode_GET_SIZE(index) == 0:
             index = 0
         else:
             index = python.PyNumber_Int(index)
-        has_dot = _cstr(dot)[0] == c'.'
+        has_dot = dot == u'.'
         if python.PyList_GET_SIZE(new_path) == 0:
             if has_dot:
                 # path '.child' => ignore root
                 python.PyList_Append(new_path, _RELATIVE_PATH_SEGMENT)
             elif index != 0:
-                raise ValueError, "index not allowed on root node"
+                raise ValueError, u"index not allowed on root node"
         elif not has_dot:
-            raise ValueError, "invalid path"
+            raise ValueError, u"invalid path"
+        if ns is not None:
+            ns = python.PyUnicode_AsUTF8String(ns)
+        name = python.PyUnicode_AsUTF8String(name)
         python.PyList_Append(new_path, (ns, name, index))
-        
+
         path_pos = match.end()
     if python.PyList_GET_SIZE(new_path) == 0 or \
-           python.PyString_GET_SIZE(path) > path_pos:
-        raise ValueError, "invalid path"
+           python.PyUnicode_GET_SIZE(path) > path_pos:
+        raise ValueError, u"invalid path"
     return new_path
 
 cdef _parseObjectPathList(path):
-    """Parse object path sequence into a (ns, name, index) list.
+    u"""Parse object path sequence into a (ns, name, index) list.
     """
     cdef char* index_pos
     cdef char* index_end
@@ -133,7 +138,7 @@
     new_path = []
     for item in path:
         item = item.strip()
-        if python.PyList_GET_SIZE(new_path) == 0 and item == '':
+        if python.PyList_GET_SIZE(new_path) == 0 and item == u'':
             # path '.child' => ignore root
             ns = name = None
             index = 0
@@ -146,17 +151,17 @@
             else:
                 index_end = cstd.strchr(index_pos + 1, c']')
                 if index_end is NULL:
-                    raise ValueError, "index must be enclosed in []"
+                    raise ValueError, u"index must be enclosed in []"
                 index = python.PyNumber_Int(
                     python.PyString_FromStringAndSize(
                         index_pos + 1, <Py_ssize_t>(index_end - index_pos - 1)))
                 if python.PyList_GET_SIZE(new_path) == 0 and index != 0:
-                    raise ValueError, "index not allowed on root node"
+                    raise ValueError, u"index not allowed on root node"
                 name = python.PyString_FromStringAndSize(
                     c_name, <Py_ssize_t>(index_pos - c_name))
         python.PyList_Append(new_path, (ns, name, index))
     if python.PyList_GET_SIZE(new_path) == 0:
-        raise ValueError, "invalid path"
+        raise ValueError, u"invalid path"
     return new_path
 
 cdef _ObjectPath* _buildObjectPathSegments(path_list) except NULL:
@@ -182,7 +187,7 @@
 
 cdef _findObjectPath(_Element root, _ObjectPath* c_path, Py_ssize_t c_path_len,
                      default_value, int use_default):
-    """Follow the path to find the target element.
+    u"""Follow the path to find the target element.
     """
     cdef tree.xmlNode* c_node
     cdef char* c_href
@@ -195,7 +200,7 @@
         c_href = tree._getNs(c_node)
     if not cetree.tagMatches(c_node, c_href, c_name):
         raise ValueError, \
-            "root element does not match: need %s, got %s" % \
+            u"root element does not match: need %s, got %s" % \
             (cetree.namespacedNameFromNsName(c_href, c_name), root.tag)
 
     while c_node is not NULL:
@@ -225,11 +230,11 @@
         return default_value
     else:
         tag = cetree.namespacedNameFromNsName(c_href, c_name)
-        raise AttributeError, "no such child: " + tag
+        raise AttributeError, u"no such child: " + tag
 
 cdef _createObjectPath(_Element root, _ObjectPath* c_path,
                        Py_ssize_t c_path_len, int replace, value):
-    """Follow the path to find the target element, build the missing children
+    u"""Follow the path to find the target element, build the missing children
     as needed and set the target element to 'value'.  If replace is true, an
     existing value is replaced, otherwise the new value is added.
     """
@@ -240,7 +245,7 @@
     cdef char* c_name
     cdef Py_ssize_t c_index
     if c_path_len == 1:
-        raise TypeError, "cannot update root node"
+        raise TypeError, u"cannot update root node"
 
     c_node = root._c_node
     c_name = c_path[0].name
@@ -249,7 +254,7 @@
         c_href = tree._getNs(c_node)
     if not cetree.tagMatches(c_node, c_href, c_name):
         raise ValueError, \
-            "root element does not match: need %s, got %s" % \
+            u"root element does not match: need %s, got %s" % \
             (cetree.namespacedNameFromNsName(c_href, c_name), root.tag)
 
     while c_path_len > 1:
@@ -273,7 +278,7 @@
             c_node = c_child
         elif c_index != 0:
             raise TypeError, \
-                "creating indexed path attributes is not supported"
+                u"creating indexed path attributes is not supported"
         elif c_path_len == 1:
             _appendValue(cetree.elementFactory(root._doc, c_node),
                          cetree.namespacedNameFromNsName(c_href, c_name),
@@ -295,12 +300,12 @@
                      cetree.namespacedName(c_node), value)
 
 cdef _buildDescendantPaths(tree.xmlNode* c_node, prefix_string):
-    """Returns a list of all descendant paths.
+    u"""Returns a list of all descendant paths.
     """
     tag = cetree.namespacedName(c_node)
     if prefix_string:
-        if prefix_string[-1] != '.':
-            prefix_string = prefix_string + '.'
+        if prefix_string[-1] != u'.':
+            prefix_string = prefix_string + u'.'
         prefix_string = prefix_string + tag
     else:
         prefix_string = tag
@@ -310,13 +315,13 @@
     return path_list
 
 cdef _recursiveBuildDescendantPaths(tree.xmlNode* c_node, path, path_list):
-    """Fills the list 'path_list' with all descendant paths, initial prefix
+    u"""Fills the list 'path_list' with all descendant paths, initial prefix
     being in the list 'path'.
     """
     cdef python.PyObject* dict_result
     cdef tree.xmlNode* c_child
     cdef char* c_href
-    python.PyList_Append(path_list, '.'.join(path))
+    python.PyList_Append(path_list, u'.'.join(path))
     tags = {}
     c_href = tree._getNs(c_node)
     c_child = c_node.children
@@ -326,10 +331,10 @@
             if c_child is NULL:
                 return
         if c_href is tree._getNs(c_child):
-            tag = c_child.name
+            tag = pyunicode(c_child.name)
         elif c_href is not NULL and tree._getNs(c_child) is NULL:
             # special case: parent has namespace, child does not
-            tag = '{}' + c_child.name
+            tag = u'{}' + pyunicode(c_child.name)
         else:
             tag = cetree.namespacedName(c_child)
         dict_result = python.PyDict_GetItem(tags, tag)
@@ -339,7 +344,7 @@
             count = (<object>dict_result) + 1
         python.PyDict_SetItem(tags, tag, count)
         if count > 0:
-            tag = tag + '[%d]' % count
+            tag += u'[%d]' % count
         python.PyList_Append(path, tag)
         _recursiveBuildDescendantPaths(c_child, path, path_list)
         del path[-1]

Modified: lxml/trunk/src/lxml/python.pxd
==============================================================================
--- lxml/trunk/src/lxml/python.pxd	(original)
+++ lxml/trunk/src/lxml/python.pxd	Wed May 21 21:45:48 2008
@@ -37,6 +37,7 @@
     cdef object PyUnicode_AsUTF8String(object ustring)
     cdef char* PyUnicode_AS_DATA(object ustring)
     cdef Py_ssize_t PyUnicode_GET_DATA_SIZE(object ustring)
+    cdef Py_ssize_t PyUnicode_GET_SIZE(object ustring)
     cdef object PyString_FromStringAndSize(char* s, Py_ssize_t size)
     cdef object PyString_FromString(char* s)
     cdef object PyString_FromFormat(char* format, ...)

Modified: lxml/trunk/src/lxml/tests/test_objectify.py
==============================================================================
--- lxml/trunk/src/lxml/tests/test_objectify.py	(original)
+++ lxml/trunk/src/lxml/tests/test_objectify.py	Wed May 21 21:45:48 2008
@@ -5,10 +5,15 @@
 """
 
 
-import unittest, operator, sys
+import unittest, operator, sys, os.path
 
-from common_imports import etree, StringIO, HelperTestCase, fileInTestDir
+this_dir = os.path.dirname(__file__)
+if this_dir not in sys.path:
+    sys.path.insert(0, this_dir) # needed for Py3
+
+from common_imports import etree, HelperTestCase, fileInTestDir
 from common_imports import SillyFileLike, canonicalize, doctest
+from common_imports import _bytes, _str, StringIO, BytesIO
 
 from lxml import objectify
 
@@ -25,10 +30,9 @@
 objectclass2xsitype = {
     # objectify built-in
     objectify.IntElement: ("int", "short", "byte", "unsignedShort",
-                           "unsignedByte",),
-    objectify.LongElement: ("integer", "nonPositiveInteger", "negativeInteger",
-                            "long", "nonNegativeInteger", "unsignedLong",
-                            "unsignedInt", "positiveInteger",),
+                           "unsignedByte", "integer", "nonPositiveInteger",
+                           "negativeInteger", "long", "nonNegativeInteger",
+                           "unsignedLong", "unsignedInt", "positiveInteger",),
     objectify.FloatElement: ("float", "double"),
     objectify.BoolElement: ("boolean",),
     objectify.StringElement: ("string", "normalizedString", "token", "language",
@@ -43,7 +47,6 @@
 objectclass2pytype = {
     # objectify built-in
     objectify.IntElement: "int",
-    objectify.LongElement: "long",
     objectify.FloatElement: "float",
     objectify.BoolElement: "bool",
     objectify.StringElement: "str",
@@ -108,7 +111,7 @@
     def test_element_nsmap_empty(self):
         nsmap = {}
         elt = objectify.Element("test", nsmap=nsmap)
-        self.assertEquals(elt.nsmap.values(), [PYTYPE_NAMESPACE])
+        self.assertEquals(list(elt.nsmap.values()), [PYTYPE_NAMESPACE])
 
     def test_element_nsmap_custom_prefixes(self):
         nsmap = {"mypy": PYTYPE_NAMESPACE,
@@ -164,7 +167,7 @@
     def test_data_element_nsmap_empty(self):
         nsmap = {}
         value = objectify.DataElement("test this", nsmap=nsmap)
-        self.assertEquals(value.nsmap.values(), [PYTYPE_NAMESPACE])
+        self.assertEquals(list(value.nsmap.values()), [PYTYPE_NAMESPACE])
 
     def test_data_element_nsmap_custom_prefixes(self):
         nsmap = {"mypy": PYTYPE_NAMESPACE,
@@ -831,11 +834,6 @@
         el = objectify.DataElement(v)
         self.assertEquals(int(el), 1)
             
-    def test_type_str_as_long(self):
-        v = "1"
-        el = objectify.DataElement(v)
-        self.assertEquals(long(el), 1)
-            
     def test_type_str_as_float(self):
         v = "1"
         el = objectify.DataElement(v)
@@ -874,59 +872,59 @@
         Element = self.Element
         SubElement = self.etree.SubElement
         root = Element("{objectified}root")
-        root.s = u"test"
+        root.s = _str("test")
         self.assert_(isinstance(root.s, objectify.StringElement))
 
     def test_type_ustr_intliteral(self):
         Element = self.Element
         SubElement = self.etree.SubElement
         root = Element("{objectified}root")
-        root.s = u"3"
+        root.s = _str("3")
         self.assert_(isinstance(root.s, objectify.StringElement))
 
     def test_type_ustr_floatliteral(self):
         Element = self.Element
         SubElement = self.etree.SubElement
         root = Element("{objectified}root")
-        root.s = u"3.72"
+        root.s = _str("3.72")
         self.assert_(isinstance(root.s, objectify.StringElement))
 
     def test_type_ustr_mul(self):
         Element = self.Element
         SubElement = self.etree.SubElement
         root = Element("{objectified}root")
-        root.s = u"test"
+        root.s = _str("test")
 
-        self.assertEquals(u"test" * 5, root.s * 5)
-        self.assertEquals(5 * u"test", 5 * root.s)
+        self.assertEquals(_str("test") * 5, root.s * 5)
+        self.assertEquals(5 * _str("test"), 5 * root.s)
 
-        self.assertRaises(TypeError, operator.mul, root.s, u"honk")
-        self.assertRaises(TypeError, operator.mul, u"honk", root.s)
+        self.assertRaises(TypeError, operator.mul, root.s, _str("honk"))
+        self.assertRaises(TypeError, operator.mul, _str("honk"), root.s)
 
     def test_type_ustr_add(self):
         Element = self.Element
         SubElement = self.etree.SubElement
         root = Element("{objectified}root")
-        root.s = u"test"
+        root.s = _str("test")
 
-        s = u"toast"
-        self.assertEquals(u"test" + s, root.s + s)
-        self.assertEquals(s + u"test", s + root.s)
+        s = _str("toast")
+        self.assertEquals(_str("test") + s, root.s + s)
+        self.assertEquals(s + _str("test"), s + root.s)
 
     def test_data_element_ustr(self):
-        value = objectify.DataElement(u"test")
+        value = objectify.DataElement(_str("test"))
         self.assert_(isinstance(value, objectify.StringElement))
-        self.assertEquals(value, u"test")
+        self.assertEquals(value, _str("test"))
 
     def test_data_element_ustr_intliteral(self):
         value = objectify.DataElement("3")
         self.assert_(isinstance(value, objectify.StringElement))
-        self.assertEquals(value, u"3")
+        self.assertEquals(value, _str("3"))
 
     def test_data_element_ustr_floatliteral(self):
-        value = objectify.DataElement(u"3.20")
+        value = objectify.DataElement(_str("3.20"))
         self.assert_(isinstance(value, objectify.StringElement))
-        self.assertEquals(value, u"3.20")
+        self.assertEquals(value, _str("3.20"))
 
     def test_type_int(self):
         Element = self.Element
@@ -953,7 +951,7 @@
         self.assertEquals(value, 5.5)
 
     def test_data_element_xsitypes(self):
-        for xsi, objclass in xsitype2objclass.iteritems():
+        for xsi, objclass in xsitype2objclass.items():
             # 1 is a valid value for all ObjectifiedDataElement classes
             pyval = 1
             value = objectify.DataElement(pyval, _xsi=xsi)
@@ -962,7 +960,7 @@
                          % (pyval, xsi, type(value), objclass))
         
     def test_data_element_xsitypes_xsdprefixed(self):
-        for xsi, objclass in xsitype2objclass.iteritems():
+        for xsi, objclass in xsitype2objclass.items():
             # 1 is a valid value for all ObjectifiedDataElement classes
             pyval = 1
             value = objectify.DataElement(pyval, _xsi="xsd:%s" % xsi)
@@ -971,13 +969,13 @@
                          % (pyval, xsi, type(value), objclass))
         
     def test_data_element_xsitypes_prefixed(self):
-        for xsi, objclass in xsitype2objclass.iteritems():
+        for xsi, objclass in xsitype2objclass.items():
             # 1 is a valid value for all ObjectifiedDataElement classes
             self.assertRaises(ValueError, objectify.DataElement, 1,
                               _xsi="foo:%s" % xsi)
 
     def test_data_element_pytypes(self):
-        for pytype, objclass in pytype2objclass.iteritems():
+        for pytype, objclass in pytype2objclass.items():
             # 1 is a valid value for all ObjectifiedDataElement classes
             pyval = 1
             value = objectify.DataElement(pyval, _pytype=pytype)
@@ -1083,13 +1081,13 @@
             self.assert_(isinstance(s, objectify.StringElement))
             self.assertEquals("5", s)
 
-        for l in root.l:
-            self.assert_(isinstance(l, objectify.LongElement))
-            self.assertEquals(5L, l)
-
         for i in root.i:
             self.assert_(isinstance(i, objectify.IntElement))
             self.assertEquals(5, i)
+
+        for l in root.l:
+            self.assert_(isinstance(l, objectify.IntElement))
+            self.assertEquals(5, i)
             
         self.assert_(isinstance(root.n, objectify.NoneElement))
         self.assertEquals(None, root.n)
@@ -1152,27 +1150,27 @@
             self.assert_(isinstance(s, objectify.StringElement))
             self.assertEquals("5", s)
 
-        for l in root.l:
-            self.assert_(isinstance(l, objectify.LongElement))
-            self.assertEquals(5L, l)
-
         for i in root.i:
             self.assert_(isinstance(i, objectify.IntElement))
             self.assertEquals(5, i)
+
+        for l in root.l:
+            self.assert_(isinstance(l, objectify.IntElement))
+            self.assertEquals(5, l)
             
         self.assert_(isinstance(root.n, objectify.NoneElement))
         self.assertEquals(None, root.n)
         
     def test_type_str_sequence(self):
         XML = self.XML
-        root = XML(u'<root><b>why</b><b>try</b></root>')
+        root = XML(_bytes('<root><b>why</b><b>try</b></root>'))
         strs = [ str(s) for s in root.b ]
         self.assertEquals(["why", "try"],
                           strs)
 
     def test_type_str_cmp(self):
         XML = self.XML
-        root = XML(u'<root><b>test</b><b>taste</b><b></b><b/></root>')
+        root = XML(_bytes('<root><b>test</b><b>taste</b><b></b><b/></root>'))
         self.assertFalse(root.b[0] <  root.b[1])
         self.assertFalse(root.b[0] <= root.b[1])
         self.assertFalse(root.b[0] == root.b[1])
@@ -1183,8 +1181,6 @@
 
         self.assertEquals(root.b[0], "test")
         self.assertEquals("test", root.b[0])
-        self.assert_(root.b[0] >  5)
-        self.assert_(5 < root.b[0])
 
         self.assertEquals("", root.b[2])
         self.assertEquals(root.b[2], "")
@@ -1201,7 +1197,7 @@
 
     def test_type_int_cmp(self):
         XML = self.XML
-        root = XML(u'<root><b>5</b><b>6</b></root>')
+        root = XML(_bytes('<root><b>5</b><b>6</b></root>'))
         self.assert_(root.b[0] <  root.b[1])
         self.assert_(root.b[0] <= root.b[1])
         self.assert_(root.b[0] != root.b[1])
@@ -1212,8 +1208,7 @@
 
         self.assertEquals(root.b[0], 5)
         self.assertEquals(5, root.b[0])
-        self.assert_(root.b[0] <  "5")
-        self.assert_("5" > root.b[0])
+        self.assertNotEquals(root.b[0], "5")
 
         root.b = 5
         self.assert_(root.b)
@@ -1224,7 +1219,7 @@
 
     def test_type_bool_cmp(self):
         XML = self.XML
-        root = XML(u'<root><b>false</b><b>true</b></root>')
+        root = XML(_bytes('<root><b>false</b><b>true</b></root>'))
         self.assert_(root.b[0] <  root.b[1])
         self.assert_(root.b[0] <= root.b[1])
         self.assert_(root.b[0] != root.b[1])
@@ -1248,21 +1243,23 @@
 
     def test_type_none_cmp(self):
         XML = self.XML
-        root = XML(u"""
+        root = XML(_bytes("""
         <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
           <b xsi:nil="true"></b><b xsi:nil="true"/>
-        </root>""")
+        </root>"""))
         self.assert_(root.b[0] == root.b[1])
         self.assertFalse(root.b[0])
         self.assertEquals(root.b[0], None)
         self.assertEquals(None, root.b[0])
 
-        for comparison in ["abc", 5, 7.3, True, [], ()]:
-            none = root.b[1]
-            self.assert_(none < comparison, "%s (%s) should be < %s" %
-                         (none, type(none), comparison) )
-            self.assert_(comparison > none, "%s should be > %s (%s)" %
-                         (comparison, none, type(none)) )
+        # doesn't work in Py3:
+
+        #for comparison in ["abc", 5, 7.3, True, [], ()]:
+        #    none = root.b[1]
+        #    self.assert_(none < comparison, "%s (%s) should be < %s" %
+        #                 (none, type(none), comparison) )
+        #    self.assert_(comparison > none, "%s should be > %s (%s)" %
+        #                 (comparison, none, type(none)) )
 
     def test_dataelement_xsi(self):
         el = objectify.DataElement(1, _xsi="string")
@@ -1283,7 +1280,7 @@
 
     def test_pytype_annotation(self):
         XML = self.XML
-        root = XML(u'''\
+        root = XML(_bytes('''\
         <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:py="http://codespeak.net/lxml/objectify/pytype">
           <b>5</b>
@@ -1301,7 +1298,7 @@
           <l py:pytype="long">2</l>
           <t py:pytype="TREE"></t>
         </a>
-        ''')
+        '''))
         objectify.annotate(root)
 
         child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
@@ -1325,12 +1322,12 @@
 
     def test_pytype_annotation_empty(self):
         XML = self.XML
-        root = XML(u'''\
+        root = XML(_bytes('''\
         <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:py="http://codespeak.net/lxml/objectify/pytype">
           <n></n>
         </a>
-        ''')
+        '''))
         objectify.annotate(root)
 
         child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
@@ -1345,7 +1342,7 @@
 
     def test_pytype_annotation_use_old(self):
         XML = self.XML
-        root = XML(u'''\
+        root = XML(_bytes('''\
         <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:py="http://codespeak.net/lxml/objectify/pytype">
           <b>5</b>
@@ -1363,7 +1360,7 @@
           <l py:pytype="long">2</l>
           <t py:pytype="TREE"></t>
         </a>
-        ''')
+        '''))
         objectify.annotate(root, ignore_old=False)
 
         child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
@@ -1380,14 +1377,14 @@
         self.assertEquals("str",   child_types[ 9])
         self.assertEquals("str",   child_types[10])
         self.assertEquals("float", child_types[11])
-        self.assertEquals("long",  child_types[12])
+        self.assertEquals("int",   child_types[12])
         self.assertEquals(TREE_PYTYPE,  child_types[13])
         
         self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
 
     def test_pytype_xsitype_annotation(self):
         XML = self.XML
-        root = XML(u'''\
+        root = XML(_bytes('''\
         <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:py="http://codespeak.net/lxml/objectify/pytype">
           <b>5</b>
@@ -1405,7 +1402,7 @@
           <l py:pytype="long">2</l>
           <t py:pytype="TREE"></t>
         </a>
-        ''')
+        '''))
         objectify.annotate(root, ignore_old=False, ignore_xsi=False,
                            annotate_xsi=1, annotate_pytype=1)
         
@@ -1424,7 +1421,7 @@
         self.assertEquals("str",   child_types[ 9])
         self.assertEquals("str",   child_types[10])
         self.assertEquals("float",   child_types[11])
-        self.assertEquals("long",   child_types[12])
+        self.assertEquals("int",     child_types[12])
         self.assertEquals(TREE_PYTYPE,  child_types[13])
         
         self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
@@ -1435,7 +1432,7 @@
         # check xsi annotations
         child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
                         for c in root.iterchildren() ]
-        self.assertEquals("xsd:int",     child_types[ 0])
+        self.assertEquals("xsd:integer", child_types[ 0])
         self.assertEquals("xsd:string",  child_types[ 1])
         self.assertEquals("xsd:double",  child_types[ 2])
         self.assertEquals("xsd:string",  child_types[ 3])
@@ -1454,7 +1451,7 @@
 
     def test_xsiannotate_use_old(self):
         XML = self.XML
-        root = XML(u'''\
+        root = XML(_bytes('''\
         <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:py="http://codespeak.net/lxml/objectify/pytype">
           <b>5</b>
@@ -1472,12 +1469,12 @@
           <l py:pytype="long">2</l>
           <t py:pytype="TREE"></t>
         </a>
-        ''')
+        '''))
         objectify.xsiannotate(root, ignore_old=False)
 
         child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
                         for c in root.iterchildren() ]
-        self.assertEquals("xsd:int",     child_types[ 0])
+        self.assertEquals("xsd:integer", child_types[ 0])
         self.assertEquals("xsd:string",  child_types[ 1])
         self.assertEquals("xsd:double",  child_types[ 2])
         self.assertEquals("xsd:string",  child_types[ 3])
@@ -1494,7 +1491,7 @@
 
     def test_pyannotate_ignore_old(self):
         XML = self.XML
-        root = XML(u'''\
+        root = XML(_bytes('''\
         <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:py="http://codespeak.net/lxml/objectify/pytype">
           <b>5</b>
@@ -1512,7 +1509,7 @@
           <l py:pytype="long">2</l>
           <t py:pytype="TREE"></t>
         </a>
-        ''')
+        '''))
         objectify.pyannotate(root, ignore_old=True)
 
         child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
@@ -1536,7 +1533,7 @@
 
     def test_pyannotate_empty(self):
         XML = self.XML
-        root = XML(u'''\
+        root = XML('''\
         <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:py="http://codespeak.net/lxml/objectify/pytype">
           <n></n>
@@ -1556,7 +1553,7 @@
 
     def test_pyannotate_use_old(self):
         XML = self.XML
-        root = XML(u'''\
+        root = XML('''\
         <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:py="http://codespeak.net/lxml/objectify/pytype">
           <b>5</b>
@@ -1591,14 +1588,14 @@
         self.assertEquals("str",   child_types[ 9])
         self.assertEquals("str",   child_types[10])
         self.assertEquals("float", child_types[11])
-        self.assertEquals("long",  child_types[12])
+        self.assertEquals("int",   child_types[12])
         self.assertEquals(TREE_PYTYPE, child_types[13])
         
         self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
         
     def test_xsiannotate_ignore_old(self):
         XML = self.XML
-        root = XML(u'''\
+        root = XML(_bytes('''\
         <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:py="http://codespeak.net/lxml/objectify/pytype">
           <b>5</b>
@@ -1616,21 +1613,21 @@
           <l py:pytype="long">2</l>
           <t py:pytype="TREE"></t>
         </a>
-        ''')
+        '''))
         objectify.xsiannotate(root, ignore_old=True)
 
         child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
                         for c in root.iterchildren() ]
-        self.assertEquals("xsd:int",     child_types[ 0])
+        self.assertEquals("xsd:integer", child_types[ 0])
         self.assertEquals("xsd:string",  child_types[ 1])
         self.assertEquals("xsd:double",  child_types[ 2])
         self.assertEquals("xsd:string",  child_types[ 3])
         self.assertEquals("xsd:boolean", child_types[ 4])
         self.assertEquals(None,          child_types[ 5])
         self.assertEquals(None,          child_types[ 6])
-        self.assertEquals("xsd:int",     child_types[ 7])
-        self.assertEquals("xsd:int",     child_types[ 8])
-        self.assertEquals("xsd:int",     child_types[ 9])
+        self.assertEquals("xsd:integer", child_types[ 7])
+        self.assertEquals("xsd:integer", child_types[ 8])
+        self.assertEquals("xsd:integer", child_types[ 9])
         self.assertEquals("xsd:string",  child_types[10])
         self.assertEquals("xsd:double",  child_types[11])
         self.assertEquals("xsd:integer", child_types[12])
@@ -1640,7 +1637,7 @@
 
     def test_deannotate(self):
         XML = self.XML
-        root = XML(u'''\
+        root = XML(_bytes('''\
         <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:py="http://codespeak.net/lxml/objectify/pytype">
           <b>5</b>
@@ -1658,7 +1655,7 @@
           <l py:pytype="long">2</l>
           <t py:pytype="TREE"></t>
         </a>
-        ''')
+        '''))
         objectify.deannotate(root)
 
         for c in root.getiterator():
@@ -1669,7 +1666,7 @@
 
     def test_pytype_deannotate(self):
         XML = self.XML
-        root = XML(u'''\
+        root = XML(_bytes('''\
         <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:py="http://codespeak.net/lxml/objectify/pytype">
           <b>5</b>
@@ -1687,7 +1684,7 @@
           <l py:pytype="long">2</l>
           <t py:pytype="TREE"></t>
         </a>
-        ''')
+        '''))
         objectify.xsiannotate(root)
         objectify.deannotate(root, xsi=False)
 
@@ -1715,7 +1712,7 @@
 
     def test_xsitype_deannotate(self):
         XML = self.XML
-        root = XML(u'''\
+        root = XML(_bytes('''\
         <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:py="http://codespeak.net/lxml/objectify/pytype"
         xmlns:xsd="http://www.w3.org/2001/XMLSchema">
@@ -1734,7 +1731,7 @@
           <l py:pytype="long">2</l>
           <t py:pytype="TREE"></t>
         </a>
-        ''')
+        '''))
         objectify.annotate(root)
         objectify.deannotate(root, pytype=False)
 
@@ -1762,7 +1759,7 @@
 
     def test_pytype_deannotate(self):
         XML = self.XML
-        root = XML(u'''\
+        root = XML(_bytes('''\
         <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:py="http://codespeak.net/lxml/objectify/pytype"
         xmlns:xsd="http://www.w3.org/2001/XMLSchema">
@@ -1781,7 +1778,7 @@
           <l xsi:type="xsd:long">2</l>
           <t py:pytype="TREE"></t>
         </a>
-        ''')
+        '''))
         objectify.annotate(root)
         objectify.deannotate(root, xsi=False)
 
@@ -1810,7 +1807,7 @@
     def test_change_pytype_attribute(self):
         XML = self.XML
 
-        xml = u'''\
+        xml = _bytes('''\
         <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
           <b>5</b>
           <b>test</b>
@@ -1821,7 +1818,7 @@
           <n></n>
           <b xsi:type="double">5</b>
         </a>
-        '''
+        ''')
 
         pytype_ns, pytype_name = objectify.PYTYPE_ATTRIBUTE[1:].split('}')
         objectify.set_pytype_attribute_tag("{TEST}test")
@@ -2263,7 +2260,7 @@
         import pickle
 
         root = self.XML(xml_str)
-        out = StringIO()
+        out = BytesIO()
         pickle.dump(root, out)
 
         new_root = pickle.loads(out.getvalue())
@@ -2278,11 +2275,6 @@
         root = E.root(E.val(23))
         self.assert_(isinstance(root.val, objectify.IntElement))
 
-    def test_efactory_long(self):
-        E = objectify.E
-        root = E.root(E.val(23L))
-        self.assert_(isinstance(root.val, objectify.LongElement))
-
     def test_efactory_float(self):
         E = objectify.E
         root = E.root(E.val(233.23))
@@ -2295,7 +2287,7 @@
 
     def test_efactory_unicode(self):
         E = objectify.E
-        root = E.root(E.val(unicode("blöödy häll", encoding="ISO-8859-1")))
+        root = E.root(E.val(_str("blöödy häll", encoding="ISO-8859-1")))
         self.assert_(isinstance(root.val, objectify.StringElement))
 
     def test_efactory_bool(self):


More information about the lxml-checkins mailing list