Exemple #1
0
class OutputSpec(object):
    def __init__(self,
                 name: str,
                 data_type: Any,
                 nullable: bool,
                 metadata: Any = None):
        self.name = assert_triad_var_name(name)
        self.data_type = to_type(data_type)
        self.nullable = nullable
        self.metadata = ParamDict(metadata, deep=True)
        self.metadata.set_readonly()

    def __uuid__(self) -> str:
        return to_uuid([self.__dict__[x] for x in self.attributes])

    def __repr__(self) -> str:
        return self.name

    def validate_value(self, obj: Any) -> Any:
        if obj is not None:
            aot(
                isinstance(obj, self.data_type),
                lambda: TypeError(f"{obj} mismatches type {self.paramdict}"),
            )
            return obj
        aot(self.nullable, lambda: f"Can't set None to {self}")
        return obj

    def validate_spec(self, spec: "OutputSpec") -> "OutputSpec":
        if not self.nullable:
            aot(
                not spec.nullable,
                lambda: TypeError(
                    f"{self} - {spec} are not compatible on nullable"),
            )
        aot(
            issubclass(spec.data_type, self.data_type),
            lambda: TypeError(
                f"{self} - {spec} are not compatible on data_type"),
        )
        return spec

    @property
    def attributes(self) -> List[str]:
        return ["name", "data_type", "nullable", "metadata"]

    @property
    def paramdict(self) -> ParamDict:
        return ParamDict((x, self.__dict__[x]) for x in self.attributes)

    @property
    def jsondict(self) -> ParamDict:
        res = ParamDict()
        for k, v in self.paramdict.items():
            if isinstance(v, type):
                v = get_full_type_path(v)
            res[k] = v
        return res
Exemple #2
0
def test_param_dict():
    d = ParamDict([("a", 1), ("b", 2)])
    assert 1 == d["a"]
    assert 1 == d[0]
    assert 2 == d["b"]
    assert "2" == d.get_or_throw(1, str)
    # if giving index, it should ignore the throw flag and always throw
    raises(IndexError, lambda: d.get(2, "x"))
    raises(IndexError, lambda: d.get_or_none(2, str))

    d = {"a": "b", "b": {"x": 1, "y": "d"}}
    p = ParamDict(d)
    print({"test": p})
    d["b"]["x"] = 2
    assert 1 == p["b"]["x"]
    p = ParamDict(d, deep=False)
    d["b"]["x"] = 3
    assert 3 == p["b"]["x"]
    pp = ParamDict(p, deep=False)
    p["b"]["x"] = 4
    assert 4 == pp["b"]["x"]
    pp = ParamDict(p, deep=True)
    p["b"]["x"] = 5
    assert 4 == pp["b"]["x"]

    assert 2 == len(p)
    assert "a,b" == ",".join([k for k, _ in p.items()])
    del p["a"]
    assert 1 == len(p)
    p["c"] = 1
    assert 2 == len(p)
    assert "c" in p
    assert "a" not in p

    raises(ValueError, lambda: p.get("c", None))
    assert 1 == p.get("c", 2)
    assert "1" == p.get("c", "2")
    assert 1.0 == p.get("c", 2.0)
    raises(TypeError, lambda: p.get("c", ParamDict()))
    assert 2 == p.get("d", 2)
    p["arr"] = [1, 2]
    assert [1, 2] == p.get("arr", [])
    assert [] == p.get("arr2", [])

    assert p.get_or_none("e", int) is None
    assert 1 == p.get_or_none("c", int)
    assert "1" == p.get_or_none("c", str)
    # exists but can't convert type
    raises(TypeError, lambda: p.get_or_none("c", ParamDict))

    raises(KeyError, lambda: p.get_or_throw("e", int))
    assert 1 == p.get_or_throw("c", int)
    assert "1" == p.get_or_throw("c", str)
    # exists but can't convert type
    raises(TypeError, lambda: p.get_or_throw("c", ParamDict))

    p = ParamDict()
    assert 0 == len(p)
    for x in p:
        pass

    raises(TypeError, lambda: ParamDict("abc"))

    a = ParamDict({"a": 1, "b": 2})
    b = ParamDict({"b": 2, "a": 1})
    c = ParamDict({"b": 2})
    assert a == a
    assert a != b
    assert a != c
    assert a == {"b": 2, "a": 1}
    assert a != {"b": 1, "a": 1}
    assert a != None
    assert not (a == None)

    p = ParamDict({
        "a": "True",
        "b": True,
        "c": "true",
        "d": "False",
        "e": False,
        "f": "false",
        "g": "yes",
        "h": "NO",
        "i": 0,
        "j": "1",
        "k": "",
    })
    assert p.get_or_throw("a", bool)
    assert p.get_or_throw("b", bool)
    assert p.get_or_throw("c", bool)
    assert not p.get_or_throw("d", bool)
    assert not p.get_or_throw("e", bool)
    assert not p.get_or_throw("f", bool)
    assert p.get_or_throw("g", bool)
    assert not p.get_or_throw("h", bool)
    assert not p.get_or_throw("i", bool)
    assert p.get_or_throw("j", bool)
    raises(TypeError, lambda: p.get_or_throw("k", bool))

    s = '{"a":false,"b":10,"c":"cd"}'
    p = ParamDict(json.loads(s))
    assert not p.get_or_throw("a", bool)
    assert "10" == p.get_or_throw("b", str)
    assert "cd" == p.get_or_throw("c", str)
    raises(KeyError, lambda: p.get_or_throw("d", str))

    print(p.to_json())
    print(p.to_json(True))

    # update
    p = ParamDict(dict(a=1, b=2))
    p1 = ParamDict(dict(b=3, c=4))
    p.update(p1)
    assert dict(a=1, b=3, c=4) == p

    p = ParamDict(dict(a=1, b=2))
    p.update(p1, ParamDict.OVERWRITE)
    assert dict(a=1, b=3, c=4) == p

    p = ParamDict(dict(a=1, b=2))
    p.update(p1, ParamDict.IGNORE)
    assert dict(a=1, b=2, c=4) == p

    p = ParamDict(dict(a=1, b=2))
    raises(KeyError, lambda: p.update(p1, ParamDict.THROW))

    raises(ValueError, lambda: p.update(p1, 100))

    p.set_readonly()
    raises(InvalidOperationError, lambda: p.update(p1, 100))