Options: Add more Option unit tests, add generic Option.__eq__, make cull_zeroes available to all OptionCounters #5905

This commit is contained in:
NewSoupVi
2026-04-18 12:49:19 +01:00
committed by GitHub
parent 66712bbd87
commit 0a742b6c98
2 changed files with 128 additions and 9 deletions

View File

@@ -212,6 +212,13 @@ class Option(typing.Generic[T], metaclass=AssembleOptions):
else:
return cls.name_lookup[value]
def __eq__(self, other: typing.Any) -> bool:
if isinstance(other, self.__class__):
return self.value == other.value
if isinstance(other, Option):
raise TypeError(f"Can't compare {self.__class__.__name__} with {other.__class__.__name__}")
return self.value == other
def __int__(self) -> T:
return self.value
@@ -930,13 +937,34 @@ class OptionDict(Option[typing.Dict[str, typing.Any]], VerifyKeys, typing.Mappin
class OptionCounter(OptionDict):
min: int | None = None
max: int | None = None
cull_zeroes: bool = False
def __init__(self, value: dict[str, int]) -> None:
super(OptionCounter, self).__init__(collections.Counter(value))
cleaned_dict = {}
invalid_value_errors = []
for key, value in value.items():
if not isinstance(value, (int, float)) or int(value) != value:
invalid_value_errors += [f"Invalid value {value} for key {key}, must be an integer."]
continue
if self.cull_zeroes and value == 0:
continue
cleaned_dict[key] = int(value)
if invalid_value_errors:
type_errors = [f"For option {self.__class__.__name__}:"] + invalid_value_errors
raise TypeError("\n".join(invalid_value_errors))
super(OptionCounter, self).__init__(collections.Counter(cleaned_dict))
def verify(self, world: type[World], player_name: str, plando_options: PlandoOptions) -> None:
super(OptionCounter, self).verify(world, player_name, plando_options)
self.verify_values()
def verify_values(self):
range_errors = []
if self.max is not None:
@@ -959,13 +987,8 @@ class OptionCounter(OptionDict):
class ItemDict(OptionCounter):
verify_item_name = True
min = 0
def __init__(self, value: dict[str, int]) -> None:
# Backwards compatibility: Cull 0s to make "in" checks behave the same as when this wasn't a OptionCounter
value = {item_name: amount for item_name, amount in value.items() if amount != 0}
super(ItemDict, self).__init__(value)
# Backwards compatibility: Cull 0s to make "in" checks behave the same as when this wasn't a OptionCounter
cull_zeroes = True
class OptionList(Option[typing.List[typing.Any]], VerifyKeys):