[Zope3-checkins] SVN: Zope3/trunk/src/zope/i18n/locales/ Performance improvements to the locale inheritance code. We are using

Stephan Richter srichter at cosmos.phy.tufts.edu
Sat Jun 26 15:15:34 EDT 2004


Log message for revision 25993:
Performance improvements to the locale inheritance code. We are using 
__getattr__ instead of __getattribute__ now.
 



-=-
Modified: Zope3/trunk/src/zope/i18n/locales/__init__.py
===================================================================
--- Zope3/trunk/src/zope/i18n/locales/__init__.py	2004-06-25 23:15:00 UTC (rev 25992)
+++ Zope3/trunk/src/zope/i18n/locales/__init__.py	2004-06-26 19:15:34 UTC (rev 25993)
@@ -102,7 +102,6 @@
         self.script = script
         self.territory = territory
         self.variant = variant
-        self.version = None
 
     def __repr__(self):
         """See zope.i18n.interfaces.ILocaleIdentity
@@ -173,18 +172,9 @@
       >>> locale.displayNames.keys
       ['fu', 'bahr']
     """
-
     implements(ILocaleDisplayNames)
 
-    def __init__(self):
-        """Initialize object."""
-        self.languages = None
-        self.scripts = None
-        self.territories = None
-        self.keys = None
-        self.types = None
 
-
 class LocaleTimeZone(object):
     """Specifies one of the timezones of a specific locale.
 
@@ -203,8 +193,6 @@
       >>> tz.cities
       ['Berlin']
     """
-    
-
     implements(ILocaleTimeZone)
 
     def __init__(self, type):
@@ -222,7 +210,6 @@
     itself is often not useful, since other calendar data is required to use
     the specified pattern for formatting and parsing.
     """
-    
     implements(ILocaleFormat)
 
     def __init__(self, type=None):
@@ -231,6 +218,7 @@
         self.displayName = u''
         self.pattern = u''
 
+
 class LocaleFormatLength(AttributeInheritance):
     """Specifies one of the format lengths of a specific quantity, like
     numbers, dates, times and datetimes."""
@@ -241,7 +229,6 @@
         """Initialize the object."""
         self.type = type
         self.default = None
-        self.formats = None
 
 
 class LocaleCalendar(AttributeInheritance):
@@ -302,39 +289,18 @@
 
       >>> root.am = u'AM'
       >>> root.pm = u'PM'
-      >>> locale.am = None
       >>> locale.pm = u'nachm.'
       >>> locale.pm
       u'nachm.'
       >>> locale.am
       u'AM'
     """
-
     implements(ILocaleCalendar)
     
     def __init__(self, type):
         """Initialize the object."""
         self.type = type
-        # See zope.i18n.interfaces.ILocaleCalendar
-        # I am initializing all attributes with None, so that the inheriting
-        # mechanism can get the entire dictionary from the higher-up locale,
-        # instead of searching for each key from the beginning.
-        self.months = None
-        self.days = None
-        self.week = None
-        self.am = None
-        self.pm = None
-        self.eras = None
 
-        self.defaultDateFormat = None
-        self.dateFormats = None
-
-        self.defaultTimeFormat = None
-        self.timeFormats = None
-
-        self.defaultDateTimeFormat = None
-        self.dateTimeFormats = None
-
     def getMonthNames(self):
         """See zope.i18n.interfaces.ILocaleCalendar"""
         return [self.months.get(type, (None, None))[0] for type in range(1, 13)]
@@ -470,16 +436,8 @@
 
       
     """
-
     implements(ILocaleDates)
 
-
-    def __init__(self):
-        # See zope.i18n.interfaces.ILocaleCalendar
-        self.localizedPatternChars = None
-        self.calendars = None
-        self.timezones = None
-
     def getFormatter(self, category, length=None, name=None,
                      calendar=u'gregorian'):
         """See zope.i18n.interfaces.locales.ILocaleDates"""
@@ -539,7 +497,7 @@
 class LocaleNumbers(AttributeInheritance):
     """Implementation of ILocaleCurrency including inheritance support.
 
-    Examples::
+`    Examples::
 
       >>> numbers = LocaleNumbers()
       >>> numbers.symbols = {
@@ -612,25 +570,6 @@
     """
     implements(ILocaleNumbers)
 
-    def __init__(self):
-        """Initialize object."""
-        # See zope.i18n.interfaces.ILocaleNumbers    
-        self.symbols = None
-
-        self.defaultDecimalFormat = None
-        self.decimalFormats = None
-
-        self.defaultScientificFormat = None
-        self.scientificFormats = None
-
-        self.defaultPercentFormat = None
-        self.percentFormats = None
-
-        self.defaultCurrencyFormat = None
-        self.currencyFormats = None
-        self.currencies = None
-
-
     def getFormatter(self, category, length=None, name=None):
         """See zope.i18n.interfaces.locales.ILocaleNumbers"""
         assert category in (u'decimal', u'percent', u'scientific', u'currency')
@@ -654,15 +593,10 @@
 
 class Locale(AttributeInheritance):
     """Implementation of the ILocale interface."""
-
     implements(ILocale)
 
     def __init__(self, id):
         self.id = id
-        self.displayNames = None
-        self.dates = None
-        self.numbers = None
-        self.delimiters = None
 
     def getLocaleID(self):
         """Return the locale id."""

Modified: Zope3/trunk/src/zope/i18n/locales/inheritance.py
===================================================================
--- Zope3/trunk/src/zope/i18n/locales/inheritance.py	2004-06-25 23:15:00 UTC (rev 25992)
+++ Zope3/trunk/src/zope/i18n/locales/inheritance.py	2004-06-26 19:15:34 UTC (rev 25993)
@@ -53,11 +53,11 @@
 
 
 class AttributeInheritance(Inheritance):
-    """Implementation of locale inheritance for attributes.
+    r"""Implementation of locale inheritance for attributes.
 
     Example::
 
-      >>> from zope.i18n.locales.tests.test_docstrings import \\
+      >>> from zope.i18n.locales.tests.test_docstrings import \
       ...     LocaleInheritanceStub
 
       >>> root = LocaleInheritanceStub()
@@ -67,10 +67,8 @@
       >>> root.data2.attr = 'value2' 
 
       >>> locale = LocaleInheritanceStub(root)
-      >>> locale.data = None
       >>> locale.attr = 'foo value'
       >>> locale.data2 = AttributeInheritance()
-      >>> locale.data2.attr = None
 
       Here is an attribute lookup directly from the locale ...
 
@@ -83,12 +81,28 @@
 
       >>> locale.data2.attr
       'value2'
+
+      Once we have looked up a particular attribute, it should be cached,
+      i.e. exist in the dictionary of this inheritance object.
+
+      >>> 'attr' in locale.data2.__dict__
+      True
+      >>> locale.data2.__dict__['attr']
+      'value2'
+
+      Make sure that None can be assigned as value as well.
+
+      >>> locale.data2.attr = None
+      >>> locale.data2.attr is None
+      True
     """
 
     implements(IAttributeInheritance)
 
     def __setattr__(self, name, value):
         """See zope.i18n.interfaces.locales.ILocaleInheritance"""
+        # If we have a value that can also inherit data from other locales, we
+        # set its parent and name, so that we know how to get to it. 
         if (ILocaleInheritance.providedBy(value) and 
             not name.startswith('__')):
             value.__parent__ = self
@@ -96,20 +110,27 @@
         super(AttributeInheritance, self).__setattr__(name, value)
 
 
-    def __getattribute__(self, name):
+    def __getattr__(self, name):
         """See zope.i18n.interfaces.locales.ILocaleInheritance"""
-        if not name.startswith('__') and name != 'getInheritedSelf':
-            dict = self.__dict__
-            if dict.has_key(name) and dict[name] is None:
-                try:
-                    selfUp = self.getInheritedSelf()
-                except NoParentException:
-                    # There was simply no parent anymore, so let's go the
-                    # usual way
-                    pass
-                else:
-                    return selfUp.__getattribute__(name)
-        return super(AttributeInheritance, self).__getattribute__(name)
+        try:
+            selfUp = self.getInheritedSelf()
+        except NoParentException:
+            # There was simply no parent anymore, so let's raise an error
+            # for good
+            raise AttributeError, \
+                "'%s' object (or any of its parents) has no attribute '%s'" %(
+                self.__class__.__name__, name)
+        else:
+            value = getattr(selfUp, name)
+            # Since a locale hierarchy never changes after startup, we can
+            # cache the value locally, saving the time to ever look it up
+            # again.
+            # Note that we cannot use the normal setattr function, since
+            # __setattr__ of this class tries to assign a parent and name,
+            # which we do not want to override.
+            super(AttributeInheritance, self).__setattr__(name, value)
+            return value
+        
 
 
 class InheritingDictionary(Inheritance, dict):



More information about the Zope3-Checkins mailing list