Commits

Anonymous committed 489656d

SF bug 1065388: calendar day/month name lookup too slow

__getitem__() methods: compute only the new spellings needed to satisfy
the given indexing object. This is purely an optimization (it should
have no effect on visible semantics).

Comments (0)

Files changed (3)

 # fresh on each call, in case the user changes locale between calls.
 
 class _localized_month:
+
+    _months = [datetime.date(2001, i+1, 1).strftime for i in range(12)]
+    _months.insert(0, lambda x: "")
+
     def __init__(self, format):
         self.format = format
 
     def __getitem__(self, i):
-        data = [datetime.date(2001, j, 1).strftime(self.format)
-                     for j in range(1, 13)]
-        data.insert(0, "")
-        return data[i]
+        funcs = self._months[i]
+        if isinstance(i, slice):
+            return [f(self.format) for f in funcs]
+        else:
+            return funcs(self.format)
 
     def __len__(self):
         return 13
 
 class _localized_day:
+
+    # January 1, 2001, was a Monday.
+    _days = [datetime.date(2001, 1, i+1).strftime for i in range(7)]
+
     def __init__(self, format):
         self.format = format
 
     def __getitem__(self, i):
-        # January 1, 2001, was a Monday.
-        data = [datetime.date(2001, 1, j+1).strftime(self.format)
-                     for j in range(7)]
-        return data[i]
+        funcs = self._days[i]
+        if isinstance(i, slice):
+            return [f(self.format) for f in funcs]
+        else:
+            return funcs(self.format)
 
     def __len__(self):
         return 7

Lib/test/test_calendar.py

             self.assertEqual(len(value), 7)
             self.assertEqual(len(value[:]), 7)
             # ensure they're all unique
-            d = {}
-            for v in value:
-                d[v] = 1
-            self.assertEqual(len(d), 7)
+            self.assertEqual(len(set(value)), 7)
+            # verify it "acts like a sequence" in two forms of iteration
+            self.assertEqual(value[::-1], list(reversed(value)))
 
     def test_months(self):
         for attr in "month_name", "month_abbr":
             self.assertEqual(len(value[:]), 13)
             self.assertEqual(value[0], "")
             # ensure they're all unique
-            d = {}
-            for v in value:
-                d[v] = 1
-            self.assertEqual(len(d), 13)
+            self.assertEqual(len(set(value)), 13)
+            # verify it "acts like a sequence" in two forms of iteration
+            self.assertEqual(value[::-1], list(reversed(value)))
 
 
 class MonthCalendarTestCase(unittest.TestCase):
 - ``doctest``'s new support for adding ``pdb.set_trace()`` calls to
   doctests was broken in a dramatic but shallow way.  Fixed.
 
+- Bug 1065388:  ``calendar``'s ``day_name``, ``day_abbr``, ``month_name``,
+  and ``month_abbr`` attributes emulate sequences of locale-correct
+  spellings of month and day names.  Because the locale can change at
+  any time, the correct spelling is recomputed whenever one of these is
+  indexed.  In the worst case, the index may be a slice object, so these
+  recomputed every day or month name each time they were indexed.  This is
+  much slower than necessary in the usual case, when the index is just an
+  integer.  In that case, only the single spelling needed is recomputed
+  now; and, when the index is a slice object, only the spellings needed
+  by the slice are recomputed now.
+
 - Patch 1061679: Added ``__all__`` to pickletools.py.
 
 Build
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.