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_overides" , "regex_match" ]
22+ __all__ = ["OverrideRecord" , " process_overides" , "regex_match" ]
2223
2324
2425def __dir__ () -> list [str ]:
@@ -29,6 +30,30 @@ 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+ original_value : Any | None
44+ """
45+ Original value in the pyproject table.
46+
47+ If the pyproject table did not have the key, this is a ``None``.
48+ """
49+ value : Any
50+ """Final value."""
51+ passed_all : dict [str , str ] | None
52+ """All if statements that passed (except the effective ``match_any``)."""
53+ passed_any : dict [str , str ] | None
54+ """All if.any statements that passed."""
55+
56+
3257def strtobool (value : str ) -> bool :
3358 """
3459 Converts a environment variable string into a boolean value.
@@ -257,20 +282,72 @@ def inherit_join(
257282 raise TypeError (msg )
258283
259284
285+ def record_override (
286+ * keys : str ,
287+ value : Any ,
288+ tool_skb : dict [str , Any ],
289+ overriden_items : dict [str , OverrideRecord ],
290+ passed_all : dict [str , str ] | None ,
291+ passed_any : dict [str , str ] | None ,
292+ ) -> None :
293+ full_key = "." .join (keys )
294+ # Get the original_value to construct the record
295+ if full_key in overriden_items :
296+ # We found the original value from a previous override record
297+ original_value = overriden_items [full_key ].original_value
298+ else :
299+ # Otherwise navigate the original pyproject table until we resolved all keys
300+ _dict_or_value = tool_skb
301+ keys_list = [* keys ]
302+ while keys_list :
303+ k = keys_list .pop (0 )
304+ if k not in _dict_or_value :
305+ # We hit a dead end so we imply the original_value was not set (`None`)
306+ original_value = None
307+ break
308+ _dict_or_value = _dict_or_value [k ]
309+ if isinstance (_dict_or_value , dict ):
310+ # If the value is a dict it is either the final value or we continue
311+ # to navigate it
312+ continue
313+ # Otherwise it should be the final value
314+ original_value = _dict_or_value
315+ if keys_list :
316+ msg = f"Could not navigate to the key { full_key } because { k } is a { type (_dict_or_value )} "
317+ raise TypeError (msg )
318+ break
319+ else :
320+ # We exhausted all keys so the current value should be the table key we are
321+ # interested in
322+ original_value = _dict_or_value
323+ # Now save the override record
324+ overriden_items [full_key ] = OverrideRecord (
325+ key = keys [- 1 ],
326+ original_value = original_value ,
327+ value = value ,
328+ passed_any = passed_any ,
329+ passed_all = passed_all ,
330+ )
331+
332+
260333def process_overides (
261334 tool_skb : dict [str , Any ],
262335 * ,
263336 state : Literal ["sdist" , "wheel" , "editable" , "metadata_wheel" , "metadata_editable" ],
264337 retry : bool ,
265338 env : Mapping [str , str ] | None = None ,
266- ) -> set [str ]:
339+ ) -> tuple [ set [str ], dict [ str , OverrideRecord ] ]:
267340 """
268341 Process overrides into the main dictionary if they match. Modifies the input
269342 dictionary. Must be run from the package directory.
343+
344+ :return: A tuple of the set of matching overrides and a dict of changed keys and
345+ override record
270346 """
271347 has_dist_info = Path ("PKG-INFO" ).is_file ()
272348
273349 global_matched : set [str ] = set ()
350+ overriden_items : dict [str , OverrideRecord ] = {}
274351 for override in tool_skb .pop ("overrides" , []):
275352 passed_any : dict [str , str ] | None = None
276353 passed_all : dict [str , str ] | None = None
@@ -354,17 +431,33 @@ def process_overides(
354431 inherit1 = inherit_override .get (key , {})
355432 if isinstance (value , dict ):
356433 for key2 , value2 in value .items ():
434+ record_override (
435+ * [key , key2 ],
436+ value = value ,
437+ tool_skb = tool_skb ,
438+ overriden_items = overriden_items ,
439+ passed_all = passed_all ,
440+ passed_any = passed_any ,
441+ )
357442 inherit2 = inherit1 .get (key2 , "none" )
358443 inner = tool_skb .get (key , {})
359444 inner [key2 ] = inherit_join (
360445 value2 , inner .get (key2 , None ), inherit2
361446 )
362447 tool_skb [key ] = inner
363448 else :
449+ record_override (
450+ key ,
451+ value = value ,
452+ tool_skb = tool_skb ,
453+ overriden_items = overriden_items ,
454+ passed_all = passed_all ,
455+ passed_any = passed_any ,
456+ )
364457 inherit_override_tmp = inherit_override or "none"
365458 if isinstance (inherit_override_tmp , dict ):
366459 assert not inherit_override_tmp
367460 tool_skb [key ] = inherit_join (
368461 value , tool_skb .get (key ), inherit_override_tmp
369462 )
370- return global_matched
463+ return global_matched , overriden_items
0 commit comments