[Python-bugs-list] [ python-Bugs-649122 ] marshal/pickle problem with True/False
noreply@sourceforge.net
noreply@sourceforge.net
Fri, 06 Dec 2002 03:08:18 -0800
Bugs item #649122, was opened at 2002-12-05 20:32
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=649122&group_id=5470
Category: Python Library
Group: None
>Status: Closed
>Resolution: Fixed
Priority: 5
Submitted By: Shack Toms (shacktoms)
Assigned to: Michael Hudson (mwh)
Summary: marshal/pickle problem with True/False
Initial Comment:
It appears that True and False are special cases of
integer 1 and 0 such that...
>>> True is 1
0
>>> False is 0
0
After pickling or marshaling, however, this specialness
is lost.
>>> pickle.loads(pickle.dumps(True)) is 1
1
>>> pickle.loads(pickle.dumps(True)) is True
0
>>> pickle.loads(pickle.dumps(False)) is 0
1
>>> pickle.loads(pickle.dumps(False)) is False
0
In other words, True is unpickled as a non-special 1 and
False is unpicked as a non-special 0.
It appears that the problem, the bug, is that neither
pickle nor marshal distinguishes between True/False
and 1/0.
>>> pickle.dumps(True) == pickle.dumps(1)
1
>>> pickle.dumps(False) == pickle.dumps(0)
1
>>> pickle.dumps(True) == pickle.dumps(1)
1
>>> pickle.dumps(False) == pickle.dumps(0)
1
>>> marshal.dumps(True) == marshal.dumps(1)
1
>>> marshal.dumps(False) == marshal.dumps(0)
1
My version info...
Python 2.2.2 (#37, Oct 14 2002, 17:02:34) [MSC 32 bit
(Intel)] on win32
Microsoft Windows 2000 5.00.2195 Service Pack 3
----------------------------------------------------------------------
>Comment By: Martin v. Löwis (loewis)
Date: 2002-12-06 12:08
Message:
Logged In: YES
user_id=21627
For Python 2.3, this has been fixed, by making True and
False instances of their own type, and by pickling an extra
0 before the integer value.
For Python 2.2, this won't be fixed: This special-ness of
True and False really is an implementation detail that
should be be relied upon. Applications that absolutely need
this property must implement custom getstate/setstate
methods that restore boolean integers to their boolean-ness
on setstate. That way, they also achieve portability to the
released versions of Python 2.2, instead of relying on
not-yet-and-perhaps-never released versions.
----------------------------------------------------------------------
Comment By: Shack Toms (shacktoms)
Date: 2002-12-06 00:08
Message:
Logged In: YES
user_id=603293
True and False may be integers, but they are special in that
they are Py_True and Py_False, internally.
Why is this important?
True and False are treated differently from 1 and 0 when
converted to a variant by Mark Hammond's oleargs.cpp code,
which specifically checks for Py_True and Py_False before
checking for Integer-ness by calling PyInt_Check(). These
values get converted to the VARIANT_BOOL type, with values
0xffff and 0. For this reason, it would be useful if their
special "True" and "False" -ness could be preserved by
pickling.
>>> 1 == 1
1
>>> (1 == 1) is True
1
>>> (1 == 1) is 1
0
Because of the above, logical results get converted by
Hammond's code to the correct VARIANT_BOOL types--but
not after pickling.
----------------------------------------------------------------------
Comment By: Michael Hudson (mwh)
Date: 2002-12-05 20:39
Message:
Logged In: YES
user_id=6656
I'm afraid you're a bit confused. In 2.2.x True and False
are integers. They may not actually *be* the integers you
get when you type 1 and 0, but they are still integers.
If you try what you tried in a 2.3a0 build from CVS, you
should see different answers. Applying identity (`is') to
immutable objects is discouraged for exactly this sort of
reason...
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=649122&group_id=5470