From b30167aa70d1b92581664a418a60a860c4a88fff Mon Sep 17 00:00:00 2001
From: Pierre LALET <pierre.lalet@cea.fr>
Date: Sun, 17 Jan 2016 14:02:03 +0100
Subject: [PATCH] Add a static __all_slots__ attribute to improve performances

---
 scapy/base_classes.py |  6 ++++++
 scapy/packet.py       | 12 ++----------
 2 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/scapy/base_classes.py b/scapy/base_classes.py
index c89169f1..4f4dc116 100644
--- a/scapy/base_classes.py
+++ b/scapy/base_classes.py
@@ -181,6 +181,12 @@ class Packet_metaclass(type):
         if "name" in dct:
             dct["_name"] = dct.pop("name")
         newcls = super(Packet_metaclass, cls).__new__(cls, name, bases, dct)
+        newcls.__all_slots__ = set(
+            attr
+            for cls in newcls.__mro__ if hasattr(cls, "__slots__")
+            for attr in cls.__slots__
+        )
+
         if hasattr(newcls, "aliastypes"):
             newcls.aliastypes = [newcls] + newcls.aliastypes
         else:
diff --git a/scapy/packet.py b/scapy/packet.py
index 2a87717a..c1374d2a 100644
--- a/scapy/packet.py
+++ b/scapy/packet.py
@@ -202,17 +202,9 @@ class Packet(BasePacket):
         else:
             self.payload.setfieldval(attr,val)
 
-    def attr_in_slots(self, attr):
-        """Return True iff `attr` belongs to the `__slots__` list of
-        this class or any parent class.
-
-        """
-        return any(attr in cls.__slots__ for cls in self.__class__.__mro__
-                   if hasattr(cls, "__slots__"))
-
     def __setattr__(self, attr, val):
         if isinstance(self, Packet):
-            if self.attr_in_slots(attr):
+            if attr in self.__all_slots__:
                 return object.__setattr__(self, attr, val)
             try:
                 return self.setfieldval(attr,val)
@@ -237,7 +229,7 @@ class Packet(BasePacket):
         if isinstance(self, Packet):
             if attr == "payload":
                 return self.remove_payload()
-            if self.attr_in_slots(attr):
+            if attr in self.__all_slots__:
                 return object.__delattr__(self, attr)
             try:
                 return self.delfieldval(attr)
-- 
GitLab