Speed up Node.FS.EntryProxy.__getattr__() by not spending cycles
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sat, 15 Nov 2008 22:59:25 +0000 (22:59 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sat, 15 Nov 2008 22:59:25 +0000 (22:59 +0000)
generating an AttributeError exception message that gets ignored most
of the time.  Instead, re-raise an AttributeError subclass that delays
message generation until its __str__() method is actually called.
(Brad Fitzpatrick)

git-svn-id: http://scons.tigris.org/svn/scons/trunk@3785 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/CHANGES.txt
src/engine/SCons/Node/FS.py

index 5abdb2914f5bdd43f3f889a3f0f12bab13afe11d..7fd865e27c2f50575a5de3a939cc70e2cd1b5dac 100644 (file)
@@ -19,6 +19,11 @@ RELEASE 1.X - XXX
 
     - Fix $FORTRANMODDIRPREFIX for the ifort (Intel Fortran) tool.
 
+  From Brad Fitzpatrick:
+
+    - Don't pre-generate an exception message (which will likely be
+      ignored anyway) when an EntryProxy re-raises an AttributeError.
+
   From Ludwig Hähne:
 
     - Handle Java inner classes declared within a method.
index 5c5aac1ae2ef1a0473bf735043b35455a97e8b45..03275da75ddbd65ea723461dbad82f378dfd958f 100644 (file)
@@ -61,6 +61,23 @@ from SCons.Debug import Trace
 
 do_store_info = True
 
+
+class EntryProxyAttributeError(AttributeError):
+    """
+    An AttributeError subclass for recording and displaying the name
+    of the underlying Entry involved in an AttributeError exception.
+    """
+    def __init__(self, entry_proxy, attribute):
+        AttributeError.__init__(self)
+        self.entry_proxy = entry_proxy
+        self.attribute = attribute
+    def __str__(self):
+        entry = self.entry_proxy.get()
+        fmt = "%s instance %s has no attribute %s"
+        return fmt % (entry.__class__.__name__,
+                      repr(entry.name),
+                      repr(self.attribute))
+
 # The max_drift value:  by default, use a cached signature value for
 # any file that's been untouched for more than two days.
 default_max_drift = 2*24*60*60
@@ -483,16 +500,11 @@ class EntryProxy(SCons.Util.Proxy):
         except KeyError:
             try:
                 attr = SCons.Util.Proxy.__getattr__(self, name)
-            except AttributeError:
-                entry = self.get()
-                classname = string.split(str(entry.__class__), '.')[-1]
-                if classname[-2:] == "'>":
-                    # new-style classes report their name as:
-                    #   "<class 'something'>"
-                    # instead of the classic classes:
-                    #   "something"
-                    classname = classname[:-2]
-                raise AttributeError, "%s instance '%s' has no attribute '%s'" % (classname, entry.name, name)
+            except AttributeError, e:
+                # Raise our own AttributeError subclass with an
+                # overridden __str__() method that identifies the
+                # name of the entry that caused the exception.
+                raise EntryProxyAttributeError(self, name)
             return attr
         else:
             return attr_function(self)