Пример #1
0
    def recurse(level, name, types, values, delimeter="-"):
        """
        Recurse through a flattened ``form`` dictionary, reconstructing
        dictionary to match structure specified by ``spec``.
        :param dict spec: the canonical_args argspec dict
        :param dict form: the flat HTML form data
        :param str delimeter: default ``"-"``, the string character used
            to separate levels in the ``form.keys()`` entries.
        :returns: ``dict``, the reconstructed, type correct argument
            dictionary, matching the ``spec`` structure.
        """
        subtype = check.eval_subtype(types)

        # choice of one
        if isinstance(subtype, check.ChoiceOfOne):
            entry = NotSpecified

            for index, subsubtype in enumerate(subtype):
                try:
                    entry = recurse(level + 1, name, subsubtype,
                                    values[check.type_to_string(subsubtype)])
                except KeyError as e:
                    pass
                else:
                    break

            if entry is NotSpecified:
                # we couldnt find a valid entry
                # See? Told you we re-raise the key error.
                warnings.warn(
                    "could not find valid entry for '{}'".format(name),
                    RuntimeWarning)

            return entry

        # structlist
        elif isinstance(subtype, list) and isinstance(values, list):
            entry = []
            for index, subsubtype in enumerate(subtype):
                ret = recurse(level + 1, name + "[{}]".format(index),
                              subtype[index], values[index])

                if ret is not NotSpecified:
                    # do not append an unspecified value
                    entry.append(ret)
                else:
                    # because this is a structured list, the positional
                    # argument is guaranteed. an unspecified value must
                    # therefore be None.
                    entry.append(None)
            return entry

        # structdict
        elif subtype == dict and isinstance(values, dict):
            entry = {}
            for kw in sorted(values):
                arg = values[kw]
                ret = recurse(level + 1,
                              name + delimeter + kw,
                              arg["type"],
                              arg["values"],
                              delimeter=delimeter)
                if ret is not NotSpecified:
                    # do not set an unspecified value
                    entry[kw] = ret
                else:
                    # this is a Structured Dict, so we have to guarantee
                    # the presence of all keys. Thusly, set None when a
                    # value is unspecified.
                    entry[kw] = None
            return entry

        # unstructlist
        elif subtype == list and values is None:
            # find all keys matching (other than index)
            pattern = re.compile('{}\[(.*)\]'.format(name))
            matchingkeys = [key for key in form.keys()\
                            if pattern.match(key)]

            construct = []
            for subkey in sorted(matchingkeys):
                index = int(re.findall('\[(.*)\]', subkey)[0])
                raw = form[subkey]
                ret = cast(raw[0], raw[1], name=name)
                if ret is not NotSpecified:
                    # ensure not to appaned a NotSpecified value
                    construct.append(ret)
                # this is an unstructured list, so if a value is
                # unspecified, ignore the shit out of it.
            if len(construct) > 0:
                return construct
            else:
                return NotSpecified

        # unstructdict
        elif subtype == dict and values is None:
            pattern = re.compile('{}\[(.*)\]'.format(name))
            matchingkeys = [key for key in form.keys()\
                            if pattern.match(key)]

            construct = {}
            for subkey in matchingkeys:
                raw = form[subkey]
                if str(raw[0]) != '':
                    # ensure there is a valid key
                    ret = cast(raw[1], raw[2], name=name)
                    if ret != NotSpecified:
                        # ensure there is a valid value
                        construct[str(raw[0])] = ret
                    # this is an unstructured dict, so keys are not
                    # guaranteed here. If a value is unspecified,
                    # simply don't append it (aka, ignore it).
            if len(construct) > 0:
                return construct
            else:
                return NotSpecified

        # cls
        elif check.type_to_string(subtype) in sources.SOURCES:
            identifier = form[name][0]
            import_string = form[name][1]
            obj = sources.get_one(import_string, identifier, raw=True)
            return obj

        # native
        else:
            raw = form[name]
            ret = cast(raw[0], raw[1], name=name)
            return ret
Пример #2
0
 def test_type_none(self):
     self.assertEqual(check.eval_subtype("NoneType"), type(None))
Пример #3
0
 def test_complex_type_with_none(self):
     self.assertEqual(check.eval_subtype("[int, str, NoneType]"),
                      [int, str, type(None)])
Пример #4
0
 def test_type_choice(self):
     self.assertEqual(check.eval_subtype("one([int, float])"),
                      check.ChoiceOfOne([int, float]))
Пример #5
0
 def test_choice_of_one_with_object(self):
     self.assertEqual(
         check.eval_subtype("one([int, cls('test_check.TestObj')])"),
         check.ChoiceOfOne([int, TestObj]))
Пример #6
0
 def test_type_object(self):
     self.assertEqual(check.eval_subtype("test_check.TestObj"), TestObj)
Пример #7
0
 def test_type_dict(self):
     self.assertEqual(check.eval_subtype("dict({'thing1': int})"),
                      {"thing1": int})
Пример #8
0
 def test_type_list(self):
     self.assertEqual(check.eval_subtype("list([int, str, float])"),
                      [int, str, float])
Пример #9
0
 def test_type_native(self):
     self.assertEqual(check.eval_subtype("str"), str)
Пример #10
0
    def recurse(level, name, types, values, delimeter=delimeter):
        subtype = check.eval_subtype(types)

        # choice of one
        if isinstance(subtype, check.ChoiceOfOne):
            entries = []
            for index, subsubtype in enumerate(subtype):
                entries.append(
                    recurse(level + 1, name, subtype[index],
                            values[check.type_to_string(subsubtype)]))

            template = env.get_template("one_selector.html")
            html = template.render(name=name,
                    options=[check.type_to_string(x)\
                       for x in subtype],
                    entries=entries)

            if level > 0:
                template = env.get_template("level.html")
                html = template.render(name=name.split(delimeter)[-1],
                                       include_header=True,
                                       inner=html)
            return html

        # structlist
        elif isinstance(subtype, list) and isinstance(values, list):
            # recurse
            html = ""
            for index, subsubtype in enumerate(subtype):
                html += recurse(level + 1, name + "[" + str(index) + "]",
                                subtype[index], values[index])

            if level > 0:
                template = env.get_template("level.html")
                html = template.render(name=name.split(delimeter)[-1],
                                       include_header=True,
                                       inner=html)
            return html

        # structdict
        elif subtype == dict and isinstance(values, dict):
            html = ""
            for kw in sorted(values):
                arg = values[kw]
                html += recurse(level + 1, name + delimeter + kw, arg["type"],
                                arg["values"])

            if level > 0:
                template = env.get_template("level.html")
                html = template.render(name=name.split(delimeter)[-1],
                                       include_header=True,
                                       inner=html)
            return html

        # unstructlist
        elif subtype == list and values is None:
            template = env.get_template("base.html")
            html = template.render(name=name,
                                   displayname=name.split(delimeter)[-1],
                                   type=check.type_to_string(subtype),
                                   inputtype="unstructlist")

            if level > 0:
                template = env.get_template("level.html")
                html = template.render(name=name.split(delimeter)[-1],
                                       include_header=True,
                                       inner=html)
            return html

        # unstructdict
        elif subtype == dict and values is None:
            template = env.get_template("base.html")
            html = template.render(name=name,
                                   displayname=name.split(delimeter)[-1],
                                   type=check.type_to_string(subtype),
                                   inputtype="unstructdict")

            if level > 0:
                template = env.get_template("level.html")
                html = template.render(name=name.split(delimeter)[-1],
                                       include_header=True,
                                       inner=html)
            return html

        # selector
        elif isinstance(values, list):
            template = env.get_template("base.html")
            return template.render(name=name,
                                   displayname=name.split(delimeter)[-1],
                                   type=check.type_to_string(subtype),
                                   options=values,
                                   inputtype="selector")

        # cls
        elif check.type_to_string(subtype) in sources.SOURCES:
            ids, values = sources.get_all(subtype)

            template = env.get_template("base.html")
            return template.render(name=name,
                                   displayname=name.split(delimeter)[-1],
                                   type=check.type_to_string(subtype),
                                   option_ids=ids,
                                   options=values,
                                   inputtype="selector")

        # native
        else:
            # name, type, inputtype
            template = env.get_template("base.html")
            return template.render(name=name,
                                   displayname=name.split(delimeter)[-1],
                                   type=check.type_to_string(subtype),
                                   constraint=values,
                                   inputtype="native")