Patch for PyDO2

Jeroen van Dongen <[email protected]>
Newsgroups gmane.comp.web.skunkweb
Message-ID <1069541156.1141.23.camel@localhost>
Hi, 

I think I just found a bug in PyDO2.
In the __new__ method of _metapydo, we iterate over the namespace to
find any class_ or static_ members. When found, the prefix is stripped
and the new name is added to the namespace while the old one is removed.

Problem seems to be the line:
for k, v in namespace.iteritems()
 ... some code ...
   del namespace[k]

We change namespace, which is a dictionary, which is implemented as a 
hashtable. Under rare circumstances it apparently can so happen that
upon deletion of an entry, a not-yet processed key is rehashed to end up
BEFORE the currently processed key and hence is never processed.

I bumped into this with a specific class where one of my class_ methods
was not converted (it kept the class_ prefix). Any other name would do,
even changing the case of one of the characters in the name would do it,
except that specific one name. Drove me insane I can tell you that much
:)

Dumping namespace.keys() at each round of the for-loop showed that at
some point the troubled key moved to position 2 in the list produced by
keys(). That one was already processed, and hence my class_ method
disappeared, never to be seen again in that loop.

I've not been able to find any Python docs explaining this or warning
against it, but apparently it can happen. Neither have I been able to
reproduce it with any other combination of method/attribute names. I
think it's a rare treat as it probably requires a collision of hashed
keys for it to occur.

Anyway, attached you'll find a patch against current cvs. Simple enough
solution, but interesting 'feature' imo.

Rgds,
Jeroen
pydo.diff (text/x-patch, 526 B)
--- ../PyDO2.py	2003-11-22 23:16:38.000000000 +0100
+++ PyDO2.py	2003-11-22 23:18:15.000000000 +0100
@@ -29,7 +29,8 @@
     def __new__(self, cl_name, bases, namespace):
         prefix_descriptor_pairs=(('static_', staticmethod),
                                  ('class_', classmethod))
-        for k, v in namespace.iteritems():
+	ns = namespace.items()
+        for k, v in ns:
             for prefix, descriptor in prefix_descriptor_pairs:
                 lenpre=len(prefix)
                 if k.startswith(prefix):
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.