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+ __all__ = ["OverrideRecord" , " process_overrides" , "regex_match" ]
2223
2324
2425def __dir__ () -> list [str ]:
@@ -29,6 +30,34 @@ def __dir__() -> list[str]:
2930 from collections .abc import Mapping
3031
3132
33+ @dataclasses .dataclass
34+ class OverrideRecord :
35+ """
36+ Record of the override action.
37+
38+ Saves the original and final values, and the override reasons.
39+ """
40+
41+ key : str
42+ """Settings key that is overridden."""
43+
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+
51+ value : Any
52+ """Final value."""
53+
54+ passed_all : dict [str , str ] | None
55+ """All if statements that passed (except the effective ``match_any``)."""
56+
57+ passed_any : dict [str , str ] | None
58+ """All if.any statements that passed."""
59+
60+
3261def strtobool (value : str ) -> bool :
3362 """
3463 Converts a environment variable string into a boolean value.
@@ -257,20 +286,72 @@ def inherit_join(
257286 raise TypeError (msg )
258287
259288
289+ def record_override (
290+ * keys : str ,
291+ value : Any ,
292+ tool_skb : dict [str , Any ],
293+ overriden_items : dict [str , OverrideRecord ],
294+ passed_all : dict [str , str ] | None ,
295+ passed_any : dict [str , str ] | None ,
296+ ) -> None :
297+ full_key = "." .join (keys )
298+ # Get the original_value to construct the record
299+ if full_key in overriden_items :
300+ # We found the original value from a previous override record
301+ original_value = overriden_items [full_key ].original_value
302+ else :
303+ # Otherwise navigate the original pyproject table until we resolved all keys
304+ _dict_or_value = tool_skb
305+ keys_list = [* keys ]
306+ while keys_list :
307+ k = keys_list .pop (0 )
308+ if k not in _dict_or_value :
309+ # We hit a dead end so we imply the original_value was not set (`None`)
310+ original_value = None
311+ break
312+ _dict_or_value = _dict_or_value [k ]
313+ if isinstance (_dict_or_value , dict ):
314+ # If the value is a dict it is either the final value or we continue
315+ # to navigate it
316+ continue
317+ # Otherwise it should be the final value
318+ original_value = _dict_or_value
319+ if keys_list :
320+ msg = f"Could not navigate to the key { full_key } because { k } is a { type (_dict_or_value )} "
321+ raise TypeError (msg )
322+ break
323+ else :
324+ # We exhausted all keys so the current value should be the table key we are
325+ # interested in
326+ original_value = _dict_or_value
327+ # Now save the override record
328+ overriden_items [full_key ] = OverrideRecord (
329+ key = keys [- 1 ],
330+ original_value = original_value ,
331+ value = value ,
332+ passed_any = passed_any ,
333+ passed_all = passed_all ,
334+ )
335+
336+
260337def process_overrides (
261338 tool_skb : dict [str , Any ],
262339 * ,
263340 state : Literal ["sdist" , "wheel" , "editable" , "metadata_wheel" , "metadata_editable" ],
264341 retry : bool ,
265342 env : Mapping [str , str ] | None = None ,
266- ) -> set [str ]:
343+ ) -> tuple [ set [str ], dict [ str , OverrideRecord ] ]:
267344 """
268345 Process overrides into the main dictionary if they match. Modifies the input
269346 dictionary. Must be run from the package directory.
347+
348+ :return: A tuple of the set of matching overrides and a dict of changed keys and
349+ override record
270350 """
271351 has_dist_info = Path ("PKG-INFO" ).is_file ()
272352
273353 global_matched : set [str ] = set ()
354+ overriden_items : dict [str , OverrideRecord ] = {}
274355 for override in tool_skb .pop ("overrides" , []):
275356 passed_any : dict [str , str ] | None = None
276357 passed_all : dict [str , str ] | None = None
@@ -354,17 +435,33 @@ def process_overrides(
354435 inherit1 = inherit_override .get (key , {})
355436 if isinstance (value , dict ):
356437 for key2 , value2 in value .items ():
438+ record_override (
439+ * [key , key2 ],
440+ value = value2 ,
441+ tool_skb = tool_skb ,
442+ overriden_items = overriden_items ,
443+ passed_all = passed_all ,
444+ passed_any = passed_any ,
445+ )
357446 inherit2 = inherit1 .get (key2 , "none" )
358447 inner = tool_skb .get (key , {})
359448 inner [key2 ] = inherit_join (
360449 value2 , inner .get (key2 , None ), inherit2
361450 )
362451 tool_skb [key ] = inner
363452 else :
453+ record_override (
454+ key ,
455+ value = value ,
456+ tool_skb = tool_skb ,
457+ overriden_items = overriden_items ,
458+ passed_all = passed_all ,
459+ passed_any = passed_any ,
460+ )
364461 inherit_override_tmp = inherit_override or "none"
365462 if isinstance (inherit_override_tmp , dict ):
366463 assert not inherit_override_tmp
367464 tool_skb [key ] = inherit_join (
368465 value , tool_skb .get (key ), inherit_override_tmp
369466 )
370- return global_matched
467+ return global_matched , overriden_items
0 commit comments