def __setattr__(self, name, value): if name in self.__dict__: raise FrozenInstanceError() elif name == "invertible_adapter": # This is for backwards compatibility. In v1, invertible adapters were specified in a nested config dict. # Now, we have two config keys directly in the adapter config. if value: object.__setattr__(self, "inv_adapter", value["block_type"]) object.__setattr__(self, "inv_adapter_reduction_factor", value["reduction_factor"]) else: object.__setattr__(self, name, value)
def _update(self, other=None, key=None, allow_new_key=False, allow_type_change=False, **kwargs): try: is_frozen = self._frozen except AttributeError: is_frozen = False if is_frozen: raise FrozenInstanceError(f'Attempted to update a frozen instance. Call `unfreeze` if this is intended.') klass = self.__class__ if isinstance(key, str): key = [key] if other is None and len(kwargs) > 0: _update(self, kwargs, key=key, allow_new_key=allow_new_key, allow_type_change=allow_type_change) elif isinstance(other, str) or hasattr(other, 'getvalue'): try: o = klass.load(other) udict = o.asdict() except ValueError: raise ValueError(f'Unable to update from {other}') _update(self, udict, key=key, allow_new_key=allow_new_key, allow_type_change=allow_type_change) elif isinstance(other, klass): for f in fields(other): if key is not None: if f.name not in key: continue self.__setattr__(f.name, getattr(other, f.name), allow_type_change=allow_type_change) elif isinstance(other, dict): for k, v in other.items(): if not hasattr(self, k): if not allow_new_key: raise KeyError(f'{k} is not a valid key in {self}, as `allow_new_key` is {allow_new_key}') else: new_cls = make_dataclass(self.__class__.__name__, fields=[(k, type(v), field(default_factory=lambda: v))], bases=(self.__class__,)) self.__class__ = new_cls self.__setattr__(k, v) else: if key is not None and k not in key: continue old_v = getattr(self, k) new_v = v if is_dataclass_instance(old_v): assert isinstance(v, dict) old_v.update(v, allow_new_key=allow_new_key, allow_type_change=allow_type_change) else: # special relaxation, tuple <-> list is interchanable if isinstance(old_v, list) and isinstance(new_v, tuple): new_v = list(new_v) if isinstance(old_v, tuple) and isinstance(new_v, list): new_v = tuple(new_v) self.__setattr__(k, new_v, allow_type_change=allow_type_change)
def __setattr__(self, name, value): # Raise error if frozen unless we're trying to unfreeze the config if hasattr(self, '_frozen'): if name == '_frozen': pass elif self._frozen: err_msg = (f"Cannot set attribute '{name}'. Config object is frozen. " "Unfreeze the config for a mutable config object") raise FrozenInstanceError(err_msg) # Check for reserved names name_taken_msg = f"The attribute '{name}' can't be assigned to config '{type(self).__name__}' since it already has a method by that name" def assert_name(name, method_name): assert name != method_name, name_taken_msg methods = inspect.getmembers(self, predicate=inspect.ismethod) [assert_name(name, m[0]) for m in methods] object.__setattr__(self, name, value)
def __setattr__(self, name, value, allow_type_change=False): field_def = None try: is_frozen = self._frozen except AttributeError: is_frozen = False if name != '_frozen' and is_frozen: raise FrozenInstanceError( f'Attempted to change `{name}` attribute of a frozen instance. Call `unfreeze` if this is intended.') try: field_def = self.__dataclass_fields__.get(name, None) except AttributeError: pass if field_def is not None: required_type = field_def.type if isinstance(required_type, AnnotateField): required_type = required_type.type if not allow_type_change and not is_instance(value, required_type): raise TypeError(f'`{self.__class__}.{name}` requires {required_type}, given {type(value)}:{value}') o___setattr__(self, name, value)
def __setattr__(self, name, value): config_class = type(self).__name__ # Handle interface values old_value = getattr(self, name, None) if isinstance(old_value, InterfaceField): value = old_value.update_value(name, value, config_class) # Raise error if frozen unless we're trying to unfreeze the config if getattr(self, '_frozen', False) and name != '_frozen': err_msg = f"Can't set attribute '{name}'. Config object is frozen. Unfreeze the config to make it mutable" raise FrozenInstanceError(err_msg) # Check for reserved names name_taken_msg = ( f"The attribute '{name}' can't be assigned to config '{config_class}' since it already has a method by that name" ) methods = inspect.getmembers(self, predicate=inspect.ismethod) for method in methods: assert name != method[0], name_taken_msg object.__setattr__(self, name, value)
def new_setattr(self, key: str, value: Any) -> None: if getattr(self, "_is_frozen", False): raise FrozenInstanceError( f"Attempting to modify the attribute {key} after the object {self} was created." ) prev_setattr(self, key, value)
def __delattr__(self, name): raise FrozenInstanceError()
def __setattr__(self, name, value): if name in self.__dict__: raise FrozenInstanceError() else: object.__setattr__(self, name, value)
def __setattr__(self, key: str, value: Any) -> None: if hasattr(self, "_is_frozen") and key == "lib_name": raise FrozenInstanceError( f"Attempting to modify the attribute {key} with value {value} on {self}." ) super().__setattr__(key, value)