summaryrefslogtreecommitdiffstats
path: root/SCons/Node
diff options
context:
space:
mode:
authorWilliam Deegan <bill@baddogconsulting.com>2020-12-14 17:20:08 (GMT)
committerGitHub <noreply@github.com>2020-12-14 17:20:08 (GMT)
commit8d140262ec73dda6738dbafb4053436405c37458 (patch)
tree690cdfbc87d31e80e398775f17a07ffe1fb4f5f3 /SCons/Node
parent68e4dc36483ad8c0c1757394b6380410ed665e10 (diff)
parent97dbf8d22b518a8f67cf670f8e3449990f3f5813 (diff)
downloadSCons-8d140262ec73dda6738dbafb4053436405c37458.zip
SCons-8d140262ec73dda6738dbafb4053436405c37458.tar.gz
SCons-8d140262ec73dda6738dbafb4053436405c37458.tar.bz2
Merge branch 'master' into topic/grossag/newhashes
Diffstat (limited to 'SCons/Node')
-rw-r--r--SCons/Node/FS.py42
-rw-r--r--SCons/Node/FSTests.py17
-rw-r--r--SCons/Node/NodeTests.py2
-rw-r--r--SCons/Node/Python.py3
-rw-r--r--SCons/Node/__init__.py10
5 files changed, 42 insertions, 32 deletions
diff --git a/SCons/Node/FS.py b/SCons/Node/FS.py
index a1b1fa9..4eb658e 100644
--- a/SCons/Node/FS.py
+++ b/SCons/Node/FS.py
@@ -2693,11 +2693,13 @@ class File(Base):
def scanner_key(self):
return self.get_suffix()
- def get_contents(self):
+ def get_contents(self) -> bytes:
+ """Return the contents of the file as bytes."""
return SCons.Node._get_contents_map[self._func_get_contents](self)
- def get_text_contents(self):
- """
+ def get_text_contents(self) -> str:
+ """Return the contents of the file in text form.
+
This attempts to figure out what the encoding of the text is
based upon the BOM bytes, and then decodes the contents so that
it's a valid python string.
@@ -2723,13 +2725,12 @@ class File(Base):
except UnicodeDecodeError as e:
return contents.decode('utf-8', errors='backslashreplace')
-
- def get_content_hash(self):
+ def get_content_hash(self) -> str:
"""
Compute and return the hash for this file.
"""
if not self.rexists():
- return hash_signature('')
+ return hash_signature(SCons.Util.NOFILE)
fname = self.rfile().get_abspath()
try:
cs = hash_file_signature(fname, chunksize=File.hash_chunksize)
@@ -2740,7 +2741,7 @@ class File(Base):
return cs
@SCons.Memoize.CountMethodCall
- def get_size(self):
+ def get_size(self) -> int:
try:
return self._memo['get_size']
except KeyError:
@@ -2749,14 +2750,14 @@ class File(Base):
if self.rexists():
size = self.rfile().getsize()
else:
- size = 0
+ # sentinel value for doesn't exist, even in repository
+ size = -1
self._memo['get_size'] = size
-
return size
@SCons.Memoize.CountMethodCall
- def get_timestamp(self):
+ def get_timestamp(self) -> int:
try:
return self._memo['get_timestamp']
except KeyError:
@@ -2768,7 +2769,6 @@ class File(Base):
timestamp = 0
self._memo['get_timestamp'] = timestamp
-
return timestamp
convert_copy_attrs = [
@@ -2780,7 +2780,6 @@ class File(Base):
'ninfo',
]
-
convert_sig_attrs = [
'bsourcesigs',
'bimplicitsigs',
@@ -3173,7 +3172,7 @@ class File(Base):
# SIGNATURE SUBSYSTEM
#
- def get_max_drift_csig(self):
+ def get_max_drift_csig(self) -> str:
"""
Returns the content signature currently stored for this node
if it's been unmodified longer than the max_drift value, or the
@@ -3199,15 +3198,8 @@ class File(Base):
return None
- def get_csig(self):
- """
- Generate a node's content signature, the digested signature
- of its content.
-
- node - the node
- cache - alternate node to use for the signature cache
- returns - the content signature
- """
+ def get_csig(self) -> str:
+ """Generate a node's content signature."""
ninfo = self.get_ninfo()
try:
return ninfo.csig
@@ -3216,9 +3208,11 @@ class File(Base):
csig = self.get_max_drift_csig()
if csig is None:
-
try:
- if self.get_size() < File.hash_chunksize:
+ size = self.get_size()
+ if size == -1:
+ contents = SCons.Util.NOFILE
+ elif size < File.hash_chunksize:
contents = self.get_contents()
else:
csig = self.get_content_hash()
diff --git a/SCons/Node/FSTests.py b/SCons/Node/FSTests.py
index 457d199..d2a1ebe 100644
--- a/SCons/Node/FSTests.py
+++ b/SCons/Node/FSTests.py
@@ -2686,8 +2686,11 @@ class FileTestCase(_tempdirTestCase):
print("%15s -> csig:%s" % (i3.name, i3.ninfo.csig))
print("%15s -> csig:%s" % (i4.name, i4.ninfo.csig))
- self.assertEqual(i2.name, i2.ninfo.csig,
- "gamma.h's fake csig should equal gamma.h but equals:%s" % i2.ninfo.csig)
+ self.assertEqual(
+ i2.name,
+ i2.ninfo.csig,
+ "gamma.h's fake csig should equal gamma.h but equals:%s" % i2.ninfo.csig,
+ )
class GlobTestCase(_tempdirTestCase):
@@ -3673,7 +3676,8 @@ class CacheDirTestCase(unittest.TestCase):
f9 = fs.File('f9')
r = f9.get_cachedir_csig()
- assert r == 'd41d8cd98f00b204e9800998ecf8427e', r
+ exsig = SCons.Util.MD5signature(SCons.Util.NOFILE)
+ assert r == exsig, r
class clearTestCase(unittest.TestCase):
@@ -3722,6 +3726,13 @@ class clearTestCase(unittest.TestCase):
assert not f.exists()
assert not f.rexists()
assert str(f) == test.workpath('f'), str(f)
+ # Now verify clear() resets optional File-specific attributes
+ optional_attrs = ['cachedir_csig', 'cachesig', 'contentsig']
+ for attr in optional_attrs:
+ setattr(f, attr, 'xyz')
+ f.clear()
+ for attr in optional_attrs:
+ assert not hasattr(f, attr), attr
class disambiguateTestCase(unittest.TestCase):
diff --git a/SCons/Node/NodeTests.py b/SCons/Node/NodeTests.py
index 6e240d4..29a3887 100644
--- a/SCons/Node/NodeTests.py
+++ b/SCons/Node/NodeTests.py
@@ -1297,6 +1297,7 @@ class NodeTestCase(unittest.TestCase):
n.includes = 'testincludes'
n.Tag('found_includes', {'testkey':'testvalue'})
n.implicit = 'testimplicit'
+ n.cached = 1
x = MyExecutor()
n.set_executor(x)
@@ -1304,6 +1305,7 @@ class NodeTestCase(unittest.TestCase):
n.clear()
assert n.includes is None, n.includes
+ assert n.cached == 0, n.cached
assert x.cleaned_up
def test_get_subst_proxy(self):
diff --git a/SCons/Node/Python.py b/SCons/Node/Python.py
index 0eab05c..738682c 100644
--- a/SCons/Node/Python.py
+++ b/SCons/Node/Python.py
@@ -138,7 +138,8 @@ class Value(SCons.Node.Node):
###TODO: something reasonable about universal newlines
contents = str(self.value)
for kid in self.children(None):
- contents = contents + kid.get_contents().decode()
+ # Get csig() value of child as this is more efficent
+ contents = contents + kid.get_csig()
return contents
def get_contents(self) -> bytes:
diff --git a/SCons/Node/__init__.py b/SCons/Node/__init__.py
index 4a53c10..745875d 100644
--- a/SCons/Node/__init__.py
+++ b/SCons/Node/__init__.py
@@ -865,10 +865,12 @@ class Node(object, metaclass=NoSlotsPyPy):
self.clear_memoized_values()
self.ninfo = self.new_ninfo()
self.executor_cleanup()
- try:
- delattr(self, '_calculated_sig')
- except AttributeError:
- pass
+ for attr in ['cachedir_csig', 'cachesig', 'contentsig']:
+ try:
+ delattr(self, attr)
+ except AttributeError:
+ pass
+ self.cached = 0
self.includes = None
def clear_memoized_values(self):