diff options
author | Guido van Rossum <guido@python.org> | 2003-02-03 19:46:54 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2003-02-03 19:46:54 (GMT) |
commit | 93fe5642175ce5b7771c3b6e32f820b4788604e9 (patch) | |
tree | c3ca8087609373c676c816b548e748b70607b750 | |
parent | 2de97d398d5a66307228b1269812da94e65e20a3 (diff) | |
download | cpython-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.py | 29 |
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): |