Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 93fe564

Browse files
committed
_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.)
1 parent 2de97d3 commit 93fe564

1 file changed

Lines changed: 23 additions & 6 deletions

File tree

Lib/pickle.py

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -876,13 +876,30 @@ class found there. (This assumes classes don't modify their
876876
__slots__ attribute to misrepresent their slots after the class is
877877
defined.)
878878
"""
879-
if not hasattr(cls, "__slots__"):
880-
return []
879+
880+
# Get the value from a cache in the class if possible
881+
names = cls.__dict__.get("__slotnames__")
882+
if names is not None:
883+
return names
884+
885+
# Not cached -- calculate the value
881886
names = []
882-
for c in cls.__mro__:
883-
if "__slots__" in c.__dict__:
884-
names += [name for name in c.__dict__["__slots__"]
885-
if name not in ("__dict__", "__weakref__")]
887+
if not hasattr(cls, "__slots__"):
888+
# This class has no slots
889+
pass
890+
else:
891+
# Slots found -- gather slot names from all base classes
892+
for c in cls.__mro__:
893+
if "__slots__" in c.__dict__:
894+
names += [name for name in c.__dict__["__slots__"]
895+
if name not in ("__dict__", "__weakref__")]
896+
897+
# Cache the outcome in the class if at all possible
898+
try:
899+
cls.__slotnames__ = names
900+
except:
901+
pass # But don't die if we can't
902+
886903
return names
887904

888905
def _keep_alive(x, memo):

0 commit comments

Comments
 (0)