github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/clients/python-wrapper/lakefs/namedtuple.py (about) 1 """ 2 LenientNamedTuple Module 3 """ 4 5 6 class LenientNamedTuple: 7 """ 8 Class which provides the NamedTuple functionality but allows initializing with unknown fields. 9 The unknown fields will be ignored and mandatory fields are enforced 10 """ 11 12 __initialized: bool = False 13 unknown: dict = {} 14 15 def __init__(self, **kwargs): 16 fields = list(self.__class__.__dict__["__annotations__"].keys()) 17 for k, v in kwargs.items(): 18 if k in fields: 19 setattr(self, k, v) 20 fields.remove(k) 21 else: 22 self.unknown[k] = v 23 24 if len(fields) > 0: 25 raise TypeError(f"missing {len(fields)} required arguments: {fields}") 26 27 self.__initialized = True 28 super().__init__() 29 30 def __repr__(self): 31 class_name = self.__class__.__name__ 32 if hasattr(self, 'id'): 33 return f'{class_name}(id="{self.id}")' 34 return f'{class_name}()' 35 36 def __setattr__(self, name, value): 37 if self.__initialized: 38 raise AttributeError("can't set attribute") 39 super().__setattr__(name, value) 40 41 def __eq__(self, other): 42 if not isinstance(other, self.__class__): 43 return False 44 for k, v in self.__dict__.items(): 45 if k == "unknown": 46 continue 47 if other.__dict__[k] != v: 48 return False 49 50 return True 51 52 def __str__(self): 53 fields = {} 54 for k, v in self.__dict__.items(): 55 if k != "unknown" and k[0] != "_": # Filter internal and unknown fields 56 fields[k] = v 57 return str(fields)