From c4b13e37c7d9abec69e9d4ef78b55b241c25b1d0 Mon Sep 17 00:00:00 2001 From: Steven Knight Date: Sat, 15 Nov 2008 22:59:25 +0000 Subject: Speed up Node.FS.EntryProxy.__getattr__() by not spending cycles 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) --- src/CHANGES.txt | 5 +++++ src/engine/SCons/Node/FS.py | 32 ++++++++++++++++++++++---------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 5abdb29..7fd865e 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -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. diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 5c5aac1..03275da 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -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: - # "" - # 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) -- cgit v0.12