diff --git a/BaseClasses.py b/BaseClasses.py index c0a77708..dddcfc3a 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -252,15 +252,20 @@ class MultiWorld(): range(1, self.players + 1)} def set_options(self, args: Namespace) -> None: + # TODO - remove this section once all worlds use options dataclasses + all_keys: Set[str] = {key for player in self.player_ids for key in + AutoWorld.AutoWorldRegister.world_types[self.game[player]].options_dataclass.type_hints} + for option_key in all_keys: + option = Utils.DeprecateDict(f"Getting options from multiworld is now deprecated. " + f"Please use `self.options.{option_key}` instead.") + option.update(getattr(args, option_key, {})) + setattr(self, option_key, option) + for player in self.player_ids: world_type = AutoWorld.AutoWorldRegister.world_types[self.game[player]] self.worlds[player] = world_type(self, player) self.worlds[player].random = self.per_slot_randoms[player] - for option_key in world_type.options_dataclass.type_hints: - option_values = getattr(args, option_key, {}) - setattr(self, option_key, option_values) - # TODO - remove this loop once all worlds use options dataclasses - options_dataclass: typing.Type[Options.PerGameCommonOptions] = self.worlds[player].options_dataclass + options_dataclass: typing.Type[Options.PerGameCommonOptions] = world_type.options_dataclass self.worlds[player].options = options_dataclass(**{option_key: getattr(args, option_key)[player] for option_key in options_dataclass.type_hints}) diff --git a/Utils.py b/Utils.py index 5955e924..f6e4a9ab 100644 --- a/Utils.py +++ b/Utils.py @@ -779,6 +779,25 @@ def deprecate(message: str): import warnings warnings.warn(message) + +class DeprecateDict(dict): + log_message: str + should_error: bool + + def __init__(self, message, error: bool = False) -> None: + self.log_message = message + self.should_error = error + super().__init__() + + def __getitem__(self, item: Any) -> Any: + if self.should_error: + deprecate(self.log_message) + elif __debug__: + import warnings + warnings.warn(self.log_message) + return super().__getitem__(item) + + def _extend_freeze_support() -> None: """Extend multiprocessing.freeze_support() to also work on Non-Windows for spawn.""" # upstream issue: https://github.com/python/cpython/issues/76327 diff --git a/worlds/AutoWorld.py b/worlds/AutoWorld.py index 5d0533e0..f56c39f6 100644 --- a/worlds/AutoWorld.py +++ b/worlds/AutoWorld.py @@ -77,6 +77,10 @@ class AutoWorldRegister(type): # create missing options_dataclass from legacy option_definitions # TODO - remove this once all worlds use options dataclasses if "options_dataclass" not in dct and "option_definitions" in dct: + # TODO - switch to deprecate after a version + if __debug__: + from warnings import warn + warn("Assigning options through option_definitions is now deprecated. Use options_dataclass instead.") dct["options_dataclass"] = make_dataclass(f"{name}Options", dct["option_definitions"].items(), bases=(PerGameCommonOptions,))