After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 345779 - equality check for python bindings
equality check for python bindings
Status: RESOLVED FIXED
Product: libxml2
Classification: Platform
Component: general
2.6.22
Other All
: Normal enhancement
: ---
Assigned To: Daniel Veillard
libxml QA maintainers
Depends on:
Blocks:
 
 
Reported: 2006-06-23 22:36 UTC by Andreas Pakulat
Modified: 2006-06-26 19:21 UTC
See Also:
GNOME target: ---
GNOME version: Unversioned Enhancement


Attachments
support equality check for xmlNode's in python bindings (1.87 KB, patch)
2006-06-25 20:08 UTC, Andreas Pakulat
none Details | Review
testcase for the comparison patch (1.00 KB, patch)
2006-06-25 20:09 UTC, Andreas Pakulat
none Details | Review
fixed patch for the comparison method (2.02 KB, patch)
2006-06-25 21:54 UTC, Andreas Pakulat
none Details | Review
final patch for comparing 2 nodes in the python bindings (1.95 KB, patch)
2006-06-26 08:36 UTC, Andreas Pakulat
none Details | Review
new testcase, including 2 more tests (1.27 KB, patch)
2006-06-26 10:27 UTC, Andreas Pakulat
none Details | Review

Description Andreas Pakulat 2006-06-23 22:36:52 UTC
Hi,

this is a request for a function in the python bindings that will tell the user wether two given nodes are the same. You cannot use pythons "==" operator as the nodes are always newly created to avoid the need for reference-counting.

Daniel Veillard dropped a short note on libxml2 list how this could be done:
  unfortunately I'm afraid you need to go down to the C level and
  check the 2 pointers, they aren't seen at the python level. Should be
  a fairly easy change to python/libxml.c to add this equality entry point
  and then add a method in the node class in libxml.py to be used for
(I'm citing him here, because his mail doesn't show up in the archive)

I don't know wether I can provide an initial patch as my knowledge about these things is rather limited.

Thanks,
Andreas
Comment 1 Andreas Pakulat 2006-06-25 20:00:36 UTC
Hi,

I had a shot at this and came up with the attached patches (the first for libxml.c and libxml.py, the second is the testcase). 

However it seems that the nodes are always equal, i.e. comparing

xmlNodePtr1 == xmlNodePtr2 

always evaluates to true and I don't really see what else I could use (I already tried using psvi from xmlNode, but that didn't work either).

I'm stuck there now and would really appreciate some help.

Thanks,
Andreas
Comment 2 Andreas Pakulat 2006-06-25 20:08:25 UTC
Created attachment 67986 [details] [review]
support equality check for xmlNode's in python bindings

The patch adds 2 methods to xmlCore: __eq__ and __ne__ which will be used by Python when comparing two xmlCore-derived objects using == or !=. The underlying C function compares the xmlNodePtr values, however it seems this is not sufficient (always returns true)
Comment 3 Andreas Pakulat 2006-06-25 20:09:38 UTC
Created attachment 67987 [details] [review]
testcase for the comparison patch

Tests for equality and un-equality of 2 xmlNodes.
Comment 4 William M. Brack 2006-06-25 21:19:47 UTC
Do not despair - your patch works OK for me :-)

When testing, make sure that your paths are setup correctly - I'm not sure of which OS you are working with - if it's Linux, then one easy way is to (manually) set LD_LIBRARY_PATH and PYTHONPATH, e.g.:

bill@bbsf /usr/projects/gnomecvs/xmltest/python/tests $ echo $LD_LIBRARY_PATH
/usr/projects/gnomecvs/xmltest/.libs

bill@bbsf /usr/projects/gnomecvs/xmltest/python/tests $ echo $PYTHONPATH
/usr/projects/gnomecvs/xmltest/python/:/usr/projects/gnomecvs/xmltest/python/.libs

bill@bbsf /usr/projects/gnomecvs/xmltest/python/tests $ ./compareNodes.py
<xmlNode (foo) object at 0x2b8768f8c8c0> <xmlNode (foo) object at 0x2b8768f8c908>
__eq__ 1
<xmlNode (foo) object at 0x2b8768f8c8c0> <xmlNode (root) object at 0x2b8768f8c1b8>
__ne__ 1
OK
Comment 5 Andreas Pakulat 2006-06-25 21:53:15 UTC
That is, because the patch is actually wrong. __ne__ returns the same value as __eq__, you could try

>>> import libxml2
>>> doc=libxml2.parseDoc('<root><doc /></root>')
>>> root = doc.getRootElement()
>>> foonode1=doc.children
>>> foonode1==root
<xmlNode (root) object at 0x-483cb674> <xmlNode (root) object at 0x-483cbbb4>
__eq__ 1
1

Which is totally wrong...

I think it would already help if I could get the actual pointer addresses out of the function I  wrote. I currently don't really want to try to debug libxml2 with plain gdb...

I'll attach a new patch which shows that somethings wrong.

Andreas
Comment 6 Andreas Pakulat 2006-06-25 21:54:25 UTC
Created attachment 67995 [details] [review]
fixed patch for the comparison method

this fixes the __ne__ function which returned the same as __eq__ (a missing not  in the return).
Comment 7 Andreas Pakulat 2006-06-25 22:37:41 UTC
Hi, 

so I started gdb and ran the test script in it.

It seems that the PyObject's given in args are somehow not containing proper xmlNodePtr's:

Breakpoint 6, libxml_compareNodesEqual (self=0x0, args=0xb72f5cac) at libxml.c:3697
3697        node1 = PyxmlNode_Get(py_node1);
(gdb) step
3699        node2 = PyxmlNode_Get(py_node2);
(gdb) step
3700        if ( node1 == NULL || node2 == NULL )
(gdb) print node1
$9 = (xmlNodePtr) 0xb78bd17c
(gdb) print node2
$10 = (xmlNodePtr) 0xb78bd17c
(gdb) print node1->name
$11 = (const xmlChar *) 0xb740d76c "\001"
(gdb) print node2->name
$12 = (const xmlChar *) 0xb740d76c "\001"
(gdb) print node2->type
$13 = 135379328
(gdb) print node1->type
$14 = 135379328

I'll try with __eq__ and __ne__ on the xmlNode class instead, maybe the problem is that it's defined on xmlCore class.
Comment 8 William M. Brack 2006-06-26 00:40:41 UTC
Try a small enhancement to your patch for libxml.py: change the

  ret = libxml2mod.compareNodesEqual(self, other)

to be

  ret = libxml2mod.compareNodesEqual(self._o, other._o)

and see how you like the results...
Comment 9 Andreas Pakulat 2006-06-26 08:30:24 UTC
Thanks,

somhow I missed that all the other functions in libxml.py do this.

Attaching the final version of the patch.

Andreas
Comment 10 Andreas Pakulat 2006-06-26 08:36:31 UTC
Created attachment 68018 [details] [review]
final patch for comparing 2 nodes in the python bindings

Thanks to William Brack, this patch now works as it is expected. So I'm uploading a clean patch (that doesn't contain any extra print's).
Comment 11 Andreas Pakulat 2006-06-26 10:27:33 UTC
Created attachment 68024 [details] [review]
new testcase, including 2 more tests

I updated the testcase, to also check wether == returns true on unequal nodes and != returns false on unequal nodes.
Comment 12 William M. Brack 2006-06-26 18:32:51 UTC
I combined the later bug 345961 with this request, added some small enhancements (including taking care of the case where one operand is None, and assuring that __eq__ always returns a Boolean), and committed to CVS.  Please check that you agree with what I did, and re-open this bug if there are any problems.

Bill
Comment 13 Andreas Pakulat 2006-06-26 19:21:11 UTC
Looks good to me.