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

scoder at codespeak.net scoder at codespeak.net
Mon Aug 20 12:15:34 CEST 2007


Author: scoder
Date: Mon Aug 20 12:15:32 2007
New Revision: 45876

Modified:
   lxml/trunk/src/lxml/cstd.pxd
   lxml/trunk/src/lxml/etree_defs.h
   lxml/trunk/src/lxml/objectify.pyx
   lxml/trunk/src/lxml/python.pxd
   lxml/trunk/src/lxml/tests/test_objectify.py
Log:
objectify updates by Holger, support passing ObjectifiedElement objects into DateElement()

Modified: lxml/trunk/src/lxml/cstd.pxd
==============================================================================
--- lxml/trunk/src/lxml/cstd.pxd	(original)
+++ lxml/trunk/src/lxml/cstd.pxd	Mon Aug 20 12:15:32 2007
@@ -9,6 +9,7 @@
     cdef int strlen(char* s)
     cdef char* strstr(char* haystack, char* needle)
     cdef char* strchr(char* haystack, int needle)
+    cdef char* strrchr(char* haystack, int needle)
     cdef int strcmp(char* s1, char* s2)
     cdef int strncmp(char* s1, char* s2, size_t len)
     cdef void* memcpy(void* dest, void* src, size_t len)

Modified: lxml/trunk/src/lxml/etree_defs.h
==============================================================================
--- lxml/trunk/src/lxml/etree_defs.h	(original)
+++ lxml/trunk/src/lxml/etree_defs.h	Mon Aug 20 12:15:32 2007
@@ -99,6 +99,7 @@
 #define repr(o)         PyObject_Repr(o)
 #define iter(o)         PyObject_GetIter(o)
 #define _cstr(s)        PyString_AS_STRING(s)
+#define _fqtypename(o)  (((PyTypeObject*)o)->ob_type->tp_name)
 
 static PyObject* __PY_NEW_GLOBAL_EMPTY_TUPLE = NULL;
 

Modified: lxml/trunk/src/lxml/objectify.pyx
==============================================================================
--- lxml/trunk/src/lxml/objectify.pyx	(original)
+++ lxml/trunk/src/lxml/objectify.pyx	Mon Aug 20 12:15:32 2007
@@ -70,6 +70,16 @@
 cdef object _ElementMaker
 from builder import ElementMaker as _ElementMaker
 
+cdef object _typename(object t):
+    cdef char* c_name
+    cdef char* s
+    c_name = python._fqtypename(t)
+    s = cstd.strrchr(c_name, c'.')
+    if s == NULL:
+        return c_name
+    else:
+        return (s+1)
+
 # namespace/name for "pytype" hint attribute
 cdef object PYTYPE_NAMESPACE
 cdef char* _PYTYPE_NAMESPACE
@@ -232,7 +242,7 @@
         if tag == 'text' or tag == 'pyval':
             # read-only !
             raise TypeError, "attribute '%s' of '%s' objects is not writable"% \
-                  (tag, type(self).__name__)
+                  (tag, _typename(self))
         elif tag == 'tail':
             cetree.setTailText(self._c_node, value)
             return
@@ -916,6 +926,15 @@
 def __lower_bool(b):
     return _lower_bool(b)
 
+cdef _get_pytypename(obj):
+    if python.PyUnicode_Check(obj):
+        return "str"
+    else:
+        return _typename(obj)
+
+def __get_pytypename(obj):
+    return _get_pytypename(obj)
+
 cdef _registerPyTypes():
     pytype = PyType('int', int, IntElement)
     pytype.xmlSchemaTypes = ("int", "short", "byte", "unsignedShort",
@@ -1020,7 +1039,6 @@
     """Type map for the ElementMaker.
     """
     cdef object _typemap
-    cdef object _typemap_get
 
     def __init__(self, initial=None):
         if initial is None:
@@ -1132,7 +1150,7 @@
             else:
                 value = repr(value)
     result = "%s%s = %s [%s]\n" % (indentstr, element.tag,
-                                   value, type(element).__name__)
+                                   value, _typename(element))
     xsi_ns    = "{%s}" % XML_SCHEMA_INSTANCE_NS
     pytype_ns = "{%s}" % PYTYPE_NAMESPACE
     for name, value in cetree.iterattributes(element, 3):
@@ -2019,6 +2037,13 @@
             attrib = dict(attrib)
             attrib.update(_attributes)
         _attributes = attrib
+    if isinstance(_value, ObjectifiedElement):
+        if _pytype is None:
+            if _xsi is None and not _attributes and nsmap is _DEFAULT_NSMAP:
+                # special case: no change!
+                return _value.__copy__()
+            elif PYTYPE_ATTRIBUTE not in _attributes:
+                _pytype = _get_pytypename(_value)
     if isinstance(_value, ObjectifiedDataElement):
         # reuse existing nsmap unless redefined in nsmap parameter
         temp = _value.nsmap
@@ -2070,9 +2095,9 @@
             if dict_result is not NULL:
                 _pytype = (<PyType>dict_result).name
 
-    if _value is None:
+    if _value is None and _pytype != "str":
+        _pytype = _pytype or "NoneType"
         strval = None
-        _pytype = "NoneType"
     elif python._isString(_value):
         strval = _value
     elif python.PyBool_Check(_value):
@@ -2102,7 +2127,7 @@
                 type_check(strval)
 
     if _pytype is not None: 
-        if _pytype == "NoneType":
+        if _pytype == "NoneType" or _pytype == "none":
             strval = None
             python.PyDict_SetItem(_attributes, XML_SCHEMA_INSTANCE_NIL_ATTR, "true")
         else:

Modified: lxml/trunk/src/lxml/python.pxd
==============================================================================
--- lxml/trunk/src/lxml/python.pxd	(original)
+++ lxml/trunk/src/lxml/python.pxd	Mon Aug 20 12:15:32 2007
@@ -107,6 +107,7 @@
     cdef int _isString(object obj)
     cdef int isinstance(object instance, object classes)
     cdef int issubclass(object derived,  object superclasses)
+    cdef char* _fqtypename(object t)
     cdef int hasattr(object obj, object attr)
     cdef object getattr(object obj, object attr)
     cdef int callable(object obj)

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	Mon Aug 20 12:15:32 2007
@@ -658,6 +658,18 @@
         self.assertEquals(value.text, None)
         self.assertEquals(value.pyval, None)
             
+    def test_data_element_pytype_none_compat(self):
+        # pre-2.0 lxml called NoneElement "none"
+        pyval = 1
+        pytype = "none"
+        objclass = objectify.NoneElement
+        value = objectify.DataElement(pyval, _pytype=pytype)
+        self.assert_(isinstance(value, objclass),
+                     "DataElement(%s, _pytype='%s') returns %s, expected %s"
+                     % (pyval, pytype, type(value), objclass))
+        self.assertEquals(value.text, None)
+        self.assertEquals(value.pyval, None)
+            
     def test_schema_types(self):
         XML = self.XML
         root = XML('''\


More information about the lxml-checkins mailing list