Beispiel #1
0
def test_evaluate_strict():
    with pytest.raises(AssertionError) as e:
        evaluate_strict(lambda foo: 1, bar=2, baz=4)

    assert str(
        e.value
    ) == "Evaluating lambda found at: `evaluate_strict(lambda foo: 1, bar=2, baz=4)` didn't resolve it into a value but strict mode was active, the signature doesn't match the given parameters. We had these arguments: bar, baz"
Beispiel #2
0
def evaluate_attrs(obj, **kwargs):
    attrs = obj.attrs or {}

    # Micro optimization
    from iommi.debug import iommi_debug_on
    if not attrs and not iommi_debug_on():
        return ''

    return Attrs(
        obj,
        **{
            'class': {
                k: evaluate_strict(v, **kwargs)
                for k, v in items(
                    evaluate_strict(attrs.get('class', {}), **kwargs))
            }
        },
        style={
            k: evaluate_strict(v, **kwargs)
            for k, v in items(evaluate_strict(attrs.get('style', {}), **
                                              kwargs))
        },
        **{
            k: evaluate_strict(v, **kwargs)
            for k, v in items(attrs) if k not in ('class', 'style')
        },
    )
Beispiel #3
0
    def _read_raw_data(self):
        if self.raw_data is not None:
            self.raw_data = evaluate_strict(self.raw_data, **self.iommi_evaluate_parameters())
            return
        if self.raw_data_list is not None:
            self.raw_data_list = evaluate_strict(self.raw_data_list, **self.iommi_evaluate_parameters())
            return

        form = self.iommi_parent().iommi_parent()

        if self.is_list:
            if self.raw_data_list is not None:
                return
            try:
                # django and similar
                # noinspection PyUnresolvedReferences
                raw_data_list = form._request_data.getlist(self.iommi_path)
            except AttributeError:  # pragma: no cover
                # werkzeug and similar
                raw_data_list = form._request_data.get(self.iommi_path)

            if raw_data_list and self.strip_input:
                raw_data_list = [x.strip() for x in raw_data_list]

            if raw_data_list is not None:
                self.raw_data_list = raw_data_list
        else:
            if self.raw_data is not None:
                return
            self.raw_data = form._request_data.get(self.iommi_path)
            if self.raw_data and self.strip_input:
                self.raw_data = self.raw_data.strip()
Beispiel #4
0
    def on_bind(self) -> None:
        assert self.actions_template
        self._valid = None
        request = self.get_request()
        self._request_data = request_data(request)

        self.title = evaluate_strict(self.title, **self.iommi_evaluate_parameters())
        if isinstance(self.h_tag, Namespace):
            if self.title not in (None, MISSING):
                self.h_tag = self.h_tag(
                    _name='h_tag',
                    children__text=capitalize(self.title),
                ).bind(parent=self)
            else:
                self.h_tag = ''
        else:
            self.h_tag = self.h_tag.bind(parent=self)

        # Actions have to be bound first because is_target() needs it
        bind_members(self, name='actions', cls=Actions)

        if self._request_data is not None and self.is_target():
            self.mode = FULL_FORM_FROM_REQUEST

        bind_members(self, name='fields')
        bind_members(self, name='endpoints')

        self.is_valid()

        self.errors = Errors(parent=self, errors=self.errors)
Beispiel #5
0
    def bind(self, *, parent=None, request=None):
        assert parent is None or parent._is_bound
        assert not self._is_bound

        result = copy.copy(self)

        if parent:
            is_root = False
            iommi_style = get_iommi_style_name(parent)
        else:
            is_root = True
            iommi_style = get_iommi_style_name(self)

        result = apply_style(iommi_style, result, is_root)
        result._declared = self

        del self  # to prevent mistakes when changing the code below

        if parent is None:
            result._request = request
            if result._name is None:
                result._name = 'root'
            result._iommi_collected_assets = {}

        result._parent = parent
        result._bound_members = Struct()
        result._is_bound = True

        evaluate_parameters = {
            **(parent.iommi_evaluate_parameters() if parent is not None else {}),
            **result.own_evaluate_parameters(),
            'traversable': result,
        }
        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

        result.include = True

        result.on_bind()

        # 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
Beispiel #6
0
    def on_bind(self):
        super(MenuItem, self).on_bind()

        self.url = evaluate_strict(self.url, **self.iommi_evaluate_parameters())

        # If this is a section header, and all sub-parts are hidden, hide myself
        if not self.url and self.sub_menu is not None and not self.sub_menu:
            self.include = False
Beispiel #7
0
def evaluate_attrs(obj, **kwargs):
    attrs = obj.attrs or {}

    # Micro optimization
    from iommi.debug import iommi_debug_on

    if not attrs and not iommi_debug_on():
        return ''

    classes = evaluate_strict(attrs.get('class', {}), **kwargs)

    assert not isinstance(
        classes, str
    ), """CSS classes needs to be specified as dicts, not as strings. So you want something like:
    field__class__foo=True

or

    field__class={'foo-bar': true}"""

    styles = evaluate_strict(attrs.get('style', {}), **kwargs)

    assert not isinstance(
        styles, str
    ), """CSS styles needs to be specified as dicts, not as strings. So you want something like:
        field__style__display='none'

    or

        field__style={'background-color': 'blue'}"""

    return Attrs(
        obj,
        **{
            'class':
            {k: evaluate_strict(v, **kwargs)
             for k, v in items(classes)}
        },
        style={k: evaluate_strict(v, **kwargs)
               for k, v in items(styles)},
        **{
            k: evaluate_strict(v, **kwargs)
            for k, v in items(attrs) if k not in ('class', 'style')
        },
    )
Beispiel #8
0
    def on_bind(self) -> None:
        assert self.template

        form = self.iommi_parent().iommi_parent()
        if self.attr is MISSING:
            self.attr = self._name
        if self.display_name is MISSING:
            self.display_name = capitalize(self._name).replace('_', ' ') if self._name else ''

        self.errors = Errors(parent=self, **self.errors)

        if form.editable is False:
            self.editable = False

        # Not strict evaluate on purpose
        self.model = evaluate(self.model, **self.iommi_evaluate_parameters())

        self.choices = evaluate_strict(self.choices, **self.iommi_evaluate_parameters())

        self.initial = evaluate_strict(self.initial, **self.iommi_evaluate_parameters())
        self._read_initial()

        self._read_raw_data()

        self.parsed_data = evaluate_strict(self.parsed_data, **self.iommi_evaluate_parameters())
        self._parse()

        self._validate()

        self.input = self.input.bind(parent=self)
        self.label = self.label.bind(parent=self)
        assert not self.label.children
        self.label.children = dict(text=evaluate_strict(self.display_name, **self.iommi_evaluate_parameters()))
        self.non_editable_input = self.non_editable_input.bind(parent=self)

        if self.model and self.include:
            try:
                self.search_fields = get_search_fields(model=self.model)
            except NoRegisteredSearchFieldException:
                self.search_fields = ['pk']
                if iommi_debug_on():
                    print(f'Warning: falling back to primary key as lookup and sorting on {self._name}. \nTo get rid of this warning and get a nicer lookup and sorting use register_search_fields.')
Beispiel #9
0
def build_and_bind_h_tag(p):
    if isinstance(p.h_tag, Namespace):
        if p.title not in (None, MISSING):
            p.h_tag = p.h_tag(
                _name='h_tag',
                children__text=capitalize(
                    evaluate_strict(
                        p.title,
                        **p.iommi_evaluate_parameters()))).bind(parent=p)
        else:
            p.h_tag = ''
    else:
        p.h_tag = p.h_tag.bind(parent=p)
Beispiel #10
0
    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