[pygccxml-development] Serious bug in pygccxml (scopedef.py)
Brought to you by:
mbaas,
roman_yakovenko
|
From: Matthias B. <ba...@ir...> - 2006-03-15 09:44:01
|
Hi,
I just had a case where a query for a single class produced a result
that contained that class twice (this something that shouldn't be
possible at all).
It took me about an hour to find that bug. The problem is the scopedef_t
class (from which class_t and namespace_t are derived). This class
overrides the equality operator __eq__() and the implementation of that
operator has unwanted side effects, i.e. it modifies the instances! The
method calls self._sorted_list() with its declaration list as argument.
_sorted_list() sorts the list inplace, so this means the declaration
list gets modified. If you do that while iterating over the list you get
a messed up result where a declaration may appear twice (while other
declarations haven't been seen at all). I think this is quite a serious
bug (that is difficult to track down).
A quick fix would be to replace the last line in scopedef_t.__eq__() with:
return self._sorted_list( self.declarations[:] ) \
== other._sorted_list( other.declarations[:] )
That is, instead of passing declarations directly we pass a copy of that
list (using slice notation, you might also use the copy module).
But of course, these involves two copy operations which makes the
operator even more inefficient.
I have to admit that I dont't really understand why those operators are
overridden at all. In which case does it happen that two separate
declaration objects refer to the same declaration? (probably when a
declaration is included in two separate include files, right? But why
isn't the first declaration then reused in the first place?).
I think in my case I could switch to comparing id(decl) instead of decl
itself. But I think for someone else reading the code this is not really
obvious why I have to do that...
- Matthias -
PS: I also don't understand the purpose of the (static!) method
_sorted_list() as this method just calls sort() and does nothing else.
Why wasn't sort() used in the first place?
|