]> granicus.if.org Git - python/commitdiff
_slotnames(): this is a fairly expensive calculation. Cache the
authorGuido van Rossum <guido@python.org>
Mon, 3 Feb 2003 19:46:54 +0000 (19:46 +0000)
committerGuido van Rossum <guido@python.org>
Mon, 3 Feb 2003 19:46:54 +0000 (19:46 +0000)
outcome as __slotnames__ on the class.  (Like __slots__, it's not safe
to ask for this as an attribute -- you must look for it in the
specific class's __dict__.  But it must be set using attribute
notation, because __dict__ is a read-only proxy.)

Lib/pickle.py

index 05772b0e2570dc61babf219f13d73bae26f8f12d..870d94d16f3f24a742253ca1e8d4594b1e30dabb 100644 (file)
@@ -876,13 +876,30 @@ def _slotnames(cls):
     __slots__ attribute to misrepresent their slots after the class is
     defined.)
     """
-    if not hasattr(cls, "__slots__"):
-        return []
+
+    # Get the value from a cache in the class if possible
+    names = cls.__dict__.get("__slotnames__")
+    if names is not None:
+        return names
+
+    # Not cached -- calculate the value
     names = []
-    for c in cls.__mro__:
-        if "__slots__" in c.__dict__:
-            names += [name for name in c.__dict__["__slots__"]
-                           if name not in ("__dict__", "__weakref__")]
+    if not hasattr(cls, "__slots__"):
+        # This class has no slots
+        pass
+    else:
+        # Slots found -- gather slot names from all base classes
+        for c in cls.__mro__:
+            if "__slots__" in c.__dict__:
+                names += [name for name in c.__dict__["__slots__"]
+                               if name not in ("__dict__", "__weakref__")]
+
+    # Cache the outcome in the class if at all possible
+    try:
+        cls.__slotnames__ = names
+    except:
+        pass # But don't die if we can't
+
     return names
 
 def _keep_alive(x, memo):