Skip to content

Commit 34aea94

Browse files
authored
Remove unnecessary and invalid settings (#3548)
* Remove unnecessary and invalid settings * Add unit tests
1 parent 0eb5022 commit 34aea94

File tree

2 files changed

+117
-0
lines changed

2 files changed

+117
-0
lines changed

src/zenml/config/compiler.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,25 @@ def _filter_and_validate_settings(
395395
f"The settings class {settings_instance.__class__} can not "
396396
f"be specified on a {configuration_level.name} level."
397397
)
398+
399+
if settings_instance.model_extra:
400+
logger.warning(
401+
"Ignoring invalid setting attributes `%s` defined for key `%s`.",
402+
list(settings_instance.model_extra),
403+
key,
404+
)
405+
settings_instance = settings_instance.model_validate(
406+
settings_instance.model_dump(
407+
exclude=set(settings_instance.model_extra),
408+
exclude_unset=True,
409+
)
410+
)
411+
412+
if not settings_instance.model_fields_set:
413+
# There are no values defined on the settings instance, don't
414+
# include them in the deployment
415+
continue
416+
398417
validated_settings[key] = settings_instance
399418

400419
return validated_settings

tests/unit/config/test_compiler.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,104 @@ def test_stack_component_settings_for_missing_component_are_ignored(
473473
)
474474

475475

476+
def test_invalid_settings_keys_are_ignored(
477+
mocker, one_step_pipeline, empty_step, local_stack
478+
):
479+
"""Tests that invalid settings keys that are not part of the settings class
480+
are ignored."""
481+
482+
class StubSettings(BaseSettings):
483+
valid_key: str = ""
484+
485+
orchestrator_class = type(local_stack.orchestrator)
486+
mocker.patch.object(
487+
orchestrator_class,
488+
"settings_class",
489+
new_callable=mocker.PropertyMock,
490+
return_value=StubSettings,
491+
)
492+
493+
settings = {"orchestrator": {"valid_key": "value", "invalid_key": "value"}}
494+
495+
step_instance = empty_step
496+
pipeline_instance = one_step_pipeline(step_instance)
497+
498+
pipeline_instance.configure(settings=settings)
499+
step_instance.configure(settings=settings)
500+
run_config = PipelineRunConfiguration(
501+
settings=settings,
502+
steps={"_empty_step": StepConfigurationUpdate(settings=settings)},
503+
)
504+
505+
with pipeline_instance:
506+
pipeline_instance.entrypoint()
507+
deployment = Compiler().compile(
508+
pipeline=pipeline_instance,
509+
stack=local_stack,
510+
run_configuration=run_config,
511+
)
512+
513+
compiled_pipeline_settings = deployment.pipeline_configuration.settings[
514+
"orchestrator.default"
515+
].model_dump()
516+
assert "invalid_key" not in compiled_pipeline_settings
517+
assert compiled_pipeline_settings["valid_key"] == "value"
518+
519+
compiled_step_settings = (
520+
deployment.step_configurations["_empty_step"]
521+
.config.settings["orchestrator.default"]
522+
.model_dump()
523+
)
524+
assert "invalid_key" not in compiled_step_settings
525+
assert compiled_step_settings["valid_key"] == "value"
526+
527+
528+
def test_empty_settings_classes_are_ignored(
529+
mocker, one_step_pipeline, empty_step, local_stack
530+
):
531+
"""Tests that empty settings classes are ignored."""
532+
533+
class StubSettings(BaseSettings):
534+
valid_key: str = ""
535+
536+
orchestrator_class = type(local_stack.orchestrator)
537+
mocker.patch.object(
538+
orchestrator_class,
539+
"settings_class",
540+
new_callable=mocker.PropertyMock,
541+
return_value=StubSettings,
542+
)
543+
544+
step_instance = empty_step
545+
pipeline_instance = one_step_pipeline(step_instance)
546+
547+
settings = {"orchestrator": {"invalid_key": "value"}}
548+
549+
pipeline_instance.configure(settings=settings)
550+
step_instance.configure(settings=settings)
551+
run_config = PipelineRunConfiguration(
552+
settings=settings,
553+
steps={"_empty_step": StepConfigurationUpdate(settings=settings)},
554+
)
555+
556+
with pipeline_instance:
557+
pipeline_instance.entrypoint()
558+
deployment = Compiler().compile(
559+
pipeline=pipeline_instance,
560+
stack=local_stack,
561+
run_configuration=run_config,
562+
)
563+
564+
assert (
565+
"orchestrator.default"
566+
not in deployment.pipeline_configuration.settings
567+
)
568+
assert (
569+
"orchestrator.default"
570+
not in deployment.step_configurations["_empty_step"].config.settings
571+
)
572+
573+
476574
@step
477575
def s1() -> int:
478576
return 1

0 commit comments

Comments
 (0)