diff --git a/flytekit/image_spec/image_spec.py b/flytekit/image_spec/image_spec.py index 7cde9fa70a..e750cc211e 100644 --- a/flytekit/image_spec/image_spec.py +++ b/flytekit/image_spec/image_spec.py @@ -79,6 +79,23 @@ def __post_init__(self): if self.registry: self.registry = self.registry.lower() + parameters_str_list = [ + "packages", + "conda_channels", + "conda_packages", + "apt_packages", + "pip_extra_index_url", + "entrypoint", + "commands", + ] + for parameter in parameters_str_list: + attr = getattr(self, parameter) + parameter_is_None = attr is None + parameter_is_list_string = isinstance(attr, list) and all(isinstance(v, str) for v in attr) + if not (parameter_is_None or parameter_is_list_string): + error_msg = f"{parameter} must be a list of strings or None" + raise ValueError(error_msg) + def image_name(self) -> str: """Full image name with tag.""" image_name = self._image_name() diff --git a/tests/flytekit/unit/core/image_spec/test_image_spec.py b/tests/flytekit/unit/core/image_spec/test_image_spec.py index c1e52953bb..fa63f08993 100644 --- a/tests/flytekit/unit/core/image_spec/test_image_spec.py +++ b/tests/flytekit/unit/core/image_spec/test_image_spec.py @@ -138,3 +138,19 @@ def test_no_build_during_execution(): ImageBuildEngine.build(spec) ImageBuildEngine._build_image.assert_not_called() + + +@pytest.mark.parametrize( + "parameter_name", [ + "packages", "conda_channels", "conda_packages", + "apt_packages", "pip_extra_index_url", "entrypoint", "commands" + ] +) +@pytest.mark.parametrize("value", ["requirements.txt", [1, 2, 3]]) +def test_image_spec_validation_string_list(parameter_name, value): + msg = f"{parameter_name} must be a list of strings or None" + + input_params = {parameter_name: value} + + with pytest.raises(ValueError, match=msg): + ImageSpec(**input_params)