summaryrefslogtreecommitdiffstats
path: root/SCons/dblite.py
diff options
context:
space:
mode:
authorMats Wichmann <mats@linux.com>2020-09-10 18:56:27 (GMT)
committerMats Wichmann <mats@linux.com>2020-11-30 19:26:59 (GMT)
commitffbc4a40573fad1ccd6685d896af930208a769c1 (patch)
treed6e449f1d2ce6f93770689ba44c115899b157157 /SCons/dblite.py
parent64a80e530b0caef9763eb67bd770dd9c8925ea18 (diff)
downloadSCons-ffbc4a40573fad1ccd6685d896af930208a769c1.zip
SCons-ffbc4a40573fad1ccd6685d896af930208a769c1.tar.gz
SCons-ffbc4a40573fad1ccd6685d896af930208a769c1.tar.bz2
dblite tweaks
use os.replace instead of the dance around os.rename which behaves differently on Windows. use True/False for flags for clarity. Fix some PEP8 warnings. Signed-off-by: Mats Wichmann <mats@linux.com>
Diffstat (limited to 'SCons/dblite.py')
-rw-r--r--SCons/dblite.py77
1 files changed, 28 insertions, 49 deletions
diff --git a/SCons/dblite.py b/SCons/dblite.py
index c6943e3..f744c9a 100644
--- a/SCons/dblite.py
+++ b/SCons/dblite.py
@@ -33,20 +33,20 @@ import time
from SCons.compat import PICKLE_PROTOCOL
-keep_all_files = 00000
-ignore_corrupt_dbfiles = 0
+KEEP_ALL_FILES = False
+IGNORE_CORRUPT_DBFILES = False
def corruption_warning(filename):
- print("Warning: Discarding corrupt database:", filename)
-
+ """Local warning for corrupt db.
-dblite_suffix = '.dblite'
+ Used for self-tests. SCons overwrites this with a
+ different warning function in SConsign.py.
+ """
+ print("Warning: Discarding corrupt database:", filename)
-# TODO: Does commenting this out break switching from py2/3?
-# if bytes is not str:
-# dblite_suffix += '.p3'
-tmp_suffix = '.tmp'
+DBLITE_SUFFIX = '.dblite'
+TMP_SUFFIX = '.tmp'
class dblite:
@@ -66,15 +66,13 @@ class dblite:
_open = open
_pickle_dump = staticmethod(pickle.dump)
_pickle_protocol = PICKLE_PROTOCOL
- _os_chmod = os.chmod
try:
_os_chown = os.chown
except AttributeError:
_os_chown = None
- _os_rename = os.rename
- _os_unlink = os.unlink
+ _os_replace = os.replace
_shutil_copyfile = shutil.copyfile
_time_time = time.time
@@ -84,18 +82,18 @@ class dblite:
flag = "r"
base, ext = os.path.splitext(file_base_name)
- if ext == dblite_suffix:
+ if ext == DBLITE_SUFFIX:
# There's already a suffix on the file name, don't add one.
self._file_name = file_base_name
- self._tmp_name = base + tmp_suffix
+ self._tmp_name = base + TMP_SUFFIX
else:
- self._file_name = file_base_name + dblite_suffix
- self._tmp_name = file_base_name + tmp_suffix
+ self._file_name = file_base_name + DBLITE_SUFFIX
+ self._tmp_name = file_base_name + TMP_SUFFIX
self._flag = flag
self._mode = mode
self._dict = {}
- self._needs_sync = 00000
+ self._needs_sync = False
if self._os_chown is not None and (os.geteuid() == 0 or os.getuid() == 0):
# running as root; chown back to current owner/group when done
@@ -103,7 +101,7 @@ class dblite:
statinfo = os.stat(self._file_name)
self._chown_to = statinfo.st_uid
self._chgrp_to = statinfo.st_gid
- except OSError as e:
+ except OSError:
# db file doesn't exist yet.
# Check os.environ for SUDO_UID, use if set
self._chown_to = int(os.environ.get('SUDO_UID', -1))
@@ -128,15 +126,12 @@ class dblite:
f.close()
if len(p) > 0:
try:
- if bytes is not str:
- self._dict = pickle.loads(p, encoding='bytes')
- else:
- self._dict = pickle.loads(p)
+ self._dict = pickle.loads(p, encoding='bytes')
except (pickle.UnpicklingError, EOFError, KeyError):
# Note how we catch KeyErrors too here, which might happen
# when we don't have cPickle available (default pickle
# throws it).
- if ignore_corrupt_dbfiles:
+ if IGNORE_CORRUPT_DBFILES:
corruption_warning(self._file_name)
else:
raise
@@ -150,29 +145,16 @@ class dblite:
def sync(self):
self._check_writable()
- f = self._open(self._tmp_name, "wb", self._mode)
- self._pickle_dump(self._dict, f, self._pickle_protocol)
- 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
- # may not be able to chmod the file if it's owned by someone else
- # (e.g. from a previous run as root). We should still be able to
- # unlink() the file if the directory's writable, though, so ignore
- # any OSError exception thrown by the chmod() call.
- try:
- self._os_chmod(self._file_name, 0o777)
- except OSError:
- pass
- self._os_unlink(self._file_name)
- self._os_rename(self._tmp_name, self._file_name)
+ with self._open(self._tmp_name, "wb", self._mode) as f:
+ self._pickle_dump(self._dict, f, self._pickle_protocol)
+ self._os_replace(self._tmp_name, self._file_name)
if self._os_chown is not None and self._chown_to > 0: # don't chown to root or -1
try:
self._os_chown(self._file_name, self._chown_to, self._chgrp_to)
except OSError:
pass
- self._needs_sync = 00000
- if keep_all_files:
+ self._needs_sync = False
+ if KEEP_ALL_FILES:
self._shutil_copyfile(
self._file_name,
self._file_name + "_" + str(int(self._time_time())))
@@ -194,7 +176,7 @@ class dblite:
raise TypeError("value `%s' must be a bytes but is %s" % (value, type(value)))
self._dict[key] = value
- self._needs_sync = 0o001
+ self._needs_sync = True
def keys(self):
return list(self._dict.keys())
@@ -205,11 +187,8 @@ class dblite:
def __contains__(self, key):
return key in self._dict
- def iterkeys(self):
- # Wrapping name in () prevents fixer from "fixing" this
- return (self._dict.iterkeys)()
-
- __iter__ = iterkeys
+ def __iter__(self):
+ return iter(self._dict)
def __len__(self):
return len(self._dict)
@@ -278,8 +257,8 @@ def _exercise():
else:
raise RuntimeError("pickle exception expected.")
- global ignore_corrupt_dbfiles
- ignore_corrupt_dbfiles = 2
+ global IGNORE_CORRUPT_DBFILES
+ IGNORE_CORRUPT_DBFILES = True
db = open("tmp", "r")
assert len(db) == 0, len(db)
os.unlink("tmp.dblite")