From e5980ac5f5027c739883137c04ea5135d3d5ee2d Mon Sep 17 00:00:00 2001 From: black-sliver <59490463+black-sliver@users.noreply.github.com> Date: Wed, 14 Feb 2024 22:56:21 +0100 Subject: [PATCH] Core: remove module level AutoWorld import (#2790) With BaseClasses running `worlds.__init__.py` and worlds importing `from BaseClasses`, this is likely to result in some extra code being run because of partial recursive imports. This now lazily loads `worlds` when needed, at which point `sys.modules` should be properly populated. --- BaseClasses.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 15470f82..40028001 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -18,11 +18,14 @@ import NetUtils import Options import Utils +if typing.TYPE_CHECKING: + from worlds import AutoWorld + class Group(TypedDict, total=False): name: str game: str - world: auto_world + world: "AutoWorld.World" players: Set[int] item_pool: Set[str] replacement_items: Dict[int, Optional[str]] @@ -55,7 +58,7 @@ class MultiWorld(): plando_texts: List[Dict[str, str]] plando_items: List[List[Dict[str, Any]]] plando_connections: List - worlds: Dict[int, auto_world] + worlds: Dict[int, "AutoWorld.World"] groups: Dict[int, Group] regions: RegionManager itempool: List[Item] @@ -219,6 +222,8 @@ class MultiWorld(): def add_group(self, name: str, game: str, players: Set[int] = frozenset()) -> Tuple[int, Group]: """Create a group with name and return the assigned player ID and group. If a group of this name already exists, the set of players is extended instead of creating a new one.""" + from worlds import AutoWorld + for group_id, group in self.groups.items(): if group["name"] == name: group["players"] |= players @@ -253,6 +258,8 @@ class MultiWorld(): def set_options(self, args: Namespace) -> None: # TODO - remove this section once all worlds use options dataclasses + from worlds import AutoWorld + 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: @@ -270,6 +277,8 @@ class MultiWorld(): for option_key in options_dataclass.type_hints}) def set_item_links(self): + from worlds import AutoWorld + item_links = {} replacement_prio = [False, True, None] for player in self.player_ids: @@ -1327,6 +1336,8 @@ class Spoiler: get_path(state, multiworld.get_region('Inverted Big Bomb Shop', player)) def to_file(self, filename: str) -> None: + from worlds import AutoWorld + def write_option(option_key: str, option_obj: Options.AssembleOptions) -> None: res = getattr(self.multiworld.worlds[player].options, option_key) display_name = getattr(option_obj, "display_name", option_key) @@ -1450,8 +1461,3 @@ def get_seed(seed: Optional[int] = None) -> int: random.seed(None) return random.randint(0, pow(10, seeddigits) - 1) return seed - - -from worlds import AutoWorld - -auto_world = AutoWorld.World