Added code submitted by Andreas Pakulat to provide node equality,

* python/libxml.c, python/libxml.py, python/tests/compareNodes.py,
  python/tests/Makefile.am:
  Added code submitted by Andreas Pakulat to provide node
  equality, inequality and hash functions, plus a single
  test program to check the functions (bugs 345779 + 345961).
diff --git a/python/libxml.c b/python/libxml.c
index 88b29cf..6e9a78e 100644
--- a/python/libxml.c
+++ b/python/libxml.c
@@ -3677,6 +3677,40 @@
     return Py_BuildValue((char *)"s", str);
 }
 
+static PyObject *
+libxml_compareNodesEqual(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
+    
+    PyObject *py_node1, *py_node2;
+    xmlNodePtr node1, node2;
+
+    if (!PyArg_ParseTuple(args, (char *)"OO:compareNodesEqual",
+		&py_node1, &py_node2))
+        return NULL;
+    /* To compare two node objects, we compare their pointer addresses */
+    node1 = PyxmlNode_Get(py_node1);
+    node2 = PyxmlNode_Get(py_node2);
+    if ( node1 == node2 )
+        return Py_BuildValue((char *)"i", 1);
+    else
+        return Py_BuildValue((char *)"i", 0);
+    
+}
+
+static PyObject *
+libxml_nodeHash(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
+
+    PyObject *py_node1;
+    xmlNodePtr node1;
+
+    if (!PyArg_ParseTuple(args, (char *)"O:nodeHash", &py_node1))
+	    return NULL;
+    /* For simplicity, we use the node pointer address as a hash value */
+    node1 = PyxmlNode_Get(py_node1);
+
+    return PyLong_FromVoidPtr(node1);
+
+}
+
 /************************************************************************
  *									*
  *			The registration stuff				*
@@ -3730,6 +3764,8 @@
 #endif
 #endif
     {(char *) "getObjDesc", libxml_getObjDesc, METH_VARARGS, NULL},
+    {(char *) "compareNodesEqual", libxml_compareNodesEqual, METH_VARARGS, NULL},
+    {(char *) "nodeHash", libxml_nodeHash, METH_VARARGS, NULL},
     {NULL, NULL, 0, NULL}
 };
 
diff --git a/python/libxml.py b/python/libxml.py
index 997e15f..f7c3129 100644
--- a/python/libxml.py
+++ b/python/libxml.py
@@ -232,6 +232,23 @@
             self._o = _obj;
             return
         self._o = None
+
+    def __eq__(self, other):
+        if other == None:
+	    return False
+        ret = libxml2mod.compareNodesEqual(self._o, other._o)
+	if ret == None:
+	    return False
+	return ret == True
+    def __ne__(self, other):
+        if other == None:
+	    return True
+        ret = libxml2mod.compareNodesEqual(self._o, other._o)
+	return not ret
+    def __hash__(self):
+    	ret = libxml2mod.nodeHash(self._o)
+	return ret
+
     def __str__(self):
         return self.serialize()
     def get_parent(self):
diff --git a/python/tests/Makefile.am b/python/tests/Makefile.am
index 3571abf..39950f6 100644
--- a/python/tests/Makefile.am
+++ b/python/tests/Makefile.am
@@ -43,7 +43,8 @@
     tstmem.py	\
     validDTD.py	\
     validSchemas.py \
-    validRNG.py
+    validRNG.py \
+    compareNodes.py
 
 XMLS=		\
     tst.xml	\
diff --git a/python/tests/compareNodes.py b/python/tests/compareNodes.py
new file mode 100755
index 0000000..ec04323
--- /dev/null
+++ b/python/tests/compareNodes.py
@@ -0,0 +1,50 @@
+#!/usr/bin/python -u
+import sys
+import libxml2
+
+# Memory debug specific
+libxml2.debugMemory(1)
+
+#
+# Testing XML Node comparison and Node hash-value
+#
+doc = libxml2.parseDoc("""<root><foo/></root>""")
+root = doc.getRootElement()
+
+# Create two different objects which point to foo
+foonode1 = root.children
+foonode2 = root.children
+
+# Now check that [in]equality tests work ok
+if not ( foonode1 == foonode2 ):
+    print "Error comparing nodes with ==, nodes should be equal but are unequal"
+    sys.exit(1)
+if not ( foonode1 != root ):
+    print "Error comparing nodes with ==, nodes should not be equal but are equal"
+    sys.exit(1)
+if not ( foonode1 != root ):
+    print "Error comparing nodes with !=, nodes should not be equal but are equal"
+if ( foonode1 != foonode2 ):
+    print "Error comparing nodes with !=, nodes should be equal but are unequal"
+
+# Next check that the hash function for the objects also works ok
+if not (hash(foonode1) == hash(foonode2)):
+    print "Error hash values for two equal nodes are different"
+    sys.exit(1)
+if not (hash(foonode1) != hash(root)):
+    print "Error hash values for two unequal nodes are not different"
+    sys.exit(1)
+if hash(foonode1) == hash(root):
+    print "Error hash values for two unequal nodes are equal"
+    sys.exit(1)
+
+# Basic tests successful
+doc.freeDoc()
+
+# Memory debug specific
+libxml2.cleanupParser()
+if libxml2.debugMemory(1) == 0:
+    print "OK"
+else:
+    print "Memory leak %d bytes" % (libxml2.debugMemory(1))
+    libxml2.dumpMemory()