11from __future__ import annotations
22
3+ from collections .abc import Mapping
34from typing import Any
45
56from packaging .version import Version
67from pyproject_metadata import StandardMetadata
78
89from ..settings .skbuild_model import ScikitBuildSettings
9- from ._load_provider import load_provider
10+ from ._load_provider import load_dynamic_metadata
1011
1112__all__ = ["get_standard_metadata" ]
1213
@@ -17,37 +18,24 @@ def __dir__() -> list[str]:
1718
1819# If pyproject-metadata eventually supports updates, this can be simplified
1920def get_standard_metadata (
20- pyproject_dict : dict [str , Any ],
21+ pyproject_dict : Mapping [str , Any ],
2122 settings : ScikitBuildSettings ,
2223) -> StandardMetadata :
24+ new_pyproject_dict = dict (pyproject_dict )
2325 # Handle any dynamic metadata
24- calls : dict [frozenset [tuple [str , Any ]], set [str ]] = {}
25- for field , raw_settings in settings .metadata .items ():
26- if field not in pyproject_dict .get ("project" , {}).get ("dynamic" , []):
27- msg = f"{ field } is not in project.dynamic"
28- raise KeyError (msg )
29- if "provider" not in raw_settings :
26+ for field , provider , config in load_dynamic_metadata (settings .metadata ):
27+ if provider is None :
3028 msg = f"{ field } is missing provider"
3129 raise KeyError (msg )
32- calls .setdefault (frozenset (raw_settings .items ()), set ()).add (field )
33-
34- for call , fields in calls .items ():
35- args = dict (call )
36- provider = args .pop ("provider" )
37- provider_path = args .pop ("provider-path" , None )
38- computed = load_provider (provider , provider_path ).dynamic_metadata (
39- frozenset (fields ), args
40- )
41- if set (computed ) != fields :
42- msg = f"{ provider } did not return requested fields"
30+ if field not in pyproject_dict .get ("project" , {}).get ("dynamic" , []):
31+ msg = f"{ field } is not in project.dynamic"
4332 raise KeyError (msg )
44- pyproject_dict ["project" ].update (computed )
45- for field in fields :
46- pyproject_dict ["project" ]["dynamic" ].remove (field )
33+ new_pyproject_dict ["project" ][field ] = provider .dynamic_metadata (field , config )
34+ new_pyproject_dict ["project" ]["dynamic" ].remove (field )
4735
48- metadata = StandardMetadata .from_pyproject (pyproject_dict )
36+ metadata = StandardMetadata .from_pyproject (new_pyproject_dict )
4937 # pyproject-metadata normalizes the name - see https://github.com/FFY00/python-pyproject-metadata/pull/65
5038 # For scikit-build-core 0.5+, we keep the un-normalized name, and normalize it when using it for filenames
5139 if settings .minimum_version is None or settings .minimum_version >= Version ("0.5" ):
52- metadata .name = pyproject_dict ["project" ]["name" ]
40+ metadata .name = new_pyproject_dict ["project" ]["name" ]
5341 return metadata
0 commit comments