lang.py: make HashableMap generic, and use in Spec (#50229)

This commit is contained in:
Harmen Stoppels 2025-05-05 10:45:11 +02:00 committed by GitHub
parent 7cd039d022
commit 02501bc4af
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 19 additions and 21 deletions

View File

@ -225,10 +225,14 @@ def setup(sphinx):
("py:class", "llnl.util.lang.T"),
("py:class", "llnl.util.lang.KT"),
("py:class", "llnl.util.lang.VT"),
("py:class", "llnl.util.lang.K"),
("py:class", "llnl.util.lang.V"),
("py:class", "llnl.util.lang.ClassPropertyType"),
("py:obj", "llnl.util.lang.KT"),
("py:obj", "llnl.util.lang.VT"),
("py:obj", "llnl.util.lang.ClassPropertyType"),
("py:obj", "llnl.util.lang.K"),
("py:obj", "llnl.util.lang.V"),
]
# The reST default role (used for this markup: `text`) to use for all documents.

View File

@ -21,6 +21,7 @@
Dict,
Generic,
Iterable,
Iterator,
List,
Mapping,
Optional,
@ -436,46 +437,39 @@ def add_func_to_class(name, func):
return cls
K = TypeVar("K")
V = TypeVar("V")
@lazy_lexicographic_ordering
class HashableMap(collections.abc.MutableMapping):
class HashableMap(typing.MutableMapping[K, V]):
"""This is a hashable, comparable dictionary. Hash is performed on
a tuple of the values in the dictionary."""
__slots__ = ("dict",)
def __init__(self):
self.dict = {}
self.dict: Dict[K, V] = {}
def __getitem__(self, key):
def __getitem__(self, key: K) -> V:
return self.dict[key]
def __setitem__(self, key, value):
def __setitem__(self, key: K, value: V) -> None:
self.dict[key] = value
def __iter__(self):
def __iter__(self) -> Iterator[K]:
return iter(self.dict)
def __len__(self):
def __len__(self) -> int:
return len(self.dict)
def __delitem__(self, key):
def __delitem__(self, key: K) -> None:
del self.dict[key]
def _cmp_iter(self):
for _, v in sorted(self.items()):
yield v
def copy(self):
"""Type-agnostic clone method. Preserves subclass type."""
# Construct a new dict of my type
self_type = type(self)
clone = self_type()
# Copy everything from this dict into it.
for key in self:
clone[key] = self[key].copy()
return clone
def match_predicate(*args):
"""Utility function for making string matching predicates.

View File

@ -2492,7 +2492,7 @@ def _spec_clauses(
# TODO: variant="*" means 'variant is defined to something', which used to
# be meaningless in concretization, as all variants had to be defined. But
# now that variants can be conditional, it should force a variant to exist.
if variant.value == ("*",):
if not variant.values:
continue
for value in variant.values:

View File

@ -837,7 +837,7 @@ def _shared_subset_pair_iterate(container1, container2):
b_idx += 1
class FlagMap(lang.HashableMap):
class FlagMap(lang.HashableMap[str, List[CompilerFlag]]):
__slots__ = ("spec",)
def __init__(self, spec):
@ -4490,7 +4490,7 @@ def has_virtual_dependency(self, virtual: str) -> bool:
return bool(self.dependencies(virtuals=(virtual,)))
class VariantMap(lang.HashableMap):
class VariantMap(lang.HashableMap[str, vt.VariantValue]):
"""Map containing variant instances. New values can be added only
if the key is not already present."""