summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2003-02-03 19:46:54 (GMT)
committerGuido van Rossum <guido@python.org>2003-02-03 19:46:54 (GMT)
commit93fe5642175ce5b7771c3b6e32f820b4788604e9 (patch)
treec3ca8087609373c676c816b548e748b70607b750
parent2de97d398d5a66307228b1269812da94e65e20a3 (diff)
downloadcpython-93fe5642175ce5b7771c3b6e32f820b4788604e9.zip
cpython-93fe5642175ce5b7771c3b6e32f820b4788604e9.tar.gz
cpython-93fe5642175ce5b7771c3b6e32f820b4788604e9.tar.bz2
_slotnames(): this is a fairly expensive calculation. Cache the
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.)
-rw-r--r--Lib/pickle.py29
1 files changed, 23 insertions, 6 deletions
diff --git a/Lib/pickle.py b/Lib/pickle.py
index 05772b0..870d94d 100644
--- a/Lib/pickle.py
+++ b/Lib/pickle.py
@@ -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):