diff --git a/esphome/espidf/component.py b/esphome/espidf/component.py index 105413cf44..bed999656b 100644 --- a/esphome/espidf/component.py +++ b/esphome/espidf/component.py @@ -240,12 +240,17 @@ def generate_idf_component_yml(component: IDFComponent) -> str: data = {} + # Metadata only: tolerate malformed shapes instead of crashing on a + # third-party manifest (repository may legally be {"url": ...} or a + # plain URL string) description = component.data.get("description") - if description: + if isinstance(description, str) and description: data["description"] = description - repository = component.data.get("repository", {}).get("url", None) - if repository: + repository = component.data.get("repository") + if isinstance(repository, dict): + repository = repository.get("url") + if isinstance(repository, str) and repository: data["repository"] = repository for dependency in component.dependencies: diff --git a/tests/unit_tests/test_espidf_component.py b/tests/unit_tests/test_espidf_component.py index a7d871b2f8..3789eefc64 100644 --- a/tests/unit_tests/test_espidf_component.py +++ b/tests/unit_tests/test_espidf_component.py @@ -374,6 +374,18 @@ def test_generate_idf_component_yml_basic(tmp_component): assert result == "description: test\nrepository: http://aaa\n" +def test_generate_idf_component_yml_tolerates_malformed_metadata(tmp_component): + """A string repository is the URL itself; junk shapes drop instead of + crashing on a third-party manifest.""" + tmp_component.data = {"description": "test", "repository": "http://aaa"} + assert ( + generate_idf_component_yml(tmp_component) + == "description: test\nrepository: http://aaa\n" + ) + tmp_component.data = {"description": {"en": "x"}, "repository": 123} + assert generate_idf_component_yml(tmp_component) == "{}\n" + + def test_generate_idf_component_yml_with_dependencies(tmp_component, tmp_path): dep = IDFComponent("dep", "1.0", source=URLSource("http://dummy.com")) dep.path = tmp_path / "dep"