diff --git a/countess/core/parameters.py b/countess/core/parameters.py index 77d48c1..7302fb7 100644 --- a/countess/core/parameters.py +++ b/countess/core/parameters.py @@ -297,7 +297,7 @@ def get_file_hash(self): try: # Python 3.11 digest = hashlib.file_digest(file, PARAM_DIGEST_HASH) - except AttributeError: + except AttributeError: # pragma: no cover digest = hashlib.new(PARAM_DIGEST_HASH) while True: data = file.read() @@ -725,8 +725,6 @@ def del_row(self, position: int): assert 0 <= position < len(self.params) self.params.pop(position) - if len(self.params) < self.min_size: - self.params.append(self.param.copy()) self.relabel() def del_subparam(self, param: BaseParam): @@ -734,6 +732,8 @@ def del_subparam(self, param: BaseParam): self.relabel() def relabel(self): + while len(self.params) < self.min_size: + self.params.append(self.param.copy()) for n, param in enumerate(self.params): param.label = self.param.label + f" {n+1}" @@ -744,8 +744,6 @@ def __len__(self): return len(self.params) def __getitem__(self, key): - while len(self.params) <= int(key): - self.add_row() return self.params[int(key)] def __setitem__(self, key, value): @@ -785,7 +783,7 @@ def set_parameter(self, key: str, value: Union[bool, int, float, str], base_dir: assert isinstance(param, (HasSubParametersMixin, ArrayParam)) param.set_parameter(subkey, value, base_dir) - else: + elif self.max_size is None or int(key) < self.max_size: while int(key) >= len(self.params): self.params.append(self.param.copy()) param = self.params[int(key)] @@ -810,14 +808,14 @@ def get_parameters(self, key, base_dir="."): def set_column_choices(self, choices): params_by_label = {p.label: p for p in self.params} - self.params = [None] * len(choices) - for num, name in enumerate(choices): - if name in params_by_label: - self.params[num] = params_by_label[name] + self.params = [] + for label in choices: + if label in params_by_label: + self.params.append(params_by_label[label]) else: - self.params[num] = self.param.copy() - self.params[num].label = name - self.params[num].set_column_choices(choices) + self.params.append(self.param.copy()) + self.params[-1].label = label + super().set_column_choices(choices) def get_column_params(self): for p in self.params: diff --git a/tests/test_parameters.py b/tests/test_parameters.py index 5eea1ff..eac481d 100644 --- a/tests/test_parameters.py +++ b/tests/test_parameters.py @@ -1,5 +1,5 @@ import io -from unittest.mock import mock_open, patch +from unittest.mock import patch import pandas as pd import pytest @@ -15,10 +15,12 @@ ColumnOrNoneChoiceParam, DataTypeChoiceParam, DataTypeOrNoneChoiceParam, + FileArrayParam, FileParam, FloatParam, IntegerParam, MultiParam, + PerColumnArrayParam, ScalarParam, StringCharacterSetParam, StringParam, @@ -108,6 +110,7 @@ def test_multiparam(): ) assert "foo" in mp + assert sorted(mp.keys()) == ["bar", "foo"] mp["foo"] = "hello" assert mp.foo == "hello" @@ -123,6 +126,9 @@ def test_multiparam(): mp.set_parameter("foo._label", "fnord") assert mp["foo"].label == "fnord" + with pytest.raises(AttributeError): + assert mp.fnord + def test_scsp(): pp = StringCharacterSetParam("x", "hello", character_set=set("HelO")) @@ -277,6 +283,23 @@ def dummy(*_, **__): fp.value = "/foo/bar/baz" assert fp.get_parameters("fnord", "/foo") == [("fnord", "bar/baz")] + assert fp.get_parameters("fnord", "") == [("fnord", "/foo/bar/baz")] + + fp.value = "" + assert fp.get_parameters("fnord", "") == [("fnord", None)] + + +def test_filearrayparam(): + ap1 = FileArrayParam("x", param=FileParam("Y")) + assert ap1.find_fileparam().label == "Y" + + ap2 = FileArrayParam("x", param=MultiParam("Y", params={"z": FileParam("Z")})) + assert ap2.find_fileparam().label == "Z" + + with pytest.raises(TypeError): + ap0 = FileArrayParam("x", param=IntegerParam("Y")) + ap0.find_fileparam() + def test_arrayparam_minmax(): pp = IntegerParam("x") @@ -295,6 +318,25 @@ def test_arrayparam_minmax(): ap.del_row(1) assert len(ap) == 2 - # FIX minimum and maximum constraints! - # ap.del_subparam(ap[1]) - # assert len(ap) == 2 + assert ap[1] in ap + ap.del_subparam(ap[1]) + assert len(ap) == 2 + + ap[0] = 7 + assert ap[0].value == 7 + + +def test_pcap(): + pp = IntegerParam("x") + ap = PerColumnArrayParam("y", param=pp) + + ap.set_column_choices(["a", "b", "c"]) + assert len(ap) == 3 + apa, apb, apc = list(ap) + + ap.set_column_choices(["c", "d", "b", "a"]) + assert len(ap) == 4 + assert ap[0] is apc + assert ap[2] is apb + assert ap[3] is apa + assert ap[1] is not apb