From e58d58063f6e66dcbe7c11a18fb18de68a995f7c Mon Sep 17 00:00:00 2001 From: stevenknight Date: Fri, 9 Apr 2010 18:39:21 +0000 Subject: [PATCH] Issue 2331: For forward compatibility, use "import pickle" and have the SCons.compat layer import cPickle as pickle when it's available. git-svn-id: http://scons.tigris.org/svn/scons/trunk@4778 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- src/engine/SCons/Action.py | 9 ++++++--- src/engine/SCons/SConsign.py | 14 ++++++++------ src/engine/SCons/Tool/msvs.py | 25 ++++++++++++++----------- src/engine/SCons/compat/__init__.py | 14 ++++++++++++++ src/engine/SCons/dblite.py | 25 ++++++++++++++----------- 5 files changed, 56 insertions(+), 31 deletions(-) diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py index da68b7de..ff67b490 100644 --- a/src/engine/SCons/Action.py +++ b/src/engine/SCons/Action.py @@ -100,9 +100,12 @@ from __future__ import generators ### KEEP FOR COMPATIBILITY FIXERS __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import cPickle +import SCons.compat + import dis import os +# compat layer imports "cPickle" for us if it's available. +import pickle import re import sys import subprocess @@ -208,8 +211,8 @@ def _object_contents(obj): except AttributeError: # Should be a pickable Python object. try: - return cPickle.dumps(obj) - except (cPickle.PicklingError, TypeError): + return pickle.dumps(obj) + except (pickle.PicklingError, TypeError): # This is weird, but it seems that nested classes # are unpickable. The Python docs say it should # always be a PicklingError, but some Python diff --git a/src/engine/SCons/SConsign.py b/src/engine/SCons/SConsign.py index bd322780..9f07ef24 100644 --- a/src/engine/SCons/SConsign.py +++ b/src/engine/SCons/SConsign.py @@ -29,9 +29,11 @@ Writing and reading information to the .sconsign file or files. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import cPickle +import SCons.compat + import os -import os.path +# compat layer imports "cPickle" for us if it's available. +import pickle import SCons.dblite import SCons.Warnings @@ -201,7 +203,7 @@ class DB(Base): pass else: try: - self.entries = cPickle.loads(rawentries) + self.entries = pickle.loads(rawentries) if not isinstance(self.entries, dict): self.entries = {} raise TypeError @@ -239,7 +241,7 @@ class DB(Base): path = normcase(self.dir.path) for key, entry in self.entries.items(): entry.convert_to_sconsign() - db[path] = cPickle.dumps(self.entries, 1) + db[path] = pickle.dumps(self.entries, 1) if sync: try: @@ -260,7 +262,7 @@ class Dir(Base): if not fp: return - self.entries = cPickle.load(fp) + self.entries = pickle.load(fp) if not isinstance(self.entries, dict): self.entries = {} raise TypeError @@ -327,7 +329,7 @@ class DirFile(Dir): return for key, entry in self.entries.items(): entry.convert_to_sconsign() - cPickle.dump(self.entries, file, 1) + pickle.dump(self.entries, file, 1) file.close() if fname != self.sconsign: try: diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index 684ca458..69864885 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -34,11 +34,14 @@ from __future__ import generators ### KEEP FOR COMPATIBILITY FIXERS __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +import SCons.compat + import base64 -import cPickle import hashlib import ntpath import os +# compat layer imports "cPickle" for us if it's available. +import pickle import re import sys @@ -426,10 +429,10 @@ class _GenerateV6DSP(_DSPGenerator): if self.nokeep == 0: # now we pickle some data and add it to the file -- MSDEV will ignore it. - pdata = cPickle.dumps(self.configs,1) + pdata = pickle.dumps(self.configs,1) pdata = base64.encodestring(pdata) self.file.write(pdata + '\n') - pdata = cPickle.dumps(self.sources,1) + pdata = pickle.dumps(self.sources,1) pdata = base64.encodestring(pdata) self.file.write(pdata + '\n') @@ -487,7 +490,7 @@ class _GenerateV6DSP(_DSPGenerator): # OK, we've found our little pickled cache of data. try: datas = base64.decodestring(datas) - data = cPickle.loads(datas) + data = pickle.loads(datas) except KeyboardInterrupt: raise except: @@ -506,7 +509,7 @@ class _GenerateV6DSP(_DSPGenerator): # it has a "# " in front of it, so we strip that. try: datas = base64.decodestring(datas) - data = cPickle.loads(datas) + data = pickle.loads(datas) except KeyboardInterrupt: raise except: @@ -688,10 +691,10 @@ class _GenerateV7DSP(_DSPGenerator): if self.nokeep == 0: # now we pickle some data and add it to the file -- MSDEV will ignore it. - pdata = cPickle.dumps(self.configs,1) + pdata = pickle.dumps(self.configs,1) pdata = base64.encodestring(pdata) self.file.write('\n') @@ -792,7 +795,7 @@ class _GenerateV7DSP(_DSPGenerator): # OK, we've found our little pickled cache of data. try: datas = base64.decodestring(datas) - data = cPickle.loads(datas) + data = pickle.loads(datas) except KeyboardInterrupt: raise except: @@ -810,7 +813,7 @@ class _GenerateV7DSP(_DSPGenerator): # OK, we've found our little pickled cache of data. try: datas = base64.decodestring(datas) - data = cPickle.loads(datas) + data = pickle.loads(datas) except KeyboardInterrupt: raise except: @@ -937,7 +940,7 @@ class _GenerateV7DSW(_DSWGenerator): # OK, we've found our little pickled cache of data. try: datas = base64.decodestring(datas) - data = cPickle.loads(datas) + data = pickle.loads(datas) except KeyboardInterrupt: raise except: @@ -1042,7 +1045,7 @@ class _GenerateV7DSW(_DSWGenerator): '\tEndGlobalSection\n') self.file.write('EndGlobal\n') if self.nokeep == 0: - pdata = cPickle.dumps(self.configs,1) + pdata = pickle.dumps(self.configs,1) pdata = base64.encodestring(pdata) self.file.write(pdata + '\n') diff --git a/src/engine/SCons/compat/__init__.py b/src/engine/SCons/compat/__init__.py index 4553d212..f220c324 100644 --- a/src/engine/SCons/compat/__init__.py +++ b/src/engine/SCons/compat/__init__.py @@ -193,6 +193,20 @@ except AttributeError: os.path.lexists = lexists +try: + # Use the "imp" module to protect the import from fixers. + import imp + cPickle = imp.load_module('cPickle', *imp.find_module('cPickle')) +except ImportError, e: + # The "cPickle" module has already been eliminated in favor of + # having "import pickle" import the fast version when available. + pass +else: + import sys + sys.modules['pickle'] = cPickle + del cPickle + + try: # Use the "imp" module to protect the import from fixers. import imp diff --git a/src/engine/SCons/dblite.py b/src/engine/SCons/dblite.py index 0789396a..01770fec 100644 --- a/src/engine/SCons/dblite.py +++ b/src/engine/SCons/dblite.py @@ -1,10 +1,13 @@ # dblite.py module contributed by Ralf W. Grosse-Kunstleve. # Extended for Unicode by Steven Knight. -import cPickle -import time -import shutil +import SCons.compat + import os +# compat layer imports "cPickle" for us if it's available. +import pickle +import shutil +import time import __builtin__ keep_all_files = 00000 @@ -42,7 +45,7 @@ class dblite: # http://mail.python.org/pipermail/python-bugs-list/2003-March/016877.html _open = __builtin__.open - _cPickle_dump = cPickle.dump + _pickle_dump = pickle.dump _os_chmod = os.chmod try: _os_chown = os.chown @@ -95,8 +98,8 @@ class dblite: p = f.read() if (len(p) > 0): try: - self._dict = cPickle.loads(p) - except (cPickle.UnpicklingError, EOFError): + self._dict = pickle.loads(p) + except (pickle.UnpicklingError, EOFError): if (ignore_corrupt_dbfiles == 0): raise if (ignore_corrupt_dbfiles == 1): corruption_warning(self._file_name) @@ -108,7 +111,7 @@ class dblite: def sync(self): self._check_writable() f = self._open(self._tmp_name, "wb", self._mode) - self._cPickle_dump(self._dict, f, 1) + self._pickle_dump(self._dict, f, 1) f.close() # Windows doesn't allow renaming if the file exists, so unlink # it first, chmod'ing it to make sure we can do so. On UNIX, we @@ -216,15 +219,15 @@ def _exercise(): assert len(db) == 5 db = open("tmp", "n") assert len(db) == 0 - _open("tmp.dblite", "w") + dblite._open("tmp.dblite", "w") db = open("tmp", "r") - _open("tmp.dblite", "w").write("x") + dblite._open("tmp.dblite", "w").write("x") try: db = open("tmp", "r") - except cPickle.UnpicklingError: + except pickle.UnpicklingError: pass else: - raise RuntimeError, "cPickle exception expected." + raise RuntimeError, "pickle exception expected." global ignore_corrupt_dbfiles ignore_corrupt_dbfiles = 2 db = open("tmp", "r") -- 2.26.2