Don't swallow the AttributeError for an expansion like .bak.
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sun, 9 Nov 2003 03:11:32 +0000 (03:11 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sun, 9 Nov 2003 03:11:32 +0000 (03:11 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@840 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/CHANGES.txt
src/engine/SCons/Node/FS.py
src/engine/SCons/Node/FSTests.py
src/engine/SCons/Sig/MD5.py
src/engine/SCons/Sig/MD5Tests.py

index 4021c8343289d99a53992de08b5970a7d272908c..c30d6c8c0a317f7445c937a2f7c5d885445f1e87 100644 (file)
@@ -8,6 +8,18 @@
 
 
 
+RELEASE 0.95 - XXX
+
+  From Steven Knight:
+
+  - Fix EnsureSConsVersion() so it checks against the SCons version,
+    not the Python version, on Pythons with sys.version_info.
+
+  - Don't swallow the AttributeError when someone uses an expansion like
+    $TARGET.bak, so we can supply a more informative error message.
+
+
+
 RELEASE 0.94 - Fri, 07 Nov 2003 05:29:48 -0600
 
   From Hartmut Goebel:
index cffa2b5dbf8f0ed4cf8e3a97a13491860ffd4987..bce5364dfdbd3014a110db98ff24f6b5495403ad 100644 (file)
@@ -290,7 +290,13 @@ class EntryProxy(SCons.Util.Proxy):
         try:
             return self.dictSpecialAttrs[name](self)
         except KeyError:
-            return SCons.Util.Proxy.__getattr__(self, name)
+            try:
+                attr = SCons.Util.Proxy.__getattr__(self, name)
+            except AttributeError:
+                entry = self.get()
+                classname = string.split(str(entry.__class__), '.')[-1]
+                raise AttributeError, "%s instance '%s' has no attribute '%s'" % (classname, entry.name, name)
+            return attr
 
 class Base(SCons.Node.Node):
     """A generic class for file system entries.  This class is for
index 2237959e326d027d6e950751d20e5906b73b4112..54c6523b9b34f13606fe7537d1de5d194766c3c8 100644 (file)
@@ -1716,6 +1716,32 @@ class SpecialAttrTestCase(unittest.TestCase):
             assert f.posix.for_signature() == 'baz.blat_posix', \
                    f.posix.for_signature()
 
+        # Check that attempts to access non-existent attributes of the
+        # subst proxy generate the right exceptions and messages.
+        caught = None
+        try:
+            fs.Dir('ddd').get_subst_proxy().no_such_attr
+        except AttributeError, e:
+            assert str(e) == "Dir instance 'ddd' has no attribute 'no_such_attr'", e
+            caught = 1
+        assert caught, "did not catch expected AttributeError"
+
+        caught = None
+        try:
+            fs.Entry('eee').get_subst_proxy().no_such_attr
+        except AttributeError, e:
+            assert str(e) == "Entry instance 'eee' has no attribute 'no_such_attr'", e
+            caught = 1
+        assert caught, "did not catch expected AttributeError"
+
+        caught = None
+        try:
+            fs.File('fff').get_subst_proxy().no_such_attr
+        except AttributeError, e:
+            assert str(e) == "File instance 'fff' has no attribute 'no_such_attr'", e
+            caught = 1
+        assert caught, "did not catch expected AttributeError"
+
         fs.BuildDir('foo', 'baz')
 
         assert str(f.srcpath) == os.path.normpath('baz/bar/baz.blat'), str(f.srcpath)
index c50dbb7f416b784886ef43ef93db56aa6d084617..21cb24c086fc866508f202ecfcb8f07533e9f4f8 100644 (file)
@@ -79,10 +79,10 @@ def signature(obj):
     """Generate a signature for an object
     """
     try:
-        contents = str(obj.get_contents())
+        gc = obj.get_contents
     except AttributeError:
         raise AttributeError, "unable to fetch contents of '%s'" % str(obj)
-    return hexdigest(md5.new(contents).digest())
+    return hexdigest(md5.new(str(gc())).digest())
 
 def to_string(signature):
     """Convert a signature to a string"""
index 6285e87ee251eced0c6b6dec79f9a7b55d795034..67bdfc9b60b0eee3d666e93a99b84fd1cc4354de 100644 (file)
@@ -88,6 +88,19 @@ class MD5TestCase(unittest.TestCase):
         else:
             raise AttributeError, "unexpected get_contents() attribute"
 
+        # Make sure we don't eat AttributeErrors raised internally
+        # by the get_contents() method (or anything it calls).
+        caught = None
+        try:
+            class xxx:
+                def get_contents(self):
+                    raise AttributeError, "internal AttributeError"
+            signature(xxx())
+        except AttributeError, e:
+            assert str(e) == "internal AttributeError", e
+            caught = 1
+        assert caught, "did not catch expected AttributeError"
+
     def test_to_string(self):
         assert '698d51a19d8a121ce581499d7b701668' == to_string('698d51a19d8a121ce581499d7b701668')