private static PythonDictionary?GetInitializedSlotValues(object obj) { PythonDictionary initializedSlotValues = new PythonDictionary(); IList <PythonType> mro = DynamicHelpers.GetPythonType(obj).ResolutionOrder; foreach (object type in mro) { if (PythonOps.TryGetBoundAttr(type, "__slots__", out object?slots)) { List <string> slotNames = PythonType.SlotsToList(slots); foreach (string slotName in slotNames) { if (slotName == "__dict__") { continue; } // don't reassign same-named slots from types earlier in the MRO if (initializedSlotValues.__contains__(slotName)) { continue; } if (PythonOps.TryGetBoundAttr(obj, slotName, out object?slotValue)) { initializedSlotValues[slotName] = slotValue; } } } } if (initializedSlotValues.Count == 0) { return(null); } return(initializedSlotValues); }
/// <summary> /// Return a dict that maps slot names to slot values, but only include slots that have been assigned to. /// Looks up slots in base types as well as the current type. /// /// Sort-of Python equivalent (doesn't look up base slots, while the real code does): /// return dict([(slot, getattr(self, slot)) for slot in type(self).__slots__ if hasattr(self, slot)]) /// /// Return null if the object has no __slots__, or empty dict if it has __slots__ but none are initialized. /// </summary> private static PythonDictionary GetInitializedSlotValues(object obj) { PythonDictionary initializedSlotValues = new PythonDictionary(); IList<PythonType> mro = DynamicHelpers.GetPythonType(obj).ResolutionOrder; object slots; object slotValue; foreach (object type in mro) { if (PythonOps.TryGetBoundAttr(type, "__slots__", out slots)) { List<string> slotNames = PythonType.SlotsToList(slots); foreach (string slotName in slotNames) { if (slotName == "__dict__") continue; // don't reassign same-named slots from types earlier in the MRO if (initializedSlotValues.__contains__(slotName)) continue; if (PythonOps.TryGetBoundAttr(obj, slotName, out slotValue)) { initializedSlotValues[slotName] = slotValue; } } } } if (initializedSlotValues.Count == 0) return null; return initializedSlotValues; }