warjiang / dpkt

Automatically exported from code.google.com/p/dpkt
Other
0 stars 0 forks source link

python 2.6: RuntimeError: dictionary changed size during iteration #35

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Python 2.6.5 (release26-maint, Jun 23 2010, 10:41:00) 
[GCC 4.3.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import dpkt
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/site-packages/dpkt/__init__.py", line 24, in <module>
    import ethernet
  File "/usr/lib/python2.6/site-packages/dpkt/ethernet.py", line 128, in <module>
    __load_types()
  File "/usr/lib/python2.6/site-packages/dpkt/ethernet.py", line 122, in __load_types
    mod = __import__(modname, g)
  File "/usr/lib/python2.6/site-packages/dpkt/ip6.py", line 95, in <module>
    import ip
  File "/usr/lib/python2.6/site-packages/dpkt/ip.py", line 255, in <module>
    __load_protos()
  File "/usr/lib/python2.6/site-packages/dpkt/ip.py", line 245, in __load_protos
    for k, v in g.iteritems():
RuntimeError: dictionary changed size during iteration

Quick fix:
--- /usr/lib/python2.6/site-packages/dpkt/ip.py~        2010-03-26 
04:53:51.000000000 +0200
+++ /usr/lib/python2.6/site-packages/dpkt/ip.py 2010-07-06 18:54:05.013117134 
+0300
@@ -242,7 +242,7 @@
 # XXX - auto-load IP dispatch table from IP_PROTO_* definitions
 def __load_protos():
     g = globals()
-    for k, v in g.iteritems():
+    for k, v in list(g.iteritems()):
         if k.startswith('IP_PROTO_'):
             name = k[9:].lower()
             try:

Original issue reported on code.google.com by y.dmi...@gmail.com on 6 Jul 2010 at 4:00

GoogleCodeExporter commented 9 years ago
I can't reproduce this?

Original comment by dugsong on 6 Jan 2011 at 3:45

GoogleCodeExporter commented 9 years ago
I just ran into this on OS X.

[joe@deepwater-2:~]$ python -c 'import dpkt'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/dpkt/__init__.py", line 24, in <module>
    import ethernet
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/dpkt/ethernet.py", line 128, in <module>
    __load_types()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/dpkt/ethernet.py", line 122, in __load_types
    mod = __import__(modname, g)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/dpkt/ip6.py", line 95, in <module>
    import ip
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/dpkt/ip.py", line 255, in <module>
    __load_protos()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/dpkt/ip.py", line 245, in __load_protos
    for k, v in g.iteritems():
RuntimeError: dictionary changed size during iteration

However, it's not consistent. Not sure what triggers it.

Original comment by jeggles...@gmail.com on 1 Mar 2011 at 9:13

GoogleCodeExporter commented 9 years ago
Alternate fix: 

--- dpkt/ip.py  (revision 84)
+++ dpkt/ip.py  (working copy)
@@ -2,6 +2,7 @@

 """Internet Protocol."""

+import copy
 import dpkt

 class IP(dpkt.Packet):
@@ -241,7 +242,7 @@

 # XXX - auto-load IP dispatch table from IP_PROTO_* definitions
 def __load_protos():
-    g = globals()
+    g = copy.copy(globals())
     for k, v in g.iteritems():
         if k.startswith('IP_PROTO_'):
             name = k[9:].lower()

Original comment by joed...@gmail.com on 12 Sep 2012 at 8:53

GoogleCodeExporter commented 9 years ago
So I had the same problem and I dug in and I notice that the problem is that 
the import in that loop is not relative. Meaning that you might import a 
non-relevant package by accident (in my case mtp).

The solution is:
@@ -246,7 +246,7 @@
         if k.startswith('IP_PROTO_'):
             name = k[9:].lower()
             try:
-                mod = __import__(name, g)
+                mod = __import__(name, g, level=1)
             except ImportError:
                 continue
             IP.set_proto(v, getattr(mod, name.upper()))

This should be commited to head

Original comment by dan...@lacoon.com on 13 May 2013 at 8:59