def reinvoke(obj: Any, additional_kwargs: Dict[str, Any]) -> Any: assert is_reinvokable( obj ), f'reinvoke() called on object with missing @reinvokable constructor decorator: {obj!r}' additional_kwargs_namespace = Namespace(additional_kwargs) kwargs = {} for name, saved_param in items(obj._iommi_saved_params): try: new_param = getattr_path(additional_kwargs_namespace, name) except AttributeError: kwargs[name] = saved_param else: if is_reinvokable(saved_param): assert isinstance(new_param, dict) kwargs[name] = reinvoke(saved_param, new_param) else: if isinstance(saved_param, Namespace): kwargs[name] = Namespace(saved_param, new_param) else: kwargs[name] = new_param additional_kwargs_namespace.pop('call_target', None) kwargs = Namespace( additional_kwargs_namespace, kwargs) # Also include those keys not already in the original result = type(obj)(**kwargs) retain_special_cases(obj, result) return result
def reinvoke_new_defaults(obj: Any, additional_kwargs: Dict[str, Any]) -> Any: assert is_reinvokable(obj), f'reinvoke_new_defaults() called on object with ' \ f'missing @reinvokable constructor decorator: {obj!r}' additional_kwargs_namespace = Namespace(additional_kwargs) kwargs = Namespace(additional_kwargs_namespace) for name, saved_param in items(obj._iommi_saved_params): try: new_param = getattr_path(additional_kwargs_namespace, name) except AttributeError: kwargs[name] = saved_param else: if is_reinvokable(saved_param): assert isinstance(new_param, dict) kwargs[name] = reinvoke_new_defaults(saved_param, new_param) else: if isinstance(saved_param, Namespace): kwargs[name] = Namespace(new_param, saved_param) else: kwargs[name] = saved_param additional_kwargs_namespace.pop('call_target', None) try: result = type(obj)(**kwargs) except TypeError as e: raise InvalidStyleConfigurationException( f'Object {obj!r} could not be updated with style configuration {flatten(additional_kwargs_namespace)}' ) from e retain_special_cases(obj, result) return result
def reinvoke(self, additional_kwargs: Dict[str, Any]) -> "Traversable": assert hasattr(self, '_iommi_saved_params'), f'reinvoke() called on class with missing @reinvokable decorator: {self.__class__.__name__}' additional_kwargs_namespace = Namespace(additional_kwargs) kwargs = {} for name, saved_param in items(self._iommi_saved_params): try: new_param = getattr_path(additional_kwargs_namespace, name) except AttributeError: kwargs[name] = saved_param else: if hasattr(saved_param, 'reinvoke'): assert isinstance(new_param, dict) kwargs[name] = saved_param.reinvoke(new_param) else: if isinstance(saved_param, Namespace): kwargs[name] = Namespace(saved_param, new_param) else: kwargs[name] = new_param additional_kwargs_namespace.pop('call_target', None) kwargs = Namespace(additional_kwargs_namespace, kwargs) # Also include those keys not already in the original result = type(self)(**kwargs) result._name = self._name __tri_declarative_shortcut_stack = getattr(self, '__tri_declarative_shortcut_stack', None) if __tri_declarative_shortcut_stack is not None: setattr(result, '__tri_declarative_shortcut_stack', __tri_declarative_shortcut_stack) return result
def component(self, obj): result = Namespace() for class_name in class_names_for(obj.__class__): if class_name in self.config: config = Namespace(self.config.get(class_name, {})) shortcuts_config = Namespace(config.pop('shortcuts', {})) result.update(config) for shortcut_name in reversed( getattr(obj, '__tri_declarative_shortcut_stack', [])): result = Namespace(result, shortcuts_config.get(shortcut_name, {})) return result
def component(self, obj): result = Namespace() # TODO: is this wrong? Should it take classes first, then loop through shortcuts? for class_name in class_names_for(type(obj)): if class_name in self.config: config = Namespace(self.config.get(class_name, {})) shortcuts_config = Namespace(config.pop('shortcuts', {})) result.update(config) for shortcut_name in reversed( getattr(obj, '__tri_declarative_shortcut_stack', [])): result = Namespace(result, shortcuts_config.get(shortcut_name, {})) return result
def component(self, obj, is_root=False): """ Calculate the namespace of additional argument that should be applied to the given object. If is_root is set to True, assets might also be added to the namespace. """ result = Namespace() # TODO: is this wrong? Should it take classes first, then loop through shortcuts? for class_name in class_names_for(type(obj)): if class_name in self.config: config = Namespace(self.config.get(class_name, {})) shortcuts_config = Namespace(config.pop('shortcuts', {})) result.update(config) for shortcut_name in reversed(getattr(obj, '__tri_declarative_shortcut_stack', [])): result = Namespace(result, shortcuts_config.get(shortcut_name, {})) if is_root: result = Namespace(result, self.root) return result