11from __future__ import annotations
22
3+ import dataclasses
34import os
45import platform
56import re
1819from ..errors import CMakeNotFoundError
1920from ..resources import resources
2021
21- __all__ = ["process_overrides" , "regex_match" ]
22+
23+ __all__ = ["OverrideRecord" , "process_overrides" , "regex_match" ]
2224
2325
2426def __dir__ () -> list [str ]:
@@ -29,6 +31,30 @@ def __dir__() -> list[str]:
2931 from collections .abc import Mapping
3032
3133
34+ @dataclasses .dataclass
35+ class OverrideRecord :
36+ """
37+ Record of the override action.
38+
39+ Saves the original and final values, and the override reasons.
40+ """
41+
42+ key : str
43+ """Settings key that is overridden."""
44+ original_value : Any | None
45+ """
46+ Original value in the pyproject table.
47+
48+ If the pyproject table did not have the key, this is a ``None``.
49+ """
50+ value : Any
51+ """Final value."""
52+ passed_all : dict [str , str ] | None
53+ """All if statements that passed (except the effective ``match_any``)."""
54+ passed_any : dict [str , str ] | None
55+ """All if.any statements that passed."""
56+
57+
3258def strtobool (value : str ) -> bool :
3359 """
3460 Converts a environment variable string into a boolean value.
@@ -257,20 +283,72 @@ def inherit_join(
257283 raise TypeError (msg )
258284
259285
286+ def record_override (
287+ * keys : str ,
288+ value : Any ,
289+ tool_skb : dict [str , Any ],
290+ overriden_items : dict [str , OverrideRecord ],
291+ passed_all : dict [str , str ] | None ,
292+ passed_any : dict [str , str ] | None ,
293+ ) -> None :
294+ full_key = "." .join (keys )
295+ # Get the original_value to construct the record
296+ if full_key in overriden_items :
297+ # We found the original value from a previous override record
298+ original_value = overriden_items [full_key ].original_value
299+ else :
300+ # Otherwise navigate the original pyproject table until we resolved all keys
301+ _dict_or_value = tool_skb
302+ keys_list = [* keys ]
303+ while keys_list :
304+ k = keys_list .pop (0 )
305+ if k not in _dict_or_value :
306+ # We hit a dead end so we imply the original_value was not set (`None`)
307+ original_value = None
308+ break
309+ _dict_or_value = _dict_or_value [k ]
310+ if isinstance (_dict_or_value , dict ):
311+ # If the value is a dict it is either the final value or we continue
312+ # to navigate it
313+ continue
314+ # Otherwise it should be the final value
315+ original_value = _dict_or_value
316+ if keys_list :
317+ msg = f"Could not navigate to the key { full_key } because { k } is a { type (_dict_or_value )} "
318+ raise TypeError (msg )
319+ break
320+ else :
321+ # We exhausted all keys so the current value should be the table key we are
322+ # interested in
323+ original_value = _dict_or_value
324+ # Now save the override record
325+ overriden_items [full_key ] = OverrideRecord (
326+ key = keys [- 1 ],
327+ original_value = original_value ,
328+ value = value ,
329+ passed_any = passed_any ,
330+ passed_all = passed_all ,
331+ )
332+
333+
260334def process_overrides (
261335 tool_skb : dict [str , Any ],
262336 * ,
263337 state : Literal ["sdist" , "wheel" , "editable" , "metadata_wheel" , "metadata_editable" ],
264338 retry : bool ,
265339 env : Mapping [str , str ] | None = None ,
266- ) -> set [str ]:
340+ ) -> tuple [ set [str ], dict [ str , OverrideRecord ] ]:
267341 """
268342 Process overrides into the main dictionary if they match. Modifies the input
269343 dictionary. Must be run from the package directory.
344+
345+ :return: A tuple of the set of matching overrides and a dict of changed keys and
346+ override record
270347 """
271348 has_dist_info = Path ("PKG-INFO" ).is_file ()
272349
273350 global_matched : set [str ] = set ()
351+ overriden_items : dict [str , OverrideRecord ] = {}
274352 for override in tool_skb .pop ("overrides" , []):
275353 passed_any : dict [str , str ] | None = None
276354 passed_all : dict [str , str ] | None = None
@@ -354,17 +432,33 @@ def process_overrides(
354432 inherit1 = inherit_override .get (key , {})
355433 if isinstance (value , dict ):
356434 for key2 , value2 in value .items ():
435+ record_override (
436+ * [key , key2 ],
437+ value = value ,
438+ tool_skb = tool_skb ,
439+ overriden_items = overriden_items ,
440+ passed_all = passed_all ,
441+ passed_any = passed_any ,
442+ )
357443 inherit2 = inherit1 .get (key2 , "none" )
358444 inner = tool_skb .get (key , {})
359445 inner [key2 ] = inherit_join (
360446 value2 , inner .get (key2 , None ), inherit2
361447 )
362448 tool_skb [key ] = inner
363449 else :
450+ record_override (
451+ key ,
452+ value = value ,
453+ tool_skb = tool_skb ,
454+ overriden_items = overriden_items ,
455+ passed_all = passed_all ,
456+ passed_any = passed_any ,
457+ )
364458 inherit_override_tmp = inherit_override or "none"
365459 if isinstance (inherit_override_tmp , dict ):
366460 assert not inherit_override_tmp
367461 tool_skb [key ] = inherit_join (
368462 value , tool_skb .get (key ), inherit_override_tmp
369463 )
370- return global_matched
464+ return global_matched , overriden_items
0 commit comments