3232_DICT_STR_FIELDS = frozenset (
3333 [
3434 "urls" ,
35- "authors" ,
36- "maintainers" ,
3735 "scripts" ,
3836 "gui-scripts" ,
3937 ]
4038)
4139
40+ _LIST_DICT_FIELDS = frozenset (
41+ [
42+ "authors" ,
43+ "maintainers" ,
44+ ]
45+ )
46+
4247# "dynamic" and "name" can't be set or requested
4348_ALL_FIELDS = (
4449 _STR_FIELDS
4550 | _LIST_STR_FIELDS
4651 | _DICT_STR_FIELDS
52+ | _LIST_DICT_FIELDS
4753 | frozenset (
4854 [
4955 "optional-dependencies" ,
5359 )
5460)
5561
56- T = typing .TypeVar ("T" , bound = "str | list[str] | dict[str, str] | dict[str, list[str]]" )
62+ T = typing .TypeVar (
63+ "T" ,
64+ bound = "str | list[str] | list[dict[str, str]] | dict[str, str] | dict[str, list[str]] | dict[str, dict[str, str]]" ,
65+ )
5766
5867
5968def _process_dynamic_metadata (field : str , action : Callable [[str ], str ], result : T ) -> T :
6069 """
61- Helper function for processing the an action on the various possible metadata fields.
70+ Helper function for processing an action on the various possible metadata fields.
6271 """
6372
6473 if field in _STR_FIELDS :
@@ -77,7 +86,16 @@ def _process_dynamic_metadata(field: str, action: Callable[[str], str], result:
7786 ):
7887 msg = f"Field { field !r} must be a dictionary of strings"
7988 raise RuntimeError (msg )
80- return {k : action (v ) for k , v in result .items ()} # type: ignore[return-value]
89+ return {action (k ): action (v ) for k , v in result .items ()} # type: ignore[return-value]
90+ if field in _LIST_DICT_FIELDS :
91+ if not isinstance (result , list ) or not all (
92+ isinstance (k , str ) and isinstance (v , str )
93+ for d in result
94+ for k , v in d .items ()
95+ ):
96+ msg = f"Field { field !r} must be a dictionary of strings"
97+ raise RuntimeError (msg )
98+ return [{k : action (v ) for k , v in d .items ()} for d in result ] # type: ignore[return-value]
8199 if field == "entry-points" :
82100 if not isinstance (result , dict ) or not all (
83101 isinstance (d , dict )
@@ -86,6 +104,10 @@ def _process_dynamic_metadata(field: str, action: Callable[[str], str], result:
86104 ):
87105 msg = "Field 'entry-points' must be a dictionary of dictionary of strings"
88106 raise RuntimeError (msg )
107+ return {
108+ dk : {action (k ): action (v ) for k , v in dv .items ()}
109+ for dk , dv in result .items ()
110+ } # type: ignore[return-value]
89111 if field == "optional-dependencies" :
90112 if not isinstance (result , dict ) or not all (
91113 isinstance (v , list ) for v in result .values ()
0 commit comments