def test_error_when_trying_to_style_non_existent_attribute(): class Foo: def __repr__(self): return '<Foo>' style = Namespace(something_that_does_not_exist='!!!') with pytest.raises(InvalidStyleConfigurationException) as e: apply_style_recursively(style_data=style, obj=Foo()) assert str( e.value ) == 'Object <Foo> has no attribute something_that_does_not_exist which the style tried to set.'
def test_style(): class A(RefinableObject): foo = Refinable() bar = Refinable() @classmethod @class_shortcut def shortcut1(cls, call_target, **kwargs): return call_target(**kwargs) def items(self): return dict(foo=self.foo, bar=self.bar) class B(A): @classmethod @class_shortcut(call_target__attribute='shortcut1') def shortcut2(cls, call_target, **kwargs): return call_target(**kwargs) base = Style(A=dict(foo=1, ), ) overrides = Style( base, A=dict( shortcuts=dict(shortcut1__foo=4, ), foo=5, bar=6, ), B=dict(bar=7, ), ) # First the unstyled case assert items(B()) == dict(foo=None, bar=None) assert items(B.shortcut1()) == dict(foo=None, bar=None) assert items(B.shortcut2()) == dict(foo=None, bar=None) # Now let's add the style b = B() apply_style_recursively(style_data=overrides.component(b), obj=b) assert items(b) == dict(foo=5, bar=7) b = B.shortcut1() assert overrides.component(b) == dict(foo=4, bar=7) assert b.__tri_declarative_shortcut_stack == ['shortcut1'] apply_style_recursively(style_data=overrides.component(b), obj=b) assert items(b) == dict(foo=4, bar=7) b = B.shortcut2() assert b.__tri_declarative_shortcut_stack == ['shortcut2', 'shortcut1'] assert overrides.component(b) == dict(foo=4, bar=7) apply_style_recursively(style_data=overrides.component(b), obj=b) assert items(b) == dict(foo=4, bar=7)
def bind(self, *, parent=None, request=None): assert parent is None or parent._is_bound assert not self._is_bound if parent is None: self._request = request if self._name is None: self._name = 'root' result = copy.copy(self) result._declared = self del self # to prevent mistakes when changing the code below result._parent = parent result._is_bound = True evaluate_parameters = { 'traversable': result, **(parent.iommi_evaluate_parameters() if parent is not None else {}), **result.own_evaluate_parameters(), } if parent is None: evaluate_parameters['request'] = request result._evaluate_parameters = evaluate_parameters if hasattr(result, 'include'): include = evaluate_strict(result.include, **evaluate_parameters) if not bool(include): return None else: include = MISSING if include is not MISSING: result.include = True rest_of_style = apply_style(result) # Styling has another chance of setting include to False if include is not MISSING and result.include is False: return None result.include = True result.on_bind() if rest_of_style: rest = apply_style_recursively(style_data=rest_of_style, obj=result) assert not rest, f'There is still styling data left for {result}: {rest_of_style}' # on_bind has a chance to hide itself if result.include is False: return None if hasattr(result, 'attrs'): result.attrs = evaluate_attrs(result, **result.iommi_evaluate_parameters()) evaluated_attributes = [ k for k, v in items(result.get_declared('refinable_members')) if is_evaluated_refinable(v) ] evaluate_members(result, evaluated_attributes, **evaluate_parameters) if hasattr(result, 'extra_evaluated'): result.extra_evaluated = evaluate_strict_container( result.extra_evaluated or {}, **evaluate_parameters) return result
def test_apply_style_recursively_does_not_overwrite(): foo = Namespace(bar__template='specified') style = Namespace(bar__template='style_template') apply_style_recursively(style_data=style, obj=foo) assert foo == Namespace(bar__template='specified')
def apply_style(obj): style = get_style_obj_for_object(style=get_style_for(obj), obj=obj) apply_style_recursively(style_data=style, obj=obj)