diff --git a/lib/objects.py b/lib/objects.py
index 76ca042c4fc8bb353654db5514707b3aceae0e7a..7fb7d5be6ed872ddb90cb71eccb4497749992d27 100644
--- a/lib/objects.py
+++ b/lib/objects.py
@@ -109,16 +109,27 @@ class ConfigObject(object):
       setattr(self, k, v)
 
   def __getattr__(self, name):
-    if name not in self.__slots__:
+    if name not in self._all_slots():
       raise AttributeError("Invalid object attribute %s.%s" %
                            (type(self).__name__, name))
     return None
 
   def __setstate__(self, state):
+    slots = self._all_slots()
     for name in state:
-      if name in self.__slots__:
+      if name in slots:
         setattr(self, name, state[name])
 
+  @classmethod
+  def _all_slots(cls):
+    """Compute the list of all declared slots for a class.
+
+    """
+    slots = []
+    for parent in cls.__mro__:
+      slots.extend(getattr(parent, "__slots__", []))
+    return slots
+
   def ToDict(self):
     """Convert to a dict holding only standard python types.
 
@@ -130,7 +141,7 @@ class ConfigObject(object):
 
     """
     result = {}
-    for name in self.__slots__:
+    for name in self._all_slots():
       value = getattr(self, name, None)
       if value is not None:
         result[name] = value
diff --git a/lib/opcodes.py b/lib/opcodes.py
index 3aed41e0cd75e2bb41958bbfd9b37e8f7fc75da8..2520101dc462ab5ce2aed4fd47b95f8047bcf819 100644
--- a/lib/opcodes.py
+++ b/lib/opcodes.py
@@ -52,8 +52,9 @@ class BaseOpCode(object):
     __slots__ attribute for this class.
 
     """
+    slots = self._all_slots()
     for key in kwargs:
-      if key not in self.__slots__:
+      if key not in slots:
         raise TypeError("Object %s doesn't support the parameter '%s'" %
                         (self.__class__.__name__, key))
       setattr(self, key, kwargs[key])
@@ -69,7 +70,7 @@ class BaseOpCode(object):
 
     """
     state = {}
-    for name in self.__slots__:
+    for name in self._all_slots():
       if hasattr(self, name):
         state[name] = getattr(self, name)
     return state
@@ -88,13 +89,23 @@ class BaseOpCode(object):
       raise ValueError("Invalid data to __setstate__: expected dict, got %s" %
                        type(state))
 
-    for name in self.__slots__:
+    for name in self._all_slots():
       if name not in state:
         delattr(self, name)
 
     for name in state:
       setattr(self, name, state[name])
 
+  @classmethod
+  def _all_slots(cls):
+    """Compute the list of all declared slots for a class.
+
+    """
+    slots = []
+    for parent in cls.__mro__:
+      slots.extend(getattr(parent, "__slots__", []))
+    return slots
+
 
 class OpCode(BaseOpCode):
   """Abstract OpCode.
diff --git a/tools/cfgshell b/tools/cfgshell
index 57ed0bd7f51a70a4812af8d10cf8e1fbc4b49880..3c53d819b6a7808f85f3b8aed68eb3593b0691fb 100755
--- a/tools/cfgshell
+++ b/tools/cfgshell
@@ -93,7 +93,9 @@ class ConfigShell(cmd.Cmd):
     dirs = []
     entries = []
     if isinstance(obj, objects.ConfigObject):
-      for name in obj.__slots__:
+      # pylint: disable-msg=W0212
+      # yes, we're using a protected member
+      for name in obj._all_slots():
         child = getattr(obj, name, None)
         if isinstance(child, (list, dict, tuple, objects.ConfigObject)):
           dirs.append(name)