mirror of
https://github.com/python/cpython.git
synced 2025-12-08 02:08:20 +00:00
_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.)
This commit is contained in:
parent
2de97d398d
commit
93fe564217
1 changed files with 23 additions and 6 deletions
|
|
@ -876,13 +876,30 @@ def _slotnames(cls):
|
||||||
__slots__ attribute to misrepresent their slots after the class is
|
__slots__ attribute to misrepresent their slots after the class is
|
||||||
defined.)
|
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 = []
|
names = []
|
||||||
|
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__:
|
for c in cls.__mro__:
|
||||||
if "__slots__" in c.__dict__:
|
if "__slots__" in c.__dict__:
|
||||||
names += [name for name in c.__dict__["__slots__"]
|
names += [name for name in c.__dict__["__slots__"]
|
||||||
if name not in ("__dict__", "__weakref__")]
|
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
|
return names
|
||||||
|
|
||||||
def _keep_alive(x, memo):
|
def _keep_alive(x, memo):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue