diff --git a/nomenclature/code.py b/nomenclature/code.py index a02350ac..b936a18b 100644 --- a/nomenclature/code.py +++ b/nomenclature/code.py @@ -16,6 +16,7 @@ class Code(BaseModel): description: str | None = None file: Union[str, Path] | None = None extra_attributes: Dict[str, Any] = {} + repository: str | None = None def __eq__(self, other) -> bool: return self.model_dump(exclude="file") == other.model_dump(exclude="file") diff --git a/nomenclature/codelist.py b/nomenclature/codelist.py index b26fea85..e2e1b40d 100644 --- a/nomenclature/codelist.py +++ b/nomenclature/codelist.py @@ -174,7 +174,7 @@ def from_directory( cls, name: str, path: Path, - config: NomenclatureConfig = None, + config: NomenclatureConfig | None = None, file_glob_pattern: str = "**/*", ): """Initialize a CodeList from a directory with codelist files @@ -200,9 +200,12 @@ def from_directory( for repo in getattr( config.definitions, name.lower(), CodeListConfig() ).repositories: - repo_path = config.repositories[repo].local_path / "definitions" / name - code_list = ( - cls._parse_codelist_dir(repo_path, file_glob_pattern) + code_list + code_list.extend( + cls._parse_codelist_dir( + config.repositories[repo].local_path / "definitions" / name, + file_glob_pattern, + repo, + ) ) errors = ErrorCollector() mapping: Dict[str, Code] = {} @@ -217,7 +220,12 @@ def from_directory( return cls(name=name, mapping=mapping) @classmethod - def _parse_codelist_dir(cls, path: Path, file_glob_pattern: str = "**/*"): + def _parse_codelist_dir( + cls, + path: Path, + file_glob_pattern: str = "**/*", + repository: str | None = None, + ): code_list: List[Code] = [] for yaml_file in ( f @@ -229,6 +237,8 @@ def _parse_codelist_dir(cls, path: Path, file_glob_pattern: str = "**/*"): for code_dict in _code_list: code = cls.code_basis.from_dict(code_dict) code.file = yaml_file.relative_to(path.parent).as_posix() + if repository: + code.repository = repository code_list.append(code) code_list = cls._parse_and_replace_tags(code_list, path, file_glob_pattern) @@ -569,7 +579,7 @@ def from_directory( cls, name: str, path: Path, - config: NomenclatureConfig = None, + config: NomenclatureConfig | None = None, file_glob_pattern: str = "**/*", ): """Initialize a RegionCodeList from a directory with codelist files @@ -617,7 +627,7 @@ def from_directory( code_list, repo_path, file_glob_pattern, - repository=config.definitions.region.repositories, + repository=repo, ) code_list = cls._parse_and_replace_tags( code_list, repo_path, file_glob_pattern @@ -656,7 +666,7 @@ def _parse_region_code_dir( code_list: List[Code], path: Path, file_glob_pattern: str = "**/*", - repository: Path = None, + repository: str | None = None, ) -> List[RegionCode]: """""" diff --git a/tests/test_codelist.py b/tests/test_codelist.py index 5ebcad8e..b5b68aaf 100644 --- a/tests/test_codelist.py +++ b/tests/test_codelist.py @@ -351,6 +351,22 @@ def test_multiple_external_repos(): clean_up_external_repos(nomenclature_config.repositories) +def test_multiple_external_repos(): + nomenclature_config = NomenclatureConfig.from_file( + TEST_DATA_DIR / "nomenclature_configs" / "multiple_repos_per_dimension.yaml" + ) + try: + variable_code_list = VariableCodeList.from_directory( + "variable", + TEST_DATA_DIR / "nomenclature_configs" / "variable", + nomenclature_config, + ) + assert variable_code_list["Final Energy"].repository == "common-definitions" + assert variable_code_list["Employment"].repository == "legacy-definitions" + finally: + clean_up_external_repos(nomenclature_config.repositories) + + @pytest.mark.parametrize("CodeList", [VariableCodeList, CodeList]) def test_variable_codelist_with_duplicates_raises(CodeList): error_string = "2 errors:\n.*Some Variable\n.*Some other Variable"