[Marshal Bug] Was Re: curious problem with large numbers
Michael Spencer
mahs at telcopartners.com
Fri Apr 8 18:03:15 EDT 2005
OK - I think this is it:
My last post fingering pickle was almost but not quite right*. Actually the
cuplrit is marshal, which produces the incorrect result that was noted. The bug
has nothing to do with IDLE, except that it uses marshal for inter-process
communication.
Here's the failure case:
>>> marshal.dumps(1e10000)
'f\x061.#INF'
>>> marshal.loads(_)
1.0
>>>
I speculate that this comes from marshal doing eval('1.#INF') rather than
float('1.#INF'), and that it should be fixed to use float. Alternatively, it
could detect this special case and raise its own exception. By analogy with
pickle and cPickle it would make sense to raise ValueError on unmarshalling
i.e., marshal.load(s).
>>> import pickle
>>> pickle.dumps(1e10000)
'F1.#INF\n.'
>>> pickle.loads(_)
Traceback (most recent call last):
File "<input>", line 1, in ?
File "c:\python24\lib\pickle.py", line 1394, in loads
return Unpickler(file).load()
File "c:\python24\lib\pickle.py", line 872, in load
dispatch[key](self)
File "c:\python24\lib\pickle.py", line 968, in load_float
self.append(float(self.readline()[:-1]))
ValueError: invalid literal for float(): 1.#INF
>>>
A more ambitious fix (which could be combined with option 1) would have the
float constructor accept 1.#INF
Incidentally, the reason why this workaround is effective:
IDLE 1.1
>>> 1e308*2
1.#INF
>>>
is that it is the compiled code object (not what it evaluates to) that is marshalled
>>> co = compile("1e308*2","<None>","single")
>>> dis.dis(co)
1 0 LOAD_CONST 0 (1e+308)
3 LOAD_CONST 1 (2)
6 BINARY_MULTIPLY
7 PRINT_EXPR
8 LOAD_CONST 2 (None)
11 RETURN_VALUE
>>> ma = marshal.dumps(co)
>>> ma
'c\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00@\x00\x00\x00s\x0c\x00\x00\x00d\x00\x00d\x01\x00\x14Fd\x02\x00S(\x03\x00\x00\x00f\x061e+308i\x02\x00\x00\x00N(\x00\x00\x00\x00(\x00\x00\x00\x00(\x00\x00\x00\x00(\x00\x00\x00\x00t\x06\x00\x00\x00<None>t\x01\x00\x00\x00?\x01\x00\x00\x00s\x00\x00\x00\x00'
>>>
Michael
More information about the Python-list
mailing list