diff --git a/.efrocachemap b/.efrocachemap index 6a1363ef..cdd76c1a 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -3992,50 +3992,50 @@ "assets/src/ba_data/python/ba/_generated/__init__.py": "https://files.ballistica.net/cache/ba1/ee/e8/cad05aa531c7faf7ff7b96db7f6e", "assets/src/ba_data/python/ba/_generated/enums.py": "https://files.ballistica.net/cache/ba1/b2/e5/0ee0561e16257a32830645239f34", "ballisticacore-windows/Generic/BallisticaCore.ico": "https://files.ballistica.net/cache/ba1/89/c0/e32c7d2a35dc9aef57cc73b0911a", - "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/25/53/6a4e5bf41e72039c2e9505314fc8", - "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d5/6b/6781774528935242d5f6d19d7576", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/63/08/568b9c8e0fdc44ae10b80506ec9b", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/67/9b/e9d3ca213933b900da272548b99c", - "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/9d/55/1835bbc7bf7da93cf6b3b2f2829d", - "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/5f/a5/bfc94a98055c65d21ce0cef290d8", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/48/b1/e78c8b6c5ff9552d423fc58e87d7", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e5/ba/00bbdbe267193e998645b75e0b30", - "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/04/d9/aca25c3290baa86d3527db214df0", - "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d7/2d/36b55e57c8911687b34001ae64bf", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/04/c2/66e462754041aa48386da42ea36b", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/19/84/5b1457c336be08ae443563e562cb", - "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/d6/e1/b42b8b4c786cf18bccf545465921", - "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/e3/5d/67bb3a15c0399b6bcb2a7843e275", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/87/00/9f492f517a5ef8c964bd60a01a8f", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/90/de/ad8ad53c2e67b71809d64d1479c8", - "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/26/ea/b486ae0f48bf72a0d5e6bcef0dfe", - "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/7f/df/cddaeaa46f35d87ba3bbdc3a4603", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/61/ba/938a1cd1c456ef81a6210f987470", - "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/6d/f8/8c1577c4ecc92a715dd70facddbb", - "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/d9/47/82e658f9bd119855a6ad75028603", - "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c6/63/96f9df7f919f44e6d4566eba5ae0", - "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7a/dc/36b1839661638396bf17b7af90e4", - "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/71/82/4679ec67236513a61a8260035d3a", - "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/26/c0/610acfd8b1eebea05169e78af27d", - "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ee/e5/46b03f0ee43affd5a800581941b2", - "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c7/f7/e01f4702338f9b09d996a2a7f445", - "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7d/a5/04080ea482994ce0135683fa5340", - "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/db/fe/6fb2d9e508ede8f5679fb258c520", - "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/20/ce/34c62328d5afb90d2848f1628d42", - "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/51/e2/870956a5cdb0f216d4386f0417ad", - "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/22/64/a8be5f32f808f536266857256162", - "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/b4/0b/48637a34a9b5b8727c73a6261c6d", - "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/94/15/1d8e7e30526b3182064ec6afa904", - "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/62/b1/a3cbed9e6a5f96b433ad657f0c36", - "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6f/bc/63aa452a2ae2f747f4a2e68da687", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/32/39/8618f51e38e8043cf2f3a20ac03b", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/c8/19/7c0eebd3b60065e62655b59c786b", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/ea/59/03b3db146092f14719782d1d017e", - "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/e8/3a/c2a9a2c00e230c0ed181dcf2df76", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/be/02/e7c834e3dd661881e968bcc1cc9b", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/e5/f4/7592825467eca48b95437f4d4fc3", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/d8/3a/b43c8a2fb8778d2f33cb2d3ccb94", - "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/7e/67/b6f493081e8b4c158fe7f3b38004", + "build/prefab/full/linux_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/8e/62/a0b2c36ae4c9946ff6d2bbe60536", + "build/prefab/full/linux_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/9c/6d/1958ddd5d36372cd05984f3f1491", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/06/b0/3383daecf55590156851be31ddca", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/10/2d/73f8d6e8d15b5d8e613768eab9fe", + "build/prefab/full/linux_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/74/bf/2493e50c4a6211c05d46e61ee690", + "build/prefab/full/linux_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/af/be/a8c7f280bb5c0eb70feacc95cb70", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/f4/14/f16305c17e826ba5304e3560b37b", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2e/ee/5cc95994525b837afd6b0a344e07", + "build/prefab/full/mac_arm64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/6e/25/2eb19336aa18f243c3818f3d684e", + "build/prefab/full/mac_arm64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/63/3d/52c08aceafbba0ec1ee22929e233", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/3b/76/2651de6a14dfac76523954383768", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/97/11/8c34021257c1717d12e02755e361", + "build/prefab/full/mac_x86_64_gui/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/5e/35/16f3aa9f5dddfae1e8a8f44bd288", + "build/prefab/full/mac_x86_64_gui/release/ballisticacore": "https://files.ballistica.net/cache/ba1/ed/68/61d55a826b44c31804e53fe9f2f8", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/27/da/ae61a120f83942040698e3c62795", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/21/a5/7dfb46884bf50c97a1b170161de5", + "build/prefab/full/windows_x86_gui/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/bc/b3/d41ad33e7a27bb687126b59f6a63", + "build/prefab/full/windows_x86_gui/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/73/d0/9ea990d6c6a22eafe5e39b7c9bf0", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/89/35/af5225fb6248d580ce4a62c0dff7", + "build/prefab/full/windows_x86_server/release/dist/BallisticaCoreHeadless.exe": "https://files.ballistica.net/cache/ba1/1b/ea/24741222a48bf6b0ae2b33c345ee", + "build/prefab/lib/linux_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/36/63/4eea616b1c44d1fc80881d583063", + "build/prefab/lib/linux_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/78/eb/361435ad4449473fcc8e79b2d253", + "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/80/16/8ebbc8bdb0447272ad4a7322e15c", + "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/19/be/351a09a6c93b0292ff6da126d235", + "build/prefab/lib/linux_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9c/1b/9bdd35fc65ef082610332b01a022", + "build/prefab/lib/linux_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6c/eb/95720079e16a95041f84237aecfc", + "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/23/55/28f16c8fe69a5bb4fa04f623d24e", + "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/6e/c0/b576e08d61b99805b78a85e443d8", + "build/prefab/lib/mac_arm64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7b/d0/f2187807f1a355fd5daf06ba9a89", + "build/prefab/lib/mac_arm64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/32/1b/b420610ac31a1cc159e5bfedbf90", + "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/44/42/217f4f3ae262675236d95b4f041a", + "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3b/75/a9bf8aa210df3295631b8ef64fe0", + "build/prefab/lib/mac_x86_64_gui/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c9/61/d337eb64ba80d29129b3baaaefb2", + "build/prefab/lib/mac_x86_64_gui/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/a4/73/03ba13813ed884e063bc070cb3a3", + "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/53/53/66b919b922f258938548e46bdce3", + "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/fb/51/05b095fe3c094e9709d68fc69cda", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/80/9f/a4168a2e1ff84f84f753321171b8", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/60/bb/dbea49521034f0f31e8af2d52472", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/31/90/95e999162f9ad805643b4b9db8d4", + "build/prefab/lib/windows/Debug_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/7a/8f/1a82c5c7bdc2d684428d7670e712", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.lib": "https://files.ballistica.net/cache/ba1/87/39/769a4deb741ad42185e05c3bfc85", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreGenericInternal.pdb": "https://files.ballistica.net/cache/ba1/9c/16/c967168be6fa2dd864724d4ac69c", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.lib": "https://files.ballistica.net/cache/ba1/a6/09/908ad0fda6281e0c07b5f84c89cc", + "build/prefab/lib/windows/Release_Win32/BallisticaCoreHeadlessInternal.pdb": "https://files.ballistica.net/cache/ba1/80/4d/03fb2d4ffb5543f78c4f25795bc9", "src/ballistica/generated/python_embedded/binding.inc": "https://files.ballistica.net/cache/ba1/6e/6f/004b696e9a13b083069374e4bb6a", "src/ballistica/generated/python_embedded/bootstrap.inc": "https://files.ballistica.net/cache/ba1/d3/db/e73d4dcf1280d5f677c3cf8b47c3" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index bb0a376a..b482459c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.2 (20615, 2022-06-23) +### 1.7.2 (20617, 2022-06-24) - Minor fixes in some minigames (Thanks Droopy!) - Fixed a bug preventing 'clients' arg from working in _ba.chatmessage (Thanks imayushsaini!) - Fixed a bug where ba.Player.getdelegate(doraise=True) could return None instead of raising a ba.DelegateNotFoundError (thanks Dliwk!) diff --git a/assets/src/ba_data/python/ba/_accountv1.py b/assets/src/ba_data/python/ba/_accountv1.py index 2f72f19d..0b07457a 100644 --- a/assets/src/ba_data/python/ba/_accountv1.py +++ b/assets/src/ba_data/python/ba/_accountv1.py @@ -11,7 +11,7 @@ from typing import TYPE_CHECKING import _ba if TYPE_CHECKING: - from typing import Any, Optional + from typing import Any class AccountV1Subsystem: @@ -23,12 +23,12 @@ class AccountV1Subsystem: """ def __init__(self) -> None: - self.account_tournament_list: Optional[tuple[int, list[str]]] = None + self.account_tournament_list: tuple[int, list[str]] | None = None # FIXME: should abstract/structure these. self.tournament_info: dict = {} self.league_rank_cache: dict = {} - self.last_post_purchase_message_time: Optional[float] = None + self.last_post_purchase_message_time: float | None = None # If we try to run promo-codes due to launch-args/etc we might # not be signed in yet; go ahead and queue them up in that case. @@ -73,7 +73,7 @@ class AccountV1Subsystem: return self.league_rank_cache.get('info', None) def get_league_rank_points(self, - data: Optional[dict[str, Any]], + data: dict[str, Any] | None, subset: str = None) -> int: """(internal)""" if data is None: diff --git a/assets/src/ba_data/python/ba/_activitytypes.py b/assets/src/ba_data/python/ba/_activitytypes.py index 8007130a..78eb6064 100644 --- a/assets/src/ba_data/python/ba/_activitytypes.py +++ b/assets/src/ba_data/python/ba/_activitytypes.py @@ -14,7 +14,6 @@ from ba._player import EmptyPlayer # pylint: disable=W0611 from ba._team import EmptyTeam # pylint: disable=W0611 if TYPE_CHECKING: - from typing import Optional import ba from ba._lobby import JoinInfo @@ -65,9 +64,9 @@ class JoinActivity(Activity[EmptyPlayer, EmptyTeam]): # In vr mode we don't want stuff moving around. self.use_fixed_vr_overlay = True - self._background: Optional[ba.Actor] = None - self._tips_text: Optional[ba.Actor] = None - self._join_info: Optional[JoinInfo] = None + self._background: ba.Actor | None = None + self._tips_text: ba.Actor | None = None + self._join_info: JoinInfo | None = None def on_transition_in(self) -> None: # pylint: disable=cyclic-import @@ -99,7 +98,7 @@ class TransitionActivity(Activity[EmptyPlayer, EmptyTeam]): def __init__(self, settings: dict): super().__init__(settings) - self._background: Optional[ba.Actor] = None + self._background: ba.Actor | None = None def on_transition_in(self) -> None: # pylint: disable=cyclic-import @@ -127,20 +126,20 @@ class ScoreScreenActivity(Activity[EmptyPlayer, EmptyTeam]): inherits_vr_camera_offset = True use_fixed_vr_overlay = True - default_music: Optional[MusicType] = MusicType.SCORES + default_music: MusicType | None = MusicType.SCORES def __init__(self, settings: dict): super().__init__(settings) self._birth_time = _ba.time() self._min_view_time = 5.0 self._allow_server_transition = False - self._background: Optional[ba.Actor] = None - self._tips_text: Optional[ba.Actor] = None + self._background: ba.Actor | None = None + self._tips_text: ba.Actor | None = None self._kicked_off_server_shutdown = False self._kicked_off_server_restart = False self._default_show_tips = True - self._custom_continue_message: Optional[ba.Lstr] = None - self._server_transitioning: Optional[bool] = None + self._custom_continue_message: ba.Lstr | None = None + self._server_transitioning: bool | None = None def on_player_join(self, player: EmptyPlayer) -> None: from ba._general import WeakCall diff --git a/assets/src/ba_data/python/ba/_appdelegate.py b/assets/src/ba_data/python/ba/_appdelegate.py index 12628701..9f967aeb 100644 --- a/assets/src/ba_data/python/ba/_appdelegate.py +++ b/assets/src/ba_data/python/ba/_appdelegate.py @@ -6,7 +6,7 @@ from __future__ import annotations from typing import TYPE_CHECKING if TYPE_CHECKING: - from typing import Optional, Callable + from typing import Callable import ba @@ -18,8 +18,8 @@ class AppDelegate: def create_default_game_settings_ui( self, gameclass: type[ba.GameActivity], - sessiontype: type[ba.Session], settings: Optional[dict], - completion_call: Callable[[Optional[dict]], None]) -> None: + sessiontype: type[ba.Session], settings: dict | None, + completion_call: Callable[[dict | None], None]) -> None: """Launch a UI to configure the given game config. It should manipulate the contents of config and call completion_call diff --git a/assets/src/ba_data/python/ba/_asyncio.py b/assets/src/ba_data/python/ba/_asyncio.py index 40e53c92..e10333bf 100644 --- a/assets/src/ba_data/python/ba/_asyncio.py +++ b/assets/src/ba_data/python/ba/_asyncio.py @@ -13,12 +13,11 @@ from typing import TYPE_CHECKING import asyncio if TYPE_CHECKING: - from typing import Optional import ba # Our timer and event loop for the ballistica game thread. -_asyncio_timer: Optional[ba.Timer] = None -_asyncio_event_loop: Optional[asyncio.AbstractEventLoop] = None +_asyncio_timer: ba.Timer | None = None +_asyncio_event_loop: asyncio.AbstractEventLoop | None = None def setup_asyncio() -> asyncio.AbstractEventLoop: diff --git a/assets/src/ba_data/python/ba/_coopgame.py b/assets/src/ba_data/python/ba/_coopgame.py index c3435f3c..2e987813 100644 --- a/assets/src/ba_data/python/ba/_coopgame.py +++ b/assets/src/ba_data/python/ba/_coopgame.py @@ -10,7 +10,7 @@ from ba._gameactivity import GameActivity from ba._general import WeakCall if TYPE_CHECKING: - from typing import Any, Sequence, Optional + from typing import Any, Sequence from bastd.actor.playerspaz import PlayerSpaz import ba @@ -40,8 +40,8 @@ class CoopGameActivity(GameActivity[PlayerType, TeamType]): # Cache these for efficiency. self._achievements_awarded: set[str] = set() - self._life_warning_beep: Optional[ba.Actor] = None - self._life_warning_beep_timer: Optional[ba.Timer] = None + self._life_warning_beep: ba.Actor | None = None + self._life_warning_beep_timer: ba.Timer | None = None self._warn_beeps_sound = _ba.getsound('warnBeeps') def on_begin(self) -> None: diff --git a/assets/src/ba_data/python/ba/_coopsession.py b/assets/src/ba_data/python/ba/_coopsession.py index 4338c3f9..b04b5915 100644 --- a/assets/src/ba_data/python/ba/_coopsession.py +++ b/assets/src/ba_data/python/ba/_coopsession.py @@ -9,7 +9,7 @@ import _ba from ba._session import Session if TYPE_CHECKING: - from typing import Any, Optional, Callable, Sequence + from typing import Any, Callable, Sequence import ba TEAM_COLORS = [(0.2, 0.4, 1.6)] @@ -33,7 +33,7 @@ class CoopSession(Session): # Note: even though these are instance vars, we annotate them at the # class level so that docs generation can access their types. - campaign: Optional[ba.Campaign] + campaign: ba.Campaign | None """The ba.Campaign instance this Session represents, or None if there is no associated Campaign.""" @@ -67,21 +67,21 @@ class CoopSession(Session): max_players=max_players) # Tournament-ID if we correspond to a co-op tournament (otherwise None) - self.tournament_id: Optional[str] = ( + self.tournament_id: str | None = ( app.coop_session_args.get('tournament_id')) self.campaign = getcampaign(app.coop_session_args['campaign']) self.campaign_level_name: str = app.coop_session_args['level'] self._ran_tutorial_activity = False - self._tutorial_activity: Optional[ba.Activity] = None + self._tutorial_activity: ba.Activity | None = None self._custom_menu_ui: list[dict[str, Any]] = [] # Start our joining screen. self.setactivity(_ba.newactivity(CoopJoinActivity)) - self._next_game_instance: Optional[ba.GameActivity] = None - self._next_game_level_name: Optional[str] = None + self._next_game_instance: ba.GameActivity | None = None + self._next_game_level_name: str | None = None self._update_on_deck_game_instances() def get_current_game_instance(self) -> ba.GameActivity: @@ -124,7 +124,7 @@ class CoopSession(Session): levels = self.campaign.levels level = self.campaign.getlevel(self.campaign_level_name) - nextlevel: Optional[ba.Level] + nextlevel: ba.Level | None if level.index < len(levels) - 1: nextlevel = levels[level.index + 1] else: diff --git a/assets/src/ba_data/python/ba/_gameactivity.py b/assets/src/ba_data/python/ba/_gameactivity.py index 2580e4c0..c432e17a 100644 --- a/assets/src/ba_data/python/ba/_gameactivity.py +++ b/assets/src/ba_data/python/ba/_gameactivity.py @@ -19,7 +19,7 @@ from ba._player import PlayerInfo from ba import _map if TYPE_CHECKING: - from typing import Optional, Any, Callable, Sequence, Union + from typing import Any, Callable, Sequence from bastd.actor.playerspaz import PlayerSpaz from bastd.actor.bomb import TNTSpawner import ba @@ -38,19 +38,19 @@ class GameActivity(Activity[PlayerType, TeamType]): # pylint: disable=too-many-public-methods # Tips to be presented to the user at the start of the game. - tips: list[Union[str, ba.GameTip]] = [] + tips: list[str | ba.GameTip] = [] # Default getname() will return this if not None. - name: Optional[str] = None + name: str | None = None # Default get_description() will return this if not None. - description: Optional[str] = None + description: str | None = None # Default get_available_settings() will return this if not None. - available_settings: Optional[list[ba.Setting]] = None + available_settings: list[ba.Setting] | None = None # Default getscoreconfig() will return this if not None. - scoreconfig: Optional[ba.ScoreConfig] = None + scoreconfig: ba.ScoreConfig | None = None # Override some defaults. allow_pausing = True @@ -61,14 +61,14 @@ class GameActivity(Activity[PlayerType, TeamType]): # If not None, the music type that should play in on_transition_in() # (unless overridden by the map). - default_music: Optional[ba.MusicType] = None + default_music: ba.MusicType | None = None @classmethod def create_settings_ui( cls, sessiontype: type[ba.Session], - settings: Optional[dict], - completion_call: Callable[[Optional[dict]], None], + settings: dict | None, + completion_call: Callable[[dict | None], None], ) -> None: """Launch an in-game UI to configure settings for a game type. @@ -105,7 +105,7 @@ class GameActivity(Activity[PlayerType, TeamType]): return cls.name if cls.name is not None else 'Untitled Game' @classmethod - def get_display_string(cls, settings: Optional[dict] = None) -> ba.Lstr: + def get_display_string(cls, settings: dict | None = None) -> ba.Lstr: """Return a descriptive name for this game/settings combo. Subclasses should override getname(); not this. @@ -214,28 +214,28 @@ class GameActivity(Activity[PlayerType, TeamType]): # Holds some flattened info about the player set at the point # when on_begin() is called. - self.initialplayerinfos: Optional[list[ba.PlayerInfo]] = None + self.initialplayerinfos: list[ba.PlayerInfo] | None = None # Go ahead and get our map loading. self._map_type = _map.get_map_class(self._calc_map_name(settings)) self._spawn_sound = _ba.getsound('spawn') self._map_type.preload() - self._map: Optional[ba.Map] = None - self._powerup_drop_timer: Optional[ba.Timer] = None - self._tnt_spawners: Optional[dict[int, TNTSpawner]] = None - self._tnt_drop_timer: Optional[ba.Timer] = None - self._game_scoreboard_name_text: Optional[ba.Actor] = None - self._game_scoreboard_description_text: Optional[ba.Actor] = None - self._standard_time_limit_time: Optional[int] = None - self._standard_time_limit_timer: Optional[ba.Timer] = None - self._standard_time_limit_text: Optional[ba.NodeActor] = None - self._standard_time_limit_text_input: Optional[ba.NodeActor] = None - self._tournament_time_limit: Optional[int] = None - self._tournament_time_limit_timer: Optional[ba.Timer] = None - self._tournament_time_limit_title_text: Optional[ba.NodeActor] = None - self._tournament_time_limit_text: Optional[ba.NodeActor] = None - self._tournament_time_limit_text_input: Optional[ba.NodeActor] = None + self._map: ba.Map | None = None + self._powerup_drop_timer: ba.Timer | None = None + self._tnt_spawners: dict[int, TNTSpawner] | None = None + self._tnt_drop_timer: ba.Timer | None = None + self._game_scoreboard_name_text: ba.Actor | None = None + self._game_scoreboard_description_text: ba.Actor | None = None + self._standard_time_limit_time: int | None = None + self._standard_time_limit_timer: ba.Timer | None = None + self._standard_time_limit_text: ba.NodeActor | None = None + self._standard_time_limit_text_input: ba.NodeActor | None = None + self._tournament_time_limit: int | None = None + self._tournament_time_limit_timer: ba.Timer | None = None + self._tournament_time_limit_title_text: ba.NodeActor | None = None + self._tournament_time_limit_text: ba.NodeActor | None = None + self._tournament_time_limit_text_input: ba.NodeActor | None = None self._zoom_message_times: dict[int, float] = {} self._is_waiting_for_continue = False @@ -280,7 +280,7 @@ class GameActivity(Activity[PlayerType, TeamType]): print_error('error getting campaign level name') return self.get_instance_display_string() - def get_instance_description(self) -> Union[str, Sequence]: + def get_instance_description(self) -> str | Sequence: """Return a description for this game instance, in English. This is shown in the center of the screen below the game name at the @@ -306,7 +306,7 @@ class GameActivity(Activity[PlayerType, TeamType]): """ return self.get_description(type(self.session)) - def get_instance_description_short(self) -> Union[str, Sequence]: + def get_instance_description_short(self) -> str | Sequence: """Return a short description for this game instance in English. This description is used above the game scoreboard in the @@ -461,8 +461,8 @@ class GameActivity(Activity[PlayerType, TeamType]): callback=WeakCall(self._on_tournament_query_response), ) - def _on_tournament_query_response(self, data: Optional[dict[str, - Any]]) -> None: + def _on_tournament_query_response(self, + data: dict[str, Any] | None) -> None: if data is not None: data_t = data['t'] # This used to be the whole payload. @@ -662,8 +662,8 @@ class GameActivity(Activity[PlayerType, TeamType]): tip = self.tips.pop(random.randrange(len(self.tips))) tip_title = Lstr(value='${A}:', subs=[('${A}', Lstr(resource='tipText'))]) - icon: Optional[ba.Texture] = None - sound: Optional[ba.Sound] = None + icon: ba.Texture | None = None + sound: ba.Sound | None = None if isinstance(tip, GameTip): icon = tip.icon sound = tip.sound @@ -781,7 +781,7 @@ class GameActivity(Activity[PlayerType, TeamType]): def respawn_player(self, player: PlayerType, - respawn_time: Optional[float] = None) -> None: + respawn_time: float | None = None) -> None: """ Given a ba.Player, sets up a standard respawn timer, along with the standard counter display, etc. diff --git a/assets/src/ba_data/python/ba/_map.py b/assets/src/ba_data/python/ba/_map.py index 20da8b7e..23e1a76b 100644 --- a/assets/src/ba_data/python/ba/_map.py +++ b/assets/src/ba_data/python/ba/_map.py @@ -11,7 +11,7 @@ from ba import _math from ba._actor import Actor if TYPE_CHECKING: - from typing import Optional, Sequence, Any + from typing import Sequence, Any import ba @@ -161,7 +161,7 @@ class Map(Actor): return [] @classmethod - def get_preview_texture_name(cls) -> Optional[str]: + def get_preview_texture_name(cls) -> str | None: """Return the name of the preview texture for this map.""" return None @@ -179,7 +179,7 @@ class Map(Actor): return cls.name @classmethod - def get_music_type(cls) -> Optional[ba.MusicType]: + def get_music_type(cls) -> ba.MusicType | None: """Return a music-type string that should be played on this map. If None is returned, default music will be used. @@ -187,13 +187,13 @@ class Map(Actor): return None def __init__(self, - vr_overlay_offset: Optional[Sequence[float]] = None) -> None: + vr_overlay_offset: Sequence[float] | None = None) -> None: """Instantiate a map.""" super().__init__() # This is expected to always be a ba.Node object (whether valid or not) # should be set to something meaningful by child classes. - self.node: Optional[_ba.Node] = None + self.node: _ba.Node | None = None # Make our class' preload-data available to us # (and instruct the user if we weren't preloaded properly). @@ -294,8 +294,8 @@ class Map(Actor): return False def get_def_bound_box( - self, name: str - ) -> Optional[tuple[float, float, float, float, float, float]]: + self, name: str + ) -> tuple[float, float, float, float, float, float] | None: """Return a 6 member bounds tuple or None if it is not defined.""" try: box = self.defs.boxes[name] @@ -305,7 +305,7 @@ class Map(Actor): except Exception: return None - def get_def_point(self, name: str) -> Optional[Sequence[float]]: + def get_def_point(self, name: str) -> Sequence[float] | None: """Return a single defined point or a default value in its absence.""" val = self.defs.points.get(name) return (None if val is None else diff --git a/assets/src/ba_data/python/ba/_profile.py b/assets/src/ba_data/python/ba/_profile.py index 6513eb62..be0a831f 100644 --- a/assets/src/ba_data/python/ba/_profile.py +++ b/assets/src/ba_data/python/ba/_profile.py @@ -9,7 +9,7 @@ from typing import TYPE_CHECKING import _ba if TYPE_CHECKING: - from typing import Any, Optional + from typing import Any # NOTE: player color options are enforced server-side for non-pro accounts # so don't change these or they won't stick... @@ -49,7 +49,7 @@ def get_player_profile_icon(profilename: str) -> str: def get_player_profile_colors( - profilename: Optional[str], + profilename: str | None, profiles: dict[str, dict[str, Any]] = None ) -> tuple[tuple[float, float, float], tuple[float, float, float]]: """Given a profile, return colors for them.""" diff --git a/assets/src/ba_data/python/ba/_servermode.py b/assets/src/ba_data/python/ba/_servermode.py index 37fad3c8..19aecb59 100644 --- a/assets/src/ba_data/python/ba/_servermode.py +++ b/assets/src/ba_data/python/ba/_servermode.py @@ -19,7 +19,7 @@ from ba._dualteamsession import DualTeamSession from ba._coopsession import CoopSession if TYPE_CHECKING: - from typing import Optional, Any + from typing import Any import ba from bacommon.servermanager import ServerConfig @@ -85,10 +85,10 @@ class ServerController: self._config = config self._playlist_name = '__default__' self._ran_access_check = False - self._prep_timer: Optional[ba.Timer] = None + self._prep_timer: ba.Timer | None = None self._next_stuck_login_warn_time = time.time() + 10.0 self._first_run = True - self._shutdown_reason: Optional[ShutdownReason] = None + self._shutdown_reason: ShutdownReason | None = None self._executing_shutdown = False # Make note if they want us to import a playlist; @@ -129,7 +129,7 @@ class ServerController: out += f'\n{clientid:<{col1}} {name:<{col2}} {players}' print(out) - def kick(self, client_id: int, ban_time: Optional[int]) -> None: + def kick(self, client_id: int, ban_time: int | None) -> None: """Kick the provided client id. ban_time is provided in seconds. @@ -198,7 +198,7 @@ class ServerController: callback=self._access_check_response, ) - def _access_check_response(self, data: Optional[dict[str, Any]]) -> None: + def _access_check_response(self, data: dict[str, Any] | None) -> None: import os if data is None: print('error on UDP port access check (internet down?)') @@ -267,7 +267,7 @@ class ServerController: def _on_playlist_fetch_response( self, - result: Optional[dict[str, Any]], + result: dict[str, Any] | None, ) -> None: if result is None: print('Error fetching playlist; aborting.') diff --git a/assets/src/ba_data/python/ba/_ui.py b/assets/src/ba_data/python/ba/_ui.py index 06298010..4bf2b70b 100644 --- a/assets/src/ba_data/python/ba/_ui.py +++ b/assets/src/ba_data/python/ba/_ui.py @@ -10,7 +10,7 @@ import _ba from ba._generated.enums import UIScale if TYPE_CHECKING: - from typing import Optional, Any, Callable + from typing import Any, Callable from ba.ui import UICleanupCheck import ba @@ -26,10 +26,10 @@ class UISubsystem: def __init__(self) -> None: env = _ba.env() - self.controller: Optional[ba.UIController] = None + self.controller: ba.UIController | None = None - self._main_menu_window: Optional[ba.Widget] = None - self._main_menu_location: Optional[str] = None + self._main_menu_window: ba.Widget | None = None + self._main_menu_location: str | None = None self._uiscale: ba.UIScale @@ -44,13 +44,12 @@ class UISubsystem: raise RuntimeError(f'Invalid UIScale value: {interfacetype}') self.window_states: dict[type, Any] = {} # FIXME: Kill this. - self.main_menu_selection: Optional[str] = None # FIXME: Kill this. + self.main_menu_selection: str | None = None # FIXME: Kill this. self.have_party_queue_window = False self.quit_window: Any = None - self.dismiss_wii_remotes_window_call: (Optional[Callable[[], - Any]]) = None + self.dismiss_wii_remotes_window_call: (Callable[[], Any] | None) = None self.cleanupchecks: list[UICleanupCheck] = [] - self.upkeeptimer: Optional[ba.Timer] = None + self.upkeeptimer: ba.Timer | None = None self.use_toolbars = env.get('toolbar_test', True) self.party_window: Any = None # FIXME: Don't use Any. self.title_color = (0.72, 0.7, 0.75) @@ -162,6 +161,6 @@ class UISubsystem: """Set the location represented by the current main menu window.""" self._main_menu_location = location - def get_main_menu_location(self) -> Optional[str]: + def get_main_menu_location(self) -> str | None: """Return the current named main menu location, if any.""" return self._main_menu_location diff --git a/assets/src/ba_data/python/ba/macmusicapp.py b/assets/src/ba_data/python/ba/macmusicapp.py index 598f5725..4a758726 100644 --- a/assets/src/ba_data/python/ba/macmusicapp.py +++ b/assets/src/ba_data/python/ba/macmusicapp.py @@ -10,7 +10,7 @@ import _ba from ba._music import MusicPlayer if TYPE_CHECKING: - from typing import Optional, Callable, Any + from typing import Callable, Any class MacMusicAppMusicPlayer(MusicPlayer): @@ -62,8 +62,8 @@ class _MacMusicAppThread(threading.Thread): self._commands_available = threading.Event() self._commands: list[list] = [] self._volume = 1.0 - self._current_playlist: Optional[str] = None - self._orig_volume: Optional[int] = None + self._current_playlist: str | None = None + self._orig_volume: int | None = None def run(self) -> None: """Run the Music.app thread.""" @@ -136,7 +136,7 @@ class _MacMusicAppThread(threading.Thread): if old_volume == 0.0: self._play_current_playlist() - def play_playlist(self, musictype: Optional[str]) -> None: + def play_playlist(self, musictype: str | None) -> None: """Play the given playlist.""" self._commands.append(['PLAY', musictype]) self._commands_available.set() @@ -170,7 +170,7 @@ class _MacMusicAppThread(threading.Thread): playlists = [] _ba.pushcall(Call(target, playlists), from_other_thread=True) - def _handle_play_command(self, target: Optional[str]) -> None: + def _handle_play_command(self, target: str | None) -> None: if target is None: if self._current_playlist is not None and self._volume > 0: try: diff --git a/assets/src/ba_data/python/ba/ui/__init__.py b/assets/src/ba_data/python/ba/ui/__init__.py index a3b16de3..67e5d936 100644 --- a/assets/src/ba_data/python/ba/ui/__init__.py +++ b/assets/src/ba_data/python/ba/ui/__init__.py @@ -14,7 +14,7 @@ from ba._generated.enums import TimeType from ba._general import print_active_refs if TYPE_CHECKING: - from typing import Optional, Any + from typing import Any import ba @@ -46,7 +46,7 @@ class UICleanupCheck: """Holds info about a uicleanupcheck target.""" obj: weakref.ref widget: ba.Widget - widget_death_time: Optional[float] + widget_death_time: float | None class UILocation: @@ -76,7 +76,7 @@ class UILocationWindow(UILocation): def __init__(self) -> None: super().__init__() - self._root_widget: Optional[ba.Widget] = None + self._root_widget: ba.Widget | None = None def get_root_widget(self) -> ba.Widget: """Return the root widget for this window.""" @@ -91,7 +91,7 @@ class UIEntry: self._name = name self._state = None self._args = None - self._instance: Optional[UILocation] = None + self._instance: UILocation | None = None self._controller = weakref.ref(controller) def create(self) -> None: @@ -129,7 +129,7 @@ class UIController: self._main_stack_menu: list[UIEntry] = [] # This points at either the game or menu stack. - self._main_stack: Optional[list[UIEntry]] = None + self._main_stack: list[UIEntry] | None = None # There's only one of these since we don't need to preserve its state # between sessions. diff --git a/assets/src/ba_data/python/bastd/actor/popuptext.py b/assets/src/ba_data/python/bastd/actor/popuptext.py index 5ce8af9a..d078e7ea 100644 --- a/assets/src/ba_data/python/bastd/actor/popuptext.py +++ b/assets/src/ba_data/python/bastd/actor/popuptext.py @@ -10,7 +10,7 @@ from typing import TYPE_CHECKING import ba if TYPE_CHECKING: - from typing import Any, Union, Sequence + from typing import Any, Sequence class PopupText(ba.Actor): @@ -20,7 +20,7 @@ class PopupText(ba.Actor): """ def __init__(self, - text: Union[str, ba.Lstr], + text: str | ba.Lstr, position: Sequence[float] = (0.0, 0.0, 0.0), color: Sequence[float] = (1.0, 1.0, 1.0, 1.0), random_offset: float = 0.5, diff --git a/assets/src/ba_data/python/bastd/actor/zoomtext.py b/assets/src/ba_data/python/bastd/actor/zoomtext.py index 5288bb66..c91df931 100644 --- a/assets/src/ba_data/python/bastd/actor/zoomtext.py +++ b/assets/src/ba_data/python/bastd/actor/zoomtext.py @@ -10,7 +10,7 @@ from typing import TYPE_CHECKING import ba if TYPE_CHECKING: - from typing import Any, Union, Sequence + from typing import Any, Sequence class ZoomText(ba.Actor): @@ -22,7 +22,7 @@ class ZoomText(ba.Actor): """ def __init__(self, - text: Union[str, ba.Lstr], + text: str | ba.Lstr, position: tuple[float, float] = (0.0, 0.0), shiftposition: tuple[float, float] = None, shiftdelay: float = None, diff --git a/assets/src/ba_data/python/bastd/game/assault.py b/assets/src/ba_data/python/bastd/game/assault.py index 44b856a5..e9f4ff15 100644 --- a/assets/src/ba_data/python/bastd/game/assault.py +++ b/assets/src/ba_data/python/bastd/game/assault.py @@ -17,7 +17,7 @@ from bastd.actor.scoreboard import Scoreboard from bastd.gameutils import SharedObjects if TYPE_CHECKING: - from typing import Any, Sequence, Union + from typing import Any, Sequence class Player(ba.Player['Team']): @@ -94,12 +94,12 @@ class AssaultGame(ba.TeamGameActivity[Player, Team]): self.default_music = (ba.MusicType.EPIC if self._epic_mode else ba.MusicType.FORWARD_MARCH) - def get_instance_description(self) -> Union[str, Sequence]: + def get_instance_description(self) -> str | Sequence: if self._score_to_win == 1: return 'Touch the enemy flag.' return 'Touch the enemy flag ${ARG1} times.', self._score_to_win - def get_instance_description_short(self) -> Union[str, Sequence]: + def get_instance_description_short(self) -> str | Sequence: if self._score_to_win == 1: return 'touch 1 flag' return 'touch ${ARG1} flags', self._score_to_win diff --git a/assets/src/ba_data/python/bastd/ui/account/link.py b/assets/src/ba_data/python/bastd/ui/account/link.py index 1e0b2b77..8c026a02 100644 --- a/assets/src/ba_data/python/bastd/ui/account/link.py +++ b/assets/src/ba_data/python/bastd/ui/account/link.py @@ -12,14 +12,14 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Optional + from typing import Any class AccountLinkWindow(ba.Window): """Window for linking accounts.""" def __init__(self, origin_widget: ba.Widget = None): - scale_origin: Optional[tuple[float, float]] + scale_origin: tuple[float, float] | None if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() diff --git a/assets/src/ba_data/python/bastd/ui/account/settings.py b/assets/src/ba_data/python/bastd/ui/account/settings.py index 901e0c89..f5b180f8 100644 --- a/assets/src/ba_data/python/bastd/ui/account/settings.py +++ b/assets/src/ba_data/python/bastd/ui/account/settings.py @@ -12,7 +12,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Optional, Union + pass class AccountSettingsWindow(ba.Window): @@ -25,15 +25,15 @@ class AccountSettingsWindow(ba.Window): close_once_signed_in: bool = False): # pylint: disable=too-many-statements - self._sign_in_game_circle_button: Optional[ba.Widget] = None - self._sign_in_v2_button: Optional[ba.Widget] = None - self._sign_in_device_button: Optional[ba.Widget] = None + self._sign_in_game_circle_button: ba.Widget | None = None + self._sign_in_v2_button: ba.Widget | None = None + self._sign_in_device_button: ba.Widget | None = None self._close_once_signed_in = close_once_signed_in ba.set_analytics_screen('Account Window') # If they provided an origin-widget, scale up from that. - scale_origin: Optional[tuple[float, float]] + scale_origin: tuple[float, float] | None if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() @@ -56,7 +56,7 @@ class AccountSettingsWindow(ba.Window): repeat=True) # Currently we can only reset achievements on game-center. - account_type: Optional[str] + account_type: str | None if self._signed_in: account_type = _ba.get_v1_account_type() else: @@ -145,7 +145,7 @@ class AccountSettingsWindow(ba.Window): claims_left_right=True, claims_tab=True, selection_loops_to_parent=True) - self._subcontainer: Optional[ba.Widget] = None + self._subcontainer: ba.Widget | None = None self._refresh() self._restore_state() @@ -344,7 +344,7 @@ class AccountSettingsWindow(ba.Window): v_align='center') v -= local_signed_in_as_space * 0.4 - self._account_name_text: Optional[ba.Widget] + self._account_name_text: ba.Widget | None if show_signed_in_as: v -= signed_in_as_space * 0.2 txt = ba.Lstr( @@ -383,7 +383,7 @@ class AccountSettingsWindow(ba.Window): if show_sign_in_benefits: v -= sign_in_benefits_space app = ba.app - extra: Optional[Union[str, ba.Lstr]] + extra: str | ba.Lstr | None if (app.platform in ['mac', 'ios'] and app.subplatform == 'appstore'): extra = ba.Lstr( @@ -616,7 +616,7 @@ class AccountSettingsWindow(ba.Window): else: self.game_service_button = None - self._achievements_text: Optional[ba.Widget] + self._achievements_text: ba.Widget | None if show_achievements_text: v -= achievements_text_space * 0.5 self._achievements_text = ba.textwidget( @@ -632,7 +632,7 @@ class AccountSettingsWindow(ba.Window): else: self._achievements_text = None - self._achievements_button: Optional[ba.Widget] + self._achievements_button: ba.Widget | None if show_achievements_button: button_width = 300 v -= achievements_button_space * 0.85 @@ -661,7 +661,7 @@ class AccountSettingsWindow(ba.Window): if show_achievements_text or show_achievements_button: self._refresh_achievements() - self._leaderboards_button: Optional[ba.Widget] + self._leaderboards_button: ba.Widget | None if show_leaderboards_button: button_width = 300 v -= leaderboards_button_space * 0.85 @@ -686,7 +686,7 @@ class AccountSettingsWindow(ba.Window): else: self._leaderboards_button = None - self._campaign_progress_text: Optional[ba.Widget] + self._campaign_progress_text: ba.Widget | None if show_campaign_progress: v -= campaign_progress_space * 0.5 self._campaign_progress_text = ba.textwidget( @@ -703,7 +703,7 @@ class AccountSettingsWindow(ba.Window): else: self._campaign_progress_text = None - self._tickets_text: Optional[ba.Widget] + self._tickets_text: ba.Widget | None if show_tickets: v -= tickets_space * 0.5 self._tickets_text = ba.textwidget(parent=self._subcontainer, @@ -753,7 +753,7 @@ class AccountSettingsWindow(ba.Window): right_widget=_ba.get_special_widget('party_button')) ba.widget(edit=btn, left_widget=bbtn) - self._linked_accounts_text: Optional[ba.Widget] + self._linked_accounts_text: ba.Widget | None if show_linked_accounts_text: v -= linked_accounts_text_space * 0.8 self._linked_accounts_text = ba.textwidget( @@ -808,7 +808,7 @@ class AccountSettingsWindow(ba.Window): right_widget=_ba.get_special_widget('party_button')) ba.widget(edit=btn, left_widget=bbtn, show_buffer_bottom=50) - self._unlink_accounts_button: Optional[ba.Widget] + self._unlink_accounts_button: ba.Widget | None if show_unlink_accounts_button: v -= unlink_accounts_button_space self._unlink_accounts_button = btn = ba.buttonwidget( @@ -957,7 +957,7 @@ class AccountSettingsWindow(ba.Window): from ba.internal import getcampaign if self._campaign_progress_text is None: return - p_str: Union[str, ba.Lstr] + p_str: str | ba.Lstr try: campaign = getcampaign('Default') levels = campaign.levels diff --git a/assets/src/ba_data/python/bastd/ui/account/unlink.py b/assets/src/ba_data/python/bastd/ui/account/unlink.py index 83e00ddc..8e9955be 100644 --- a/assets/src/ba_data/python/bastd/ui/account/unlink.py +++ b/assets/src/ba_data/python/bastd/ui/account/unlink.py @@ -11,14 +11,14 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Optional + from typing import Any class AccountUnlinkWindow(ba.Window): """A window to kick off account unlinks.""" def __init__(self, origin_widget: ba.Widget = None): - scale_origin: Optional[tuple[float, float]] + scale_origin: tuple[float, float] | None if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() diff --git a/assets/src/ba_data/python/bastd/ui/account/v2.py b/assets/src/ba_data/python/bastd/ui/account/v2.py index 7cacca02..1f9fea3b 100644 --- a/assets/src/ba_data/python/bastd/ui/account/v2.py +++ b/assets/src/ba_data/python/bastd/ui/account/v2.py @@ -14,7 +14,7 @@ from efro.error import CommunicationError import bacommon.cloud if TYPE_CHECKING: - from typing import Union, Optional + pass STATUS_CHECK_INTERVAL_SECONDS = 2.0 @@ -25,8 +25,8 @@ class V2SignInWindow(ba.Window): def __init__(self, origin_widget: ba.Widget): self._width = 600 self._height = 550 - self._proxyid: Optional[str] = None - self._proxykey: Optional[str] = None + self._proxyid: str | None = None + self._proxykey: str | None = None uiscale = ba.app.ui.uiscale super().__init__(root_widget=ba.containerwidget( @@ -60,7 +60,7 @@ class V2SignInWindow(ba.Window): ba.containerwidget(edit=self._root_widget, cancel_button=self._cancel_button) - self._update_timer: Optional[ba.Timer] = None + self._update_timer: ba.Timer | None = None # Ask the cloud for a proxy login id. ba.app.cloud.send_message_cb(bacommon.cloud.LoginProxyRequestMessage(), @@ -68,8 +68,7 @@ class V2SignInWindow(ba.Window): self._on_proxy_request_response)) def _on_proxy_request_response( - self, response: Union[bacommon.cloud.LoginProxyRequestResponse, - Exception] + self, response: bacommon.cloud.LoginProxyRequestResponse | Exception ) -> None: from ba.internal import is_browser_likely_available @@ -141,8 +140,7 @@ class V2SignInWindow(ba.Window): on_response=ba.WeakCall(self._got_status)) def _got_status( - self, response: Union[bacommon.cloud.LoginProxyStateQueryResponse, - Exception] + self, response: bacommon.cloud.LoginProxyStateQueryResponse | Exception ) -> None: # For now, if anything goes wrong on the server-side, just abort @@ -184,8 +182,7 @@ class V2SignInWindow(ba.Window): ba.timer(STATUS_CHECK_INTERVAL_SECONDS, ba.WeakCall(self._ask_for_status)) - def _proxy_complete_response(self, response: Union[None, - Exception]) -> None: + def _proxy_complete_response(self, response: None | Exception) -> None: del response # Not used. # We could do something smart like retry on exceptions here, but # this isn't critical so we'll just let anything slide. diff --git a/assets/src/ba_data/python/bastd/ui/account/viewer.py b/assets/src/ba_data/python/bastd/ui/account/viewer.py index 6464da20..549207e7 100644 --- a/assets/src/ba_data/python/bastd/ui/account/viewer.py +++ b/assets/src/ba_data/python/bastd/ui/account/viewer.py @@ -11,7 +11,7 @@ import ba from bastd.ui import popup if TYPE_CHECKING: - from typing import Any, Optional + from typing import Any class AccountViewerWindow(popup.PopupWindow): @@ -37,7 +37,7 @@ class AccountViewerWindow(popup.PopupWindow): self._width = 400 self._height = (300 if uiscale is ba.UIScale.SMALL else 400 if uiscale is ba.UIScale.MEDIUM else 450) - self._subcontainer: Optional[ba.Widget] = None + self._subcontainer: ba.Widget | None = None bg_color = (0.5, 0.4, 0.6) @@ -169,7 +169,7 @@ class AccountViewerWindow(popup.PopupWindow): ba.open_url(_ba.get_master_server_address() + '/highscores?profile=' + self._account_id) - def _on_query_response(self, data: Optional[dict[str, Any]]) -> None: + def _on_query_response(self, data: dict[str, Any] | None) -> None: # FIXME: Tidy this up. # pylint: disable=too-many-locals # pylint: disable=too-many-branches diff --git a/assets/src/ba_data/python/bastd/ui/appinvite.py b/assets/src/ba_data/python/bastd/ui/appinvite.py index 262a809f..98ba818a 100644 --- a/assets/src/ba_data/python/bastd/ui/appinvite.py +++ b/assets/src/ba_data/python/bastd/ui/appinvite.py @@ -12,7 +12,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Optional, Union + from typing import Any class AppInviteWindow(ba.Window): @@ -20,7 +20,7 @@ class AppInviteWindow(ba.Window): def __init__(self) -> None: ba.set_analytics_screen('AppInviteWindow') - self._data: Optional[dict[str, Any]] = None + self._data: dict[str, Any] | None = None self._width = 650 self._height = 400 @@ -113,7 +113,7 @@ class AppInviteWindow(ba.Window): callback=ba.WeakCall(self._on_code_result)) _ba.run_transactions() - def _on_code_result(self, result: Optional[dict[str, Any]]) -> None: + def _on_code_result(self, result: dict[str, Any] | None) -> None: if result is not None: self._data = result @@ -202,7 +202,7 @@ class ShowFriendCodeWindow(ba.Window): text=data['code'], maxwidth=self._width * 0.85) - award_str: Optional[Union[str, ba.Lstr]] + award_str: str | ba.Lstr | None if self._data['awardTickets'] != 0: award_str = ba.Lstr( resource='gatherWindow.friendPromoCodeAwardText', @@ -317,7 +317,7 @@ def handle_app_invites_press(force_code: bool = False) -> None: ba.Lstr(resource='gatherWindow.requestingAPromoCodeText'), color=(0, 1, 0)) - def handle_result(result: Optional[dict[str, Any]]) -> None: + def handle_result(result: dict[str, Any] | None) -> None: with ba.Context('ui'): if result is None: ba.screenmessage(ba.Lstr(resource='errorText'), diff --git a/assets/src/ba_data/python/bastd/ui/colorpicker.py b/assets/src/ba_data/python/bastd/ui/colorpicker.py index 3f12ed02..1d7faa0d 100644 --- a/assets/src/ba_data/python/bastd/ui/colorpicker.py +++ b/assets/src/ba_data/python/bastd/ui/colorpicker.py @@ -10,7 +10,7 @@ import ba from bastd.ui.popup import PopupWindow if TYPE_CHECKING: - from typing import Any, Sequence, Optional + from typing import Any, Sequence class ColorPicker(PopupWindow): @@ -182,8 +182,8 @@ class ColorPickerExact(PopupWindow): self._color = list(initial_color) self._last_press_time = ba.time(ba.TimeType.REAL, ba.TimeFormat.MILLISECONDS) - self._last_press_color_name: Optional[str] = None - self._last_press_increasing: Optional[bool] = None + self._last_press_color_name: str | None = None + self._last_press_increasing: bool | None = None self._change_speed = 1.0 width = 180.0 height = 240.0 diff --git a/assets/src/ba_data/python/bastd/ui/config.py b/assets/src/ba_data/python/bastd/ui/config.py index d8567e51..fbd77203 100644 --- a/assets/src/ba_data/python/bastd/ui/config.py +++ b/assets/src/ba_data/python/bastd/ui/config.py @@ -9,7 +9,7 @@ from typing import TYPE_CHECKING import ba if TYPE_CHECKING: - from typing import Any, Union, Callable + from typing import Any, Callable class ConfigCheckBox: @@ -27,7 +27,7 @@ class ConfigCheckBox: configkey: str, position: tuple[float, float], size: tuple[float, float], - displayname: Union[str, ba.Lstr] = None, + displayname: str | ba.Lstr | None = None, scale: float = None, maxwidth: float = None, autoselect: bool = True, @@ -86,7 +86,7 @@ class ConfigNumberEdit: increment: float = 1.0, callback: Callable[[float], Any] = None, xoffset: float = 0.0, - displayname: Union[str, ba.Lstr] = None, + displayname: str | ba.Lstr | None = None, changesound: bool = True, textscale: float = 1.0): if displayname is None: diff --git a/assets/src/ba_data/python/bastd/ui/confirm.py b/assets/src/ba_data/python/bastd/ui/confirm.py index 716c7fe0..3136a7c5 100644 --- a/assets/src/ba_data/python/bastd/ui/confirm.py +++ b/assets/src/ba_data/python/bastd/ui/confirm.py @@ -10,14 +10,14 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Union, Callable + from typing import Any, Callable class ConfirmWindow: """Window for answering simple yes/no questions.""" def __init__(self, - text: Union[str, ba.Lstr] = 'Are you sure?', + text: str | ba.Lstr = 'Are you sure?', action: Callable[[], Any] = None, width: float = 360.0, height: float = 100.0, @@ -25,8 +25,8 @@ class ConfirmWindow: cancel_is_selected: bool = False, color: tuple[float, float, float] = (1, 1, 1), text_scale: float = 1.0, - ok_text: Union[str, ba.Lstr] = None, - cancel_text: Union[str, ba.Lstr] = None, + ok_text: str | ba.Lstr | None = None, + cancel_text: str | ba.Lstr | None = None, origin_widget: ba.Widget = None): # pylint: disable=too-many-locals if ok_text is None: diff --git a/assets/src/ba_data/python/bastd/ui/continues.py b/assets/src/ba_data/python/bastd/ui/continues.py index 2635d90a..861c860e 100644 --- a/assets/src/ba_data/python/bastd/ui/continues.py +++ b/assets/src/ba_data/python/bastd/ui/continues.py @@ -11,7 +11,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Callable, Optional + from typing import Any, Callable class ContinuesWindow(ba.Window): @@ -74,8 +74,8 @@ class ContinuesWindow(ba.Window): t_left_width + t_price_width + 5, self._height - 30)) - self._tickets_text_base: Optional[str] - self._tickets_text: Optional[ba.Widget] + self._tickets_text_base: str | None + self._tickets_text: ba.Widget | None if not ba.app.ui.use_toolbars: self._tickets_text_base = ba.Lstr( resource='getTicketsWindow.youHaveShortText', diff --git a/assets/src/ba_data/python/bastd/ui/coop/browser.py b/assets/src/ba_data/python/bastd/ui/coop/browser.py index d118b503..aeabeafc 100644 --- a/assets/src/ba_data/python/bastd/ui/coop/browser.py +++ b/assets/src/ba_data/python/bastd/ui/coop/browser.py @@ -16,7 +16,7 @@ from bastd.ui.league.rankbutton import LeagueRankButton from bastd.ui.store.browser import StoreBrowserWindow if TYPE_CHECKING: - from typing import Any, Optional, Union + from typing import Any class CoopBrowserWindow(ba.Window): @@ -36,7 +36,7 @@ class CoopBrowserWindow(ba.Window): (4 if uiscale is ba.UIScale.SMALL else 0))) def __init__(self, - transition: Optional[str] = 'in_right', + transition: str | None = 'in_right', origin_widget: ba.Widget = None): # pylint: disable=too-many-statements # pylint: disable=cyclic-import @@ -62,7 +62,7 @@ class CoopBrowserWindow(ba.Window): timetype=ba.TimeType.REAL) # If they provided an origin-widget, scale up from that. - scale_origin: Optional[tuple[float, float]] + scale_origin: tuple[float, float] | None if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() @@ -76,10 +76,10 @@ class CoopBrowserWindow(ba.Window): self._tournament_button_count = app.config.get('Tournament Rows', 0) assert isinstance(self._tournament_button_count, int) - self._easy_button: Optional[ba.Widget] = None - self._hard_button: Optional[ba.Widget] = None - self._hard_button_lock_image: Optional[ba.Widget] = None - self._campaign_percent_text: Optional[ba.Widget] = None + self._easy_button: ba.Widget | None = None + self._hard_button: ba.Widget | None = None + self._hard_button_lock_image: ba.Widget | None = None + self._campaign_percent_text: ba.Widget | None = None uiscale = ba.app.ui.uiscale self._width = 1320 if uiscale is ba.UIScale.SMALL else 1120 @@ -118,10 +118,10 @@ class CoopBrowserWindow(ba.Window): label=ba.Lstr(resource='backText'), button_type='back') - self._league_rank_button: Optional[LeagueRankButton] - self._store_button: Optional[StoreButton] - self._store_button_widget: Optional[ba.Widget] - self._league_rank_button_widget: Optional[ba.Widget] + self._league_rank_button: LeagueRankButton | None + self._store_button: StoreButton | None + self._store_button_widget: ba.Widget | None + self._league_rank_button_widget: ba.Widget | None if not app.ui.use_toolbars: prb = self._league_rank_button = LeagueRankButton( @@ -167,8 +167,8 @@ class CoopBrowserWindow(ba.Window): repeat=True, timetype=ba.TimeType.REAL) - self._last_tournament_query_time: Optional[float] = None - self._last_tournament_query_response_time: Optional[float] = None + self._last_tournament_query_time: float | None = None + self._last_tournament_query_response_time: float | None = None self._doing_tournament_query = False self._selected_campaign_level = (cfg.get( @@ -232,7 +232,7 @@ class CoopBrowserWindow(ba.Window): claims_left_right=True, claims_tab=True, selection_loops_to_parent=True) - self._subcontainer: Optional[ba.Widget] = None + self._subcontainer: ba.Widget | None = None # Take note of our account state; we'll refresh later if this changes. self._account_state_num = _ba.get_v1_account_state_num() @@ -362,7 +362,7 @@ class CoopBrowserWindow(ba.Window): except Exception: ba.print_exception('Error updating campaign lock.') - def _update_for_data(self, data: Optional[list[dict[str, Any]]]) -> None: + def _update_for_data(self, data: list[dict[str, Any]] | None) -> None: # pylint: disable=too-many-statements # pylint: disable=too-many-locals # pylint: disable=too-many-branches @@ -444,7 +444,7 @@ class CoopBrowserWindow(ba.Window): 93 - 90 + prize_y_offs)) leader_name = '-' - leader_score: Union[str, ba.Lstr] = '-' + leader_score: str | ba.Lstr = '-' if entry['scores']: score = tbtn['leader'] = copy.deepcopy(entry['scores'][0]) leader_name = score[1] @@ -464,7 +464,7 @@ class CoopBrowserWindow(ba.Window): text=leader_score) ba.buttonwidget(edit=tbtn['more_scores_button'], label=ba.Lstr(resource=self._r + '.seeMoreText')) - out_of_time_text: Union[str, ba.Lstr] = ( + out_of_time_text: str | ba.Lstr = ( '-' if 'totalTime' not in entry else ba.Lstr( resource=self._r + '.ofTotalTimeText', subs=[('${TOTAL}', @@ -524,11 +524,11 @@ class CoopBrowserWindow(ba.Window): tbtn['allow_ads'] = allow_ads = entry['allowAds'] - final_fee: Optional[int] = (None if fee_var is None else - _ba.get_v1_account_misc_read_val( - fee_var, '?')) + final_fee: int | None = (None if fee_var is None else + _ba.get_v1_account_misc_read_val( + fee_var, '?')) - final_fee_str: Union[str, ba.Lstr] + final_fee_str: str | ba.Lstr if fee_var is None: final_fee_str = '' else: @@ -590,8 +590,8 @@ class CoopBrowserWindow(ba.Window): ('' + str(free_tries_remaining))), color=(0.6, 0.6, 0.6, 1)) - def _on_tournament_query_response(self, data: Optional[dict[str, - Any]]) -> None: + def _on_tournament_query_response(self, + data: dict[str, Any] | None) -> None: accounts = ba.app.accounts_v1 if data is not None: tournament_data = data['t'] # This used to be the whole payload. @@ -1361,8 +1361,8 @@ class CoopBrowserWindow(ba.Window): def _switch_to_score( self, - show_tab: Optional[ - StoreBrowserWindow.TabID] = StoreBrowserWindow.TabID.EXTRAS + show_tab: StoreBrowserWindow.TabID + | None = StoreBrowserWindow.TabID.EXTRAS ) -> None: # pylint: disable=cyclic-import from bastd.ui.account import show_sign_in_prompt @@ -1414,7 +1414,7 @@ class CoopBrowserWindow(ba.Window): return self._tourney_data_up_to_date def run(self, - game: Optional[str], + game: str | None, tournament_button: dict[str, Any] = None) -> None: """Run the provided game.""" # pylint: disable=too-many-branches @@ -1491,7 +1491,7 @@ class CoopBrowserWindow(ba.Window): PurchaseWindow(items=['pro']) return - required_purchase: Optional[str] + required_purchase: str | None if game in ['Challenges:Meteor Shower']: required_purchase = 'games.meteor_shower' elif game in [ diff --git a/assets/src/ba_data/python/bastd/ui/coop/gamebutton.py b/assets/src/ba_data/python/bastd/ui/coop/gamebutton.py index 026f4cef..40ff1cff 100644 --- a/assets/src/ba_data/python/bastd/ui/coop/gamebutton.py +++ b/assets/src/ba_data/python/bastd/ui/coop/gamebutton.py @@ -11,7 +11,6 @@ import _ba import ba if TYPE_CHECKING: - from typing import Optional from bastd.ui.coop.browser import CoopBrowserWindow @@ -35,7 +34,7 @@ class GameButton: if game == 'Easy:The Last Stand': campaignname = 'Default' - rating: Optional[float] + rating: float | None campaign = getcampaign(campaignname) rating = campaign.getlevel(levelname).rating diff --git a/assets/src/ba_data/python/bastd/ui/creditslist.py b/assets/src/ba_data/python/bastd/ui/creditslist.py index d6a37c8d..722fd7a5 100644 --- a/assets/src/ba_data/python/bastd/ui/creditslist.py +++ b/assets/src/ba_data/python/bastd/ui/creditslist.py @@ -10,7 +10,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Optional, Sequence + from typing import Sequence class CreditsListWindow(ba.Window): @@ -23,7 +23,7 @@ class CreditsListWindow(ba.Window): ba.set_analytics_screen('Credits Window') # if they provided an origin-widget, scale up from that - scale_origin: Optional[tuple[float, float]] + scale_origin: tuple[float, float] | None if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() diff --git a/assets/src/ba_data/python/bastd/ui/feedback.py b/assets/src/ba_data/python/bastd/ui/feedback.py index 7d4db7c2..6999cca7 100644 --- a/assets/src/ba_data/python/bastd/ui/feedback.py +++ b/assets/src/ba_data/python/bastd/ui/feedback.py @@ -9,10 +9,10 @@ from typing import TYPE_CHECKING import ba if TYPE_CHECKING: - from typing import Optional + pass -def ask_for_rating() -> Optional[ba.Widget]: +def ask_for_rating() -> ba.Widget | None: """(internal)""" app = ba.app platform = app.platform diff --git a/assets/src/ba_data/python/bastd/ui/fileselector.py b/assets/src/ba_data/python/bastd/ui/fileselector.py index e48b456a..8af14daa 100644 --- a/assets/src/ba_data/python/bastd/ui/fileselector.py +++ b/assets/src/ba_data/python/bastd/ui/fileselector.py @@ -13,7 +13,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Callable, Sequence, Optional + from typing import Any, Callable, Sequence class FileSelectorWindow(ba.Window): @@ -21,7 +21,7 @@ class FileSelectorWindow(ba.Window): def __init__(self, path: str, - callback: Callable[[Optional[str]], Any] = None, + callback: Callable[[str | None], Any] = None, show_base_path: bool = True, valid_file_extensions: Sequence[str] = None, allow_folders: bool = False): @@ -33,15 +33,15 @@ class FileSelectorWindow(ba.Window): self._height = 365 if uiscale is ba.UIScale.SMALL else 418 self._callback = callback self._base_path = path - self._path: Optional[str] = None + self._path: str | None = None self._recent_paths: list[str] = [] self._show_base_path = show_base_path self._valid_file_extensions = [ '.' + ext for ext in valid_file_extensions ] self._allow_folders = allow_folders - self._subcontainer: Optional[ba.Widget] = None - self._subcontainerheight: Optional[float] = None + self._subcontainer: ba.Widget | None = None + self._subcontainerheight: float | None = None self._scroll_width = self._width - (80 + 2 * x_inset) self._scroll_height = self._height - 170 self._r = 'fileSelectorWindow' @@ -92,7 +92,7 @@ class FileSelectorWindow(ba.Window): self._folder_color = (1.1, 0.8, 0.2) self._file_tex = ba.gettexture('file') self._file_color = (1, 1, 1) - self._use_folder_button: Optional[ba.Widget] = None + self._use_folder_button: ba.Widget | None = None self._folder_center = self._width * 0.5 + 15 self._folder_icon = ba.imagewidget(parent=self._root_widget, size=(40, 40), @@ -108,7 +108,7 @@ class FileSelectorWindow(ba.Window): v_align='center', text=self._path, maxwidth=self._width * 0.9) - self._scrollwidget: Optional[ba.Widget] = None + self._scrollwidget: ba.Widget | None = None ba.containerwidget(edit=self._root_widget, cancel_button=self._cancel_button) self._set_path(path) @@ -173,7 +173,7 @@ class FileSelectorWindow(ba.Window): class _RefreshThread(threading.Thread): def __init__(self, path: str, - callback: Callable[[list[str], Optional[str]], Any]): + callback: Callable[[list[str], str | None], Any]): super().__init__() self._callback = callback self._path = path @@ -205,7 +205,7 @@ class FileSelectorWindow(ba.Window): self._recent_paths.append(path) self._RefreshThread(path, self._refresh).start() - def _refresh(self, file_names: list[str], error: Optional[str]) -> None: + def _refresh(self, file_names: list[str], error: str | None) -> None: # pylint: disable=too-many-statements # pylint: disable=too-many-branches # pylint: disable=too-many-locals diff --git a/assets/src/ba_data/python/bastd/ui/gather/__init__.py b/assets/src/ba_data/python/bastd/ui/gather/__init__.py index c8de2ced..2eaa49c9 100644 --- a/assets/src/ba_data/python/bastd/ui/gather/__init__.py +++ b/assets/src/ba_data/python/bastd/ui/gather/__init__.py @@ -13,7 +13,7 @@ import ba from bastd.ui.tabs import TabRow if TYPE_CHECKING: - from typing import Optional + pass class GatherTab: @@ -67,7 +67,7 @@ class GatherWindow(ba.Window): MANUAL = 'manual' def __init__(self, - transition: Optional[str] = 'in_right', + transition: str | None = 'in_right', origin_widget: ba.Widget = None): # pylint: disable=too-many-statements # pylint: disable=too-many-locals @@ -79,7 +79,7 @@ class GatherWindow(ba.Window): from bastd.ui.gather.nearbytab import NearbyGatherTab ba.set_analytics_screen('Gather Window') - scale_origin: Optional[tuple[float, float]] + scale_origin: tuple[float, float] | None if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() @@ -94,7 +94,7 @@ class GatherWindow(ba.Window): x_offs = 100 if uiscale is ba.UIScale.SMALL else 0 self._height = (582 if uiscale is ba.UIScale.SMALL else 680 if uiscale is ba.UIScale.MEDIUM else 800) - self._current_tab: Optional[GatherWindow.TabID] = None + self._current_tab: GatherWindow.TabID | None = None extra_top = 20 if uiscale is ba.UIScale.SMALL else 0 self._r = 'gatherWindow' @@ -209,7 +209,7 @@ class GatherWindow(ba.Window): self._scroll_height + 2 * buffer_v), texture=ba.gettexture('scrollWidget'), model_transparent=ba.getmodel('softEdgeOutside')) - self._tab_container: Optional[ba.Widget] = None + self._tab_container: ba.Widget | None = None self._restore_state() @@ -291,7 +291,7 @@ class GatherWindow(ba.Window): for tab in self._tabs.values(): tab.restore_state() - sel: Optional[ba.Widget] + sel: ba.Widget | None winstate = ba.app.ui.window_states.get(type(self), {}) sel_name = winstate.get('sel_name', None) assert isinstance(sel_name, (str, type(None))) diff --git a/assets/src/ba_data/python/bastd/ui/gather/abouttab.py b/assets/src/ba_data/python/bastd/ui/gather/abouttab.py index 87e09377..a782e6cd 100644 --- a/assets/src/ba_data/python/bastd/ui/gather/abouttab.py +++ b/assets/src/ba_data/python/bastd/ui/gather/abouttab.py @@ -11,7 +11,6 @@ import _ba from bastd.ui.gather import GatherTab if TYPE_CHECKING: - from typing import Optional from bastd.ui.gather import GatherWindow @@ -20,7 +19,7 @@ class AboutGatherTab(GatherTab): def __init__(self, window: GatherWindow) -> None: super().__init__(window) - self._container: Optional[ba.Widget] = None + self._container: ba.Widget | None = None def on_activate( self, diff --git a/assets/src/ba_data/python/bastd/ui/gather/manualtab.py b/assets/src/ba_data/python/bastd/ui/gather/manualtab.py index fe0a706b..0f2053a8 100644 --- a/assets/src/ba_data/python/bastd/ui/gather/manualtab.py +++ b/assets/src/ba_data/python/bastd/ui/gather/manualtab.py @@ -15,12 +15,12 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Optional, Union, Callable + from typing import Any, Callable from bastd.ui.gather import GatherWindow -def _safe_set_text(txt: Optional[ba.Widget], - val: Union[str, ba.Lstr], +def _safe_set_text(txt: ba.Widget | None, + val: str | ba.Lstr, success: bool = True) -> None: if txt: ba.textwidget(edit=txt, @@ -31,15 +31,15 @@ def _safe_set_text(txt: Optional[ba.Widget], class _HostLookupThread(threading.Thread): """Thread to fetch an addr.""" - def __init__(self, name: str, port: int, - call: Callable[[Optional[str], int], Any]): + def __init__(self, name: str, port: int, call: Callable[[str | None, int], + Any]): super().__init__() self._name = name self._port = port self._call = call def run(self) -> None: - result: Optional[str] + result: str | None try: import socket result = socket.gethostbyname(self._name) @@ -66,31 +66,31 @@ class ManualGatherTab(GatherTab): def __init__(self, window: GatherWindow) -> None: super().__init__(window) - self._check_button: Optional[ba.Widget] = None - self._doing_access_check: Optional[bool] = None - self._access_check_count: Optional[int] = None + self._check_button: ba.Widget | None = None + self._doing_access_check: bool | None = None + self._access_check_count: int | None = None self._sub_tab: SubTabType = SubTabType.JOIN_BY_ADDRESS - self._t_addr: Optional[ba.Widget] = None - self._t_accessible: Optional[ba.Widget] = None - self._t_accessible_extra: Optional[ba.Widget] = None - self._access_check_timer: Optional[ba.Timer] = None - self._checking_state_text: Optional[ba.Widget] = None - self._container: Optional[ba.Widget] = None - self._join_by_address_text: Optional[ba.Widget] = None - self._favorites_text: Optional[ba.Widget] = None - self._width: Optional[int] = None - self._height: Optional[int] = None - self._scroll_width: Optional[int] = None - self._scroll_height: Optional[int] = None - self._favorites_scroll_width: Optional[int] = None - self._favorites_connect_button: Optional[ba.Widget] = None - self._scrollwidget: Optional[ba.Widget] = None - self._columnwidget: Optional[ba.Widget] = None - self._favorite_selected: Optional[str] = None - self._favorite_edit_window: Optional[ba.Widget] = None - self._party_edit_name_text: Optional[ba.Widget] = None - self._party_edit_addr_text: Optional[ba.Widget] = None - self._party_edit_port_text: Optional[ba.Widget] = None + self._t_addr: ba.Widget | None = None + self._t_accessible: ba.Widget | None = None + self._t_accessible_extra: ba.Widget | None = None + self._access_check_timer: ba.Timer | None = None + self._checking_state_text: ba.Widget | None = None + self._container: ba.Widget | None = None + self._join_by_address_text: ba.Widget | None = None + self._favorites_text: ba.Widget | None = None + self._width: int | None = None + self._height: int | None = None + self._scroll_width: int | None = None + self._scroll_height: int | None = None + self._favorites_scroll_width: int | None = None + self._favorites_connect_button: ba.Widget | None = None + self._scrollwidget: ba.Widget | None = None + self._columnwidget: ba.Widget | None = None + self._favorite_selected: str | None = None + self._favorite_edit_window: ba.Widget | None = None + self._party_edit_name_text: ba.Widget | None = None + self._party_edit_addr_text: ba.Widget | None = None + self._party_edit_port_text: ba.Widget | None = None def on_activate( self, @@ -674,7 +674,7 @@ class ManualGatherTab(GatherTab): ba.screenmessage('Invalid Address', color=(1, 0, 0)) ba.playsound(ba.getsound('error')) - def _host_lookup_result(self, resolved_address: Optional[str], + def _host_lookup_result(self, resolved_address: str | None, port: int) -> None: if resolved_address is None: ba.screenmessage( @@ -723,7 +723,7 @@ class ManualGatherTab(GatherTab): from_other_thread=True) def _on_show_my_address_button_press(self, v2: float, - container: Optional[ba.Widget], + container: ba.Widget | None, c_width: float) -> None: if not container: return @@ -849,7 +849,7 @@ class ManualGatherTab(GatherTab): callback=ba.WeakCall( self._on_accessible_response)) - def _on_accessible_response(self, data: Optional[dict[str, Any]]) -> None: + def _on_accessible_response(self, data: dict[str, Any] | None) -> None: t_addr = self._t_addr t_accessible = self._t_accessible t_accessible_extra = self._t_accessible_extra diff --git a/assets/src/ba_data/python/bastd/ui/gather/nearbytab.py b/assets/src/ba_data/python/bastd/ui/gather/nearbytab.py index 03561cbd..4622d5ad 100644 --- a/assets/src/ba_data/python/bastd/ui/gather/nearbytab.py +++ b/assets/src/ba_data/python/bastd/ui/gather/nearbytab.py @@ -12,7 +12,7 @@ import _ba from bastd.ui.gather import GatherTab if TYPE_CHECKING: - from typing import Optional, Any + from typing import Any from bastd.ui.gather import GatherWindow @@ -30,7 +30,7 @@ class NetScanner: left_border=10) ba.widget(edit=self._columnwidget, up_widget=tab_button) self._width = width - self._last_selected_host: Optional[dict[str, Any]] = None + self._last_selected_host: dict[str, Any] | None = None self._update_timer = ba.Timer(1.0, ba.WeakCall(self.update), @@ -93,8 +93,8 @@ class NearbyGatherTab(GatherTab): def __init__(self, window: GatherWindow) -> None: super().__init__(window) - self._net_scanner: Optional[NetScanner] = None - self._container: Optional[ba.Widget] = None + self._net_scanner: NetScanner | None = None + self._container: ba.Widget | None = None def on_activate( self, diff --git a/assets/src/ba_data/python/bastd/ui/gather/privatetab.py b/assets/src/ba_data/python/bastd/ui/gather/privatetab.py index b1d047ff..4eac79ef 100644 --- a/assets/src/ba_data/python/bastd/ui/gather/privatetab.py +++ b/assets/src/ba_data/python/bastd/ui/gather/privatetab.py @@ -20,7 +20,7 @@ from bastd.ui.gather import GatherTab from bastd.ui import getcurrency if TYPE_CHECKING: - from typing import Optional, Any + from typing import Any from bastd.ui.gather import GatherWindow # Print a bit of info about queries, etc. @@ -44,28 +44,28 @@ class PrivateGatherTab(GatherTab): def __init__(self, window: GatherWindow) -> None: super().__init__(window) - self._container: Optional[ba.Widget] = None + self._container: ba.Widget | None = None self._state: State = State() self._hostingstate = PrivateHostingState() - self._join_sub_tab_text: Optional[ba.Widget] = None - self._host_sub_tab_text: Optional[ba.Widget] = None - self._update_timer: Optional[ba.Timer] = None - self._join_party_code_text: Optional[ba.Widget] = None + self._join_sub_tab_text: ba.Widget | None = None + self._host_sub_tab_text: ba.Widget | None = None + self._update_timer: ba.Timer | None = None + self._join_party_code_text: ba.Widget | None = None self._c_width: float = 0.0 self._c_height: float = 0.0 - self._last_hosting_state_query_time: Optional[float] = None + self._last_hosting_state_query_time: float | None = None self._waiting_for_initial_state = True self._waiting_for_start_stop_response = True - self._host_playlist_button: Optional[ba.Widget] = None - self._host_copy_button: Optional[ba.Widget] = None - self._host_connect_button: Optional[ba.Widget] = None - self._host_start_stop_button: Optional[ba.Widget] = None - self._get_tickets_button: Optional[ba.Widget] = None - self._ticket_count_text: Optional[ba.Widget] = None + self._host_playlist_button: ba.Widget | None = None + self._host_copy_button: ba.Widget | None = None + self._host_connect_button: ba.Widget | None = None + self._host_start_stop_button: ba.Widget | None = None + self._get_tickets_button: ba.Widget | None = None + self._ticket_count_text: ba.Widget | None = None self._showing_not_signed_in_screen = False self._create_time = time.time() - self._last_action_send_time: Optional[float] = None - self._connect_press_time: Optional[float] = None + self._last_action_send_time: float | None = None + self._connect_press_time: float | None = None try: self._hostingconfig = self._build_hosting_config() except Exception: @@ -177,7 +177,7 @@ class PrivateGatherTab(GatherTab): if playlist_name == '__default__' else playlist_name) - playlist: Optional[list[dict[str, Any]]] = None + playlist: list[dict[str, Any]] | None = None if playlist_name != '__default__': playlist = (cfg.get(f'{pvars.config_name} Playlists', {}).get(playlist_name)) @@ -197,7 +197,7 @@ class PrivateGatherTab(GatherTab): hcfg.tutorial = tutorial if hcfg.session_type == 'teams': - ctn: Optional[list[str]] = cfg.get('Custom Team Names') + ctn: list[str] | None = cfg.get('Custom Team Names') if ctn is not None: if (isinstance(ctn, (list, tuple)) and len(ctn) == 2 and all(isinstance(x, str) for x in ctn)): @@ -205,7 +205,7 @@ class PrivateGatherTab(GatherTab): else: print(f'Found invalid custom-team-names data: {ctn}') - ctc: Optional[list[list[float]]] = cfg.get('Custom Team Colors') + ctc: list[list[float]] | None = cfg.get('Custom Team Colors') if ctc is not None: if (isinstance(ctc, (list, tuple)) and len(ctc) == 2 and all(isinstance(x, (list, tuple)) for x in ctc) @@ -269,7 +269,7 @@ class PrivateGatherTab(GatherTab): self._last_hosting_state_query_time = now def _hosting_state_idle_response(self, - result: Optional[dict[str, Any]]) -> None: + result: dict[str, Any] | None) -> None: # This simply passes through to our standard response handler. # The one exception is if we've recently sent an action to the @@ -284,15 +284,14 @@ class PrivateGatherTab(GatherTab): return self._hosting_state_response(result) - def _hosting_state_response(self, result: Optional[dict[str, - Any]]) -> None: + def _hosting_state_response(self, result: dict[str, Any] | None) -> None: # Its possible for this to come back to us after our UI is dead; # ignore in that case. if not self._container: return - state: Optional[PrivateHostingState] = None + state: PrivateHostingState | None = None if result is not None: self._debug_server_comm('got private party state response') try: @@ -344,7 +343,7 @@ class PrivateGatherTab(GatherTab): # Kick off an update to get any needed messages sent/etc. ba.pushcall(self._update) - def _selwidgets(self) -> list[Optional[ba.Widget]]: + def _selwidgets(self) -> list[ba.Widget | None]: """An indexed list of widgets we can use for saving/restoring sel.""" return [ self._host_playlist_button, self._host_copy_button, @@ -357,7 +356,7 @@ class PrivateGatherTab(GatherTab): # Store an index for our current selection so we can # reselect the equivalent recreated widget if possible. - selindex: Optional[int] = None + selindex: int | None = None selchild = self._container.get_selected_child() if selchild is not None: try: @@ -793,7 +792,7 @@ class PrivateGatherTab(GatherTab): # If there's a ticket cost, make sure we have enough tickets. if self._hostingstate.tickets_to_host_now > 0: - ticket_count: Optional[int] + ticket_count: int | None try: ticket_count = _ba.get_v1_account_ticket_count() except Exception: @@ -832,7 +831,7 @@ class PrivateGatherTab(GatherTab): def _join_connect_press(self) -> None: # Error immediately if its an empty code. - code: Optional[str] = None + code: str | None = None if self._join_party_code_text: code = cast(str, ba.textwidget(query=self._join_party_code_text)) if not code: @@ -844,7 +843,7 @@ class PrivateGatherTab(GatherTab): self._connect_to_party_code(code) - def _connect_response(self, result: Optional[dict[str, Any]]) -> None: + def _connect_response(self, result: dict[str, Any] | None) -> None: try: self._connect_press_time = None if result is None: diff --git a/assets/src/ba_data/python/bastd/ui/gather/publictab.py b/assets/src/ba_data/python/bastd/ui/gather/publictab.py index 0261cef5..5eaa2821 100644 --- a/assets/src/ba_data/python/bastd/ui/gather/publictab.py +++ b/assets/src/ba_data/python/bastd/ui/gather/publictab.py @@ -17,7 +17,7 @@ import ba from bastd.ui.gather import GatherTab if TYPE_CHECKING: - from typing import Callable, Any, Optional, Union + from typing import Callable, Any from bastd.ui.gather import GatherWindow # Print a bit of info about pings, queries, etc. @@ -36,19 +36,19 @@ class PartyEntry: """Info about a public party.""" address: str index: int - queue: Optional[str] = None + queue: str | None = None port: int = -1 name: str = '' size: int = -1 size_max: int = -1 claimed: bool = False - ping: Optional[float] = None + ping: float | None = None ping_interval: float = -1.0 next_ping_time: float = -1.0 ping_attempts: int = 0 ping_responses: int = 0 - stats_addr: Optional[str] = None - clean_display_index: Optional[int] = None + stats_addr: str | None = None + clean_display_index: int | None = None def get_key(self) -> str: """Return the key used to store this party.""" @@ -59,10 +59,10 @@ class UIRow: """Wrangles UI for a row in the party list.""" def __init__(self) -> None: - self._name_widget: Optional[ba.Widget] = None - self._size_widget: Optional[ba.Widget] = None - self._ping_widget: Optional[ba.Widget] = None - self._stats_button: Optional[ba.Widget] = None + self._name_widget: ba.Widget | None = None + self._size_widget: ba.Widget | None = None + self._ping_widget: ba.Widget | None = None + self._stats_button: ba.Widget | None = None def __del__(self) -> None: self._clear() @@ -78,7 +78,7 @@ class UIRow: def update(self, index: int, party: PartyEntry, sub_scroll_width: float, sub_scroll_height: float, lineheight: float, columnwidget: ba.Widget, join_text: ba.Widget, - filter_text: ba.Widget, existing_selection: Optional[Selection], + filter_text: ba.Widget, existing_selection: Selection | None, tab: PublicGatherTab) -> None: """Update for the given data.""" # pylint: disable=too-many-locals @@ -182,7 +182,7 @@ class UIRow: class State: """State saved/restored only while the app is running.""" sub_tab: SubTabType = SubTabType.JOIN - parties: Optional[list[tuple[str, PartyEntry]]] = None + parties: list[tuple[str, PartyEntry]] | None = None next_entry_index: int = 0 filter_value: str = '' have_server_list_response: bool = False @@ -231,7 +231,7 @@ class PingThread(threading.Thread): """Thread for sending out game pings.""" def __init__(self, address: str, port: int, - call: Callable[[str, int, Optional[float]], Optional[int]]): + call: Callable[[str, int, float | None], int | None]): super().__init__() self._address = address self._port = port @@ -239,7 +239,7 @@ class PingThread(threading.Thread): def run(self) -> None: ba.app.ping_thread_count += 1 - sock: Optional[socket.socket] = None + sock: socket.socket | None = None try: import socket from ba.internal import get_ip_address_type @@ -255,7 +255,7 @@ class PingThread(threading.Thread): sock.settimeout(1) for _i in range(3): sock.send(b'\x0b') - result: Optional[bytes] + result: bytes | None try: # 11: BA_PACKET_SIMPLE_PING result = sock.recv(10) @@ -291,31 +291,31 @@ class PublicGatherTab(GatherTab): def __init__(self, window: GatherWindow) -> None: super().__init__(window) - self._container: Optional[ba.Widget] = None - self._join_text: Optional[ba.Widget] = None - self._host_text: Optional[ba.Widget] = None - self._filter_text: Optional[ba.Widget] = None - self._local_address: Optional[str] = None - self._last_connect_attempt_time: Optional[float] = None + self._container: ba.Widget | None = None + self._join_text: ba.Widget | None = None + self._host_text: ba.Widget | None = None + self._filter_text: ba.Widget | None = None + self._local_address: str | None = None + self._last_connect_attempt_time: float | None = None self._sub_tab: SubTabType = SubTabType.JOIN - self._selection: Optional[Selection] = None + self._selection: Selection | None = None self._refreshing_list = False - self._update_timer: Optional[ba.Timer] = None - self._host_scrollwidget: Optional[ba.Widget] = None - self._host_name_text: Optional[ba.Widget] = None - self._host_toggle_button: Optional[ba.Widget] = None - self._last_server_list_query_time: Optional[float] = None - self._join_list_column: Optional[ba.Widget] = None - self._join_status_text: Optional[ba.Widget] = None - self._host_max_party_size_value: Optional[ba.Widget] = None - self._host_max_party_size_minus_button: (Optional[ba.Widget]) = None - self._host_max_party_size_plus_button: (Optional[ba.Widget]) = None - self._host_status_text: Optional[ba.Widget] = None + self._update_timer: ba.Timer | None = None + self._host_scrollwidget: ba.Widget | None = None + self._host_name_text: ba.Widget | None = None + self._host_toggle_button: ba.Widget | None = None + self._last_server_list_query_time: float | None = None + self._join_list_column: ba.Widget | None = None + self._join_status_text: ba.Widget | None = None + self._host_max_party_size_value: ba.Widget | None = None + self._host_max_party_size_minus_button: (ba.Widget | None) = None + self._host_max_party_size_plus_button: (ba.Widget | None) = None + self._host_status_text: ba.Widget | None = None self._signed_in = False self._ui_rows: list[UIRow] = [] self._refresh_ui_row = 0 self._have_user_selected_row = False - self._first_valid_server_list_time: Optional[float] = None + self._first_valid_server_list_time: float | None = None # Parties indexed by id: self._parties: dict[str, PartyEntry] = {} @@ -714,8 +714,8 @@ class PublicGatherTab(GatherTab): if _ba.get_public_party_enabled(): self._do_status_check() - def _on_public_party_query_result( - self, result: Optional[dict[str, Any]]) -> None: + def _on_public_party_query_result(self, + result: dict[str, Any] | None) -> None: starttime = time.time() self._have_server_list_response = True @@ -1071,8 +1071,8 @@ class PublicGatherTab(GatherTab): PingThread(party.address, party.port, ba.WeakCall(self._ping_callback)).start() - def _ping_callback(self, address: str, port: Optional[int], - result: Optional[float]) -> None: + def _ping_callback(self, address: str, port: int | None, + result: float | None) -> None: # Look for a widget corresponding to this target. # If we find one, update our list. party_key = f'{address}_{port}' @@ -1100,7 +1100,7 @@ class PublicGatherTab(GatherTab): self._local_address = str(val) def _on_public_party_accessible_response( - self, data: Optional[dict[str, Any]]) -> None: + self, data: dict[str, Any] | None) -> None: # If we've got status text widgets, update them. text = self._host_status_text @@ -1114,7 +1114,7 @@ class PublicGatherTab(GatherTab): ) else: if not data.get('accessible', False): - ex_line: Union[str, ba.Lstr] + ex_line: str | ba.Lstr if self._local_address is not None: ex_line = ba.Lstr( value='\n${A} ${B}', diff --git a/assets/src/ba_data/python/bastd/ui/getcurrency.py b/assets/src/ba_data/python/bastd/ui/getcurrency.py index 040d1c15..e0ef860e 100644 --- a/assets/src/ba_data/python/bastd/ui/getcurrency.py +++ b/assets/src/ba_data/python/bastd/ui/getcurrency.py @@ -10,7 +10,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Optional, Union + from typing import Any class GetCurrencyWindow(ba.Window): @@ -31,14 +31,14 @@ class GetCurrencyWindow(ba.Window): self._store_back_location = store_back_location # ew. self._ad_button_greyed = False - self._smooth_update_timer: Optional[ba.Timer] = None + self._smooth_update_timer: ba.Timer | None = None self._ad_button = None self._ad_label = None self._ad_image = None self._ad_time_text = None # If they provided an origin-widget, scale up from that. - scale_origin: Optional[tuple[float, float]] + scale_origin: tuple[float, float] | None if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() @@ -372,8 +372,8 @@ class GetCurrencyWindow(ba.Window): scale=0.8) # update count now and once per second going forward.. - self._ticking_node: Optional[ba.Node] = None - self._smooth_ticket_count: Optional[float] = None + self._ticking_node: ba.Node | None = None + self._smooth_ticket_count: float | None = None self._ticket_count = 0 self._update() self._update_timer = ba.Timer(1.0, @@ -460,7 +460,7 @@ class GetCurrencyWindow(ba.Window): ba.textwidget(edit=self._ad_label, color=(0.7, 0.9, 0.7, 0.2)) ba.textwidget(edit=self._ad_free_text, color=(1, 1, 0, 0.2)) ba.imagewidget(edit=self._ad_image, opacity=0.6 * 0.25) - sval: Union[str, ba.Lstr] + sval: str | ba.Lstr if (next_reward_ad_time is not None and next_reward_ad_time > now): sval = ba.timestring( @@ -533,7 +533,7 @@ class GetCurrencyWindow(ba.Window): item)) def _purchase_check_result(self, item: str, - result: Optional[dict[str, Any]]) -> None: + result: dict[str, Any] | None) -> None: if result is None: ba.playsound(ba.getsound('error')) ba.screenmessage( diff --git a/assets/src/ba_data/python/bastd/ui/helpui.py b/assets/src/ba_data/python/bastd/ui/helpui.py index 77594b0a..09bc4d50 100644 --- a/assets/src/ba_data/python/bastd/ui/helpui.py +++ b/assets/src/ba_data/python/bastd/ui/helpui.py @@ -10,7 +10,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Optional + pass class HelpWindow(ba.Window): @@ -25,7 +25,7 @@ class HelpWindow(ba.Window): ba.set_analytics_screen('Help Window') # If they provided an origin-widget, scale up from that. - scale_origin: Optional[tuple[float, float]] + scale_origin: tuple[float, float] | None if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() diff --git a/assets/src/ba_data/python/bastd/ui/kiosk.py b/assets/src/ba_data/python/bastd/ui/kiosk.py index 09f92aa9..c748b608 100644 --- a/assets/src/ba_data/python/bastd/ui/kiosk.py +++ b/assets/src/ba_data/python/bastd/ui/kiosk.py @@ -10,7 +10,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Optional + pass class KioskWindow(ba.Window): @@ -182,9 +182,9 @@ class KioskWindow(ba.Window): if not ba.app.did_menu_intro: ba.app.did_menu_intro = True - self._b4: Optional[ba.Widget] - self._b5: Optional[ba.Widget] - self._b6: Optional[ba.Widget] + self._b4: ba.Widget | None + self._b5: ba.Widget | None + self._b6: ba.Widget | None if bool(False): ba.textwidget( @@ -293,7 +293,7 @@ class KioskWindow(ba.Window): else: self._b4 = self._b5 = self._b6 = None - self._b7: Optional[ba.Widget] + self._b7: ba.Widget | None if ba.app.arcade_mode: self._b7 = ba.buttonwidget( parent=self._root_widget, @@ -317,7 +317,7 @@ class KioskWindow(ba.Window): def _restore_state(self) -> None: sel_name = ba.app.ui.window_states.get(type(self)) - sel: Optional[ba.Widget] + sel: ba.Widget | None if sel_name == 'b1': sel = self._b1 elif sel_name == 'b2': diff --git a/assets/src/ba_data/python/bastd/ui/league/rankbutton.py b/assets/src/ba_data/python/bastd/ui/league/rankbutton.py index 3a6ffa54..9b62fc1c 100644 --- a/assets/src/ba_data/python/bastd/ui/league/rankbutton.py +++ b/assets/src/ba_data/python/bastd/ui/league/rankbutton.py @@ -10,7 +10,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Optional, Callable, Union + from typing import Any, Callable class LeagueRankButton: @@ -82,20 +82,20 @@ class LeagueRankButton: transition_delay=transition_delay, color=textcolor) - self._smooth_percent: Optional[float] = None - self._percent: Optional[int] = None - self._smooth_rank: Optional[float] = None - self._rank: Optional[int] = None - self._ticking_node: Optional[ba.Node] = None + self._smooth_percent: float | None = None + self._percent: int | None = None + self._smooth_rank: float | None = None + self._rank: int | None = None + self._ticking_node: ba.Node | None = None self._smooth_increase_speed = 1.0 - self._league: Optional[str] = None - self._improvement_text: Optional[str] = None + self._league: str | None = None + self._improvement_text: str | None = None - self._smooth_update_timer: Optional[ba.Timer] = None + self._smooth_update_timer: ba.Timer | None = None # Take note of our account state; we'll refresh later if this changes. self._account_state_num = _ba.get_v1_account_state_num() - self._last_power_ranking_query_time: Optional[float] = None + self._last_power_ranking_query_time: float | None = None self._doing_power_ranking_query = False self.set_position(position) self._bg_flash = False @@ -191,7 +191,7 @@ class LeagueRankButton: ba.timer(2.0, ba.Call(safe_delete, diff_text), timetype=ba.TimeType.REAL) - status_text: Union[str, ba.Lstr] + status_text: str | ba.Lstr if self._rank is not None: assert self._smooth_rank is not None status_text = ba.Lstr(resource='numberText', @@ -211,8 +211,8 @@ class LeagueRankButton: ba.print_exception('Error doing smooth update.') self._smooth_update_timer = None - def _update_for_league_rank_data(self, data: Optional[dict[str, - Any]]) -> None: + def _update_for_league_rank_data(self, + data: dict[str, Any] | None) -> None: # pylint: disable=too-many-branches # pylint: disable=too-many-statements @@ -220,7 +220,7 @@ class LeagueRankButton: if not self._button: return - status_text: Union[str, ba.Lstr] + status_text: str | ba.Lstr in_top = data is not None and data['rank'] is not None do_percent = False @@ -325,8 +325,8 @@ class LeagueRankButton: ba.textwidget(edit=self._title_text, text=txt, color=t_color) ba.textwidget(edit=self._value_text, text=status_text) - def _on_power_ranking_query_response( - self, data: Optional[dict[str, Any]]) -> None: + def _on_power_ranking_query_response(self, + data: dict[str, Any] | None) -> None: self._doing_power_ranking_query = False ba.app.accounts_v1.cache_league_rank_data(data) self._update_for_league_rank_data(data) diff --git a/assets/src/ba_data/python/bastd/ui/league/rankwindow.py b/assets/src/ba_data/python/bastd/ui/league/rankwindow.py index e1828adc..3a23f89b 100644 --- a/assets/src/ba_data/python/bastd/ui/league/rankwindow.py +++ b/assets/src/ba_data/python/bastd/ui/league/rankwindow.py @@ -12,7 +12,7 @@ import ba from bastd.ui import popup as popup_ui if TYPE_CHECKING: - from typing import Any, Optional, Union + from typing import Any class LeagueRankWindow(ba.Window): @@ -24,11 +24,11 @@ class LeagueRankWindow(ba.Window): origin_widget: ba.Widget = None): ba.set_analytics_screen('League Rank Window') - self._league_rank_data: Optional[dict[str, Any]] = None + self._league_rank_data: dict[str, Any] | None = None self._modal = modal # If they provided an origin-widget, scale up from that. - scale_origin: Optional[tuple[float, float]] + scale_origin: tuple[float, float] | None if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() @@ -105,17 +105,17 @@ class LeagueRankWindow(ba.Window): cancel_button=self._back_button, selected_child=self._back_button) - self._last_power_ranking_query_time: Optional[float] = None + self._last_power_ranking_query_time: float | None = None self._doing_power_ranking_query = False - self._subcontainer: Optional[ba.Widget] = None + self._subcontainer: ba.Widget | None = None self._subcontainerwidth = 800 self._subcontainerheight = 483 self._power_ranking_score_widgets: list[ba.Widget] = [] - self._season_popup_menu: Optional[popup_ui.PopupMenu] = None - self._requested_season: Optional[str] = None - self._season: Optional[str] = None + self._season_popup_menu: popup_ui.PopupMenu | None = None + self._requested_season: str | None = None + self._season: str | None = None # take note of our account state; we'll refresh later if this changes self._account_state = _ba.get_v1_account_state() @@ -190,8 +190,8 @@ class LeagueRankWindow(ba.Window): else: ba.playsound(ba.getsound('error')) - def _on_power_ranking_query_response( - self, data: Optional[dict[str, Any]]) -> None: + def _on_power_ranking_query_response(self, + data: dict[str, Any] | None) -> None: self._doing_power_ranking_query = False # important: *only* cache this if we requested the current season.. if data is not None and data.get('s', None) is None: @@ -351,7 +351,7 @@ class LeagueRankWindow(ba.Window): color=(1, 1, 1, 0.3), maxwidth=200) - self._activity_mult_button: Optional[ba.Widget] + self._activity_mult_button: ba.Widget | None if _ba.get_v1_account_misc_read_val('act', False): self._activity_mult_button = ba.buttonwidget( parent=w_parent, @@ -586,8 +586,8 @@ class LeagueRankWindow(ba.Window): '/highscores?list=powerRankings&v=2' + league_str + season_str + '&player=' + our_login_id) - def _update_for_league_rank_data(self, data: Optional[dict[str, - Any]]) -> None: + def _update_for_league_rank_data(self, + data: dict[str, Any] | None) -> None: # pylint: disable=too-many-statements # pylint: disable=too-many-branches # pylint: disable=too-many-locals @@ -714,7 +714,7 @@ class LeagueRankWindow(ba.Window): self._league_url_arg = (data['l']['n'] + '_' + str(data['l']['i'])).lower() - to_end_string: Union[ba.Lstr, str] + to_end_string: ba.Lstr | str if data is None or self._season == 'a' or data['se'] is None: to_end_string = '' show_season_end = False diff --git a/assets/src/ba_data/python/bastd/ui/mainmenu.py b/assets/src/ba_data/python/bastd/ui/mainmenu.py index 155188b2..4e5c8c52 100644 --- a/assets/src/ba_data/python/bastd/ui/mainmenu.py +++ b/assets/src/ba_data/python/bastd/ui/mainmenu.py @@ -11,13 +11,13 @@ import ba import _ba if TYPE_CHECKING: - from typing import Any, Callable, Optional, Union + from typing import Any, Callable class MainMenuWindow(ba.Window): """The main menu window, both in-game and in the main menu session.""" - def __init__(self, transition: Optional[str] = 'in_right'): + def __init__(self, transition: str | None = 'in_right'): # pylint: disable=cyclic-import import threading from bastd.mainmenu import MainMenuSession @@ -52,14 +52,14 @@ class MainMenuWindow(ba.Window): self._button_height = 45.0 self._width = 100.0 self._height = 100.0 - self._demo_menu_button: Optional[ba.Widget] = None - self._gather_button: Optional[ba.Widget] = None - self._start_button: Optional[ba.Widget] = None - self._watch_button: Optional[ba.Widget] = None - self._gc_button: Optional[ba.Widget] = None - self._how_to_play_button: Optional[ba.Widget] = None - self._credits_button: Optional[ba.Widget] = None - self._settings_button: Optional[ba.Widget] = None + self._demo_menu_button: ba.Widget | None = None + self._gather_button: ba.Widget | None = None + self._start_button: ba.Widget | None = None + self._watch_button: ba.Widget | None = None + self._gc_button: ba.Widget | None = None + self._how_to_play_button: ba.Widget | None = None + self._credits_button: ba.Widget | None = None + self._settings_button: ba.Widget | None = None self._store_char_tex = self._get_store_char_tex() @@ -150,7 +150,7 @@ class MainMenuWindow(ba.Window): self._refresh() self._restore_state() - def get_play_button(self) -> Optional[ba.Widget]: + def get_play_button(self) -> ba.Widget | None: """Return the play button.""" return self._start_button @@ -261,7 +261,7 @@ class MainMenuWindow(ba.Window): label=ba.Lstr(resource=self._r + '.leavePartyText'), on_activate_call=self._confirm_leave_party) - self._store_button: Optional[ba.Widget] + self._store_button: ba.Widget | None if self._have_store_button: this_b_width = self._button_width h, v, scale = positions[self._p_index] @@ -293,7 +293,7 @@ class MainMenuWindow(ba.Window): else: self._store_button = None - self._quit_button: Optional[ba.Widget] + self._quit_button: ba.Widget | None if not self._in_game and self._have_quit_button: h, v, scale = positions[self._p_index] self._p_index += 1 @@ -426,7 +426,7 @@ class MainMenuWindow(ba.Window): self._width = 400.0 self._height = 200.0 enable_account_button = True - account_type_name: Union[str, ba.Lstr] + account_type_name: str | ba.Lstr if _ba.get_v1_account_state() == 'signed_in': account_type_name = _ba.get_v1_account_display_string() account_type_icon = None @@ -981,7 +981,7 @@ class MainMenuWindow(ba.Window): if self._in_game: return sel_name = ba.app.ui.main_menu_selection - sel: Optional[ba.Widget] + sel: ba.Widget | None if sel_name is None: sel_name = 'Start' if sel_name == 'HowToPlay': diff --git a/assets/src/ba_data/python/bastd/ui/onscreenkeyboard.py b/assets/src/ba_data/python/bastd/ui/onscreenkeyboard.py index 4a446a3c..c55917fb 100644 --- a/assets/src/ba_data/python/bastd/ui/onscreenkeyboard.py +++ b/assets/src/ba_data/python/bastd/ui/onscreenkeyboard.py @@ -12,7 +12,7 @@ from ba import charstr from ba import SpecialChar as SpCh if TYPE_CHECKING: - from typing import Optional + pass class OnScreenKeyboardWindow(ba.Window): @@ -72,12 +72,12 @@ class OnScreenKeyboardWindow(ba.Window): self._key_color = (0.69, 0.6, 0.74) self._key_color_dark = (0.55, 0.55, 0.71) - self._shift_button: Optional[ba.Widget] = None - self._backspace_button: Optional[ba.Widget] = None - self._space_button: Optional[ba.Widget] = None + self._shift_button: ba.Widget | None = None + self._backspace_button: ba.Widget | None = None + self._space_button: ba.Widget | None = None self._double_press_shift = False - self._num_mode_button: Optional[ba.Widget] = None - self._emoji_button: Optional[ba.Widget] = None + self._num_mode_button: ba.Widget | None = None + self._emoji_button: ba.Widget | None = None self._char_keys: list[ba.Widget] = [] self._keyboard_index = 0 self._last_space_press = 0.0 @@ -244,7 +244,7 @@ class OnScreenKeyboardWindow(ba.Window): return kbclass() def _refresh(self) -> None: - chars: Optional[list[str]] = None + chars: list[str] | None = None if self._mode in ['normal', 'caps']: chars = list(self._chars) if self._mode == 'caps': diff --git a/assets/src/ba_data/python/bastd/ui/partyqueue.py b/assets/src/ba_data/python/bastd/ui/partyqueue.py index a44f92c6..c68878b3 100644 --- a/assets/src/ba_data/python/bastd/ui/partyqueue.py +++ b/assets/src/ba_data/python/bastd/ui/partyqueue.py @@ -12,7 +12,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Optional, Sequence + from typing import Any, Sequence class PartyQueueWindow(ba.Window): @@ -77,8 +77,8 @@ class PartyQueueWindow(ba.Window): self._update_image() # DEBUG: vis target pos.. - self._body_image_target: Optional[ba.Widget] - self._eyes_image_target: Optional[ba.Widget] + self._body_image_target: ba.Widget | None + self._eyes_image_target: ba.Widget | None if self._debug: self._body_image_target = ba.imagewidget( parent=parent.get_root_widget(), @@ -105,7 +105,7 @@ class PartyQueueWindow(ba.Window): # need to push a deferred call to kill these as necessary instead. # (should bulletproof internal widget code to give a clean error # in this case) - def kill_widgets(widgets: Sequence[Optional[ba.Widget]]) -> None: + def kill_widgets(widgets: Sequence[ba.Widget | None]) -> None: for widget in widgets: if widget: widget.delete() @@ -175,11 +175,11 @@ class PartyQueueWindow(ba.Window): self._queue_id = queue_id self._width = 800 self._height = 400 - self._last_connect_attempt_time: Optional[float] = None - self._last_transaction_time: Optional[float] = None - self._boost_button: Optional[ba.Widget] = None - self._boost_price: Optional[ba.Widget] = None - self._boost_label: Optional[ba.Widget] = None + self._last_connect_attempt_time: float | None = None + self._last_transaction_time: float | None = None + self._boost_button: ba.Widget | None = None + self._boost_price: ba.Widget | None = None + self._boost_label: ba.Widget | None = None self._field_shown = False self._dudes: list[PartyQueueWindow.Dude] = [] self._dudes_by_id: dict[int, PartyQueueWindow.Dude] = {} @@ -193,7 +193,7 @@ class PartyQueueWindow(ba.Window): self._boost_strength = 0.0 self._angry_computer_transparent_model = ba.getmodel( 'angryComputerTransparent') - self._angry_computer_image: Optional[ba.Widget] = None + self._angry_computer_image: ba.Widget | None = None self.lineup_1_transparent_model = ba.getmodel( 'playerLineup1Transparent') self._lineup_2_transparent_model = ba.getmodel( @@ -202,7 +202,7 @@ class PartyQueueWindow(ba.Window): 'playerLineup3Transparent') self._lineup_4_transparent_model = ba.getmodel( 'playerLineup4Transparent') - self._line_image: Optional[ba.Widget] = None + self._line_image: ba.Widget | None = None self.eyes_model = ba.getmodel('plasticEyesTransparent') self._white_tex = ba.gettexture('white') uiscale = ba.app.ui.uiscale @@ -277,7 +277,7 @@ class PartyQueueWindow(ba.Window): """(internal)""" return self._line_bottom - def on_account_press(self, account_id: Optional[str], + def on_account_press(self, account_id: str | None, origin_widget: ba.Widget) -> None: """A dude was clicked so we should show his account info.""" from bastd.ui.account import viewer @@ -357,7 +357,7 @@ class PartyQueueWindow(ba.Window): self._dudes = [] self._dudes_by_id = {} - def on_update_response(self, response: Optional[dict[str, Any]]) -> None: + def on_update_response(self, response: dict[str, Any] | None) -> None: """We've received a response from an update to the server.""" # pylint: disable=too-many-branches if not self._root_widget: diff --git a/assets/src/ba_data/python/bastd/ui/play.py b/assets/src/ba_data/python/bastd/ui/play.py index 5fefb3e3..62809b07 100644 --- a/assets/src/ba_data/python/bastd/ui/play.py +++ b/assets/src/ba_data/python/bastd/ui/play.py @@ -10,7 +10,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Optional + pass class PlayWindow(ba.Window): @@ -37,7 +37,7 @@ class PlayWindow(ba.Window): height = 550 button_width = 400 - scale_origin: Optional[tuple[float, float]] + scale_origin: tuple[float, float] | None if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() @@ -112,7 +112,7 @@ class PlayWindow(ba.Window): 'playerLineup4Transparent') self._eyes_model = ba.getmodel('plasticEyesTransparent') - self._coop_button: Optional[ba.Widget] = None + self._coop_button: ba.Widget | None = None # Only show coop button in main-menu variant. if self._is_main_menu: diff --git a/assets/src/ba_data/python/bastd/ui/playlist/addgame.py b/assets/src/ba_data/python/bastd/ui/playlist/addgame.py index 607226dd..8ca5c6c2 100644 --- a/assets/src/ba_data/python/bastd/ui/playlist/addgame.py +++ b/assets/src/ba_data/python/bastd/ui/playlist/addgame.py @@ -10,7 +10,6 @@ import _ba import ba if TYPE_CHECKING: - from typing import Optional from bastd.ui.playlist.editcontroller import PlaylistEditController @@ -106,13 +105,13 @@ class PlaylistAddGameWindow(ba.Window): up_widget=self._back_button, left_widget=self._back_button, right_widget=select_button) - self._column: Optional[ba.Widget] = None + self._column: ba.Widget | None = None v -= 35 ba.containerwidget(edit=self._root_widget, cancel_button=self._back_button, start_button=select_button) - self._selected_game_type: Optional[type[ba.GameActivity]] = None + self._selected_game_type: type[ba.GameActivity] | None = None ba.containerwidget(edit=self._root_widget, selected_child=self._scrollwidget) diff --git a/assets/src/ba_data/python/bastd/ui/playlist/browser.py b/assets/src/ba_data/python/bastd/ui/playlist/browser.py index 7ca0b333..9dcab822 100644 --- a/assets/src/ba_data/python/bastd/ui/playlist/browser.py +++ b/assets/src/ba_data/python/bastd/ui/playlist/browser.py @@ -12,7 +12,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Optional, Union + pass class PlaylistBrowserWindow(ba.Window): @@ -20,14 +20,14 @@ class PlaylistBrowserWindow(ba.Window): def __init__(self, sessiontype: type[ba.Session], - transition: Optional[str] = 'in_right', + transition: str | None = 'in_right', origin_widget: ba.Widget = None): # pylint: disable=too-many-statements # pylint: disable=cyclic-import from bastd.ui.playlist import PlaylistTypeVars # If they provided an origin-widget, scale up from that. - scale_origin: Optional[tuple[float, float]] + scale_origin: tuple[float, float] | None if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() @@ -49,9 +49,9 @@ class PlaylistBrowserWindow(ba.Window): self._sessiontype = sessiontype - self._customize_button: Optional[ba.Widget] = None - self._sub_width: Optional[float] = None - self._sub_height: Optional[float] = None + self._customize_button: ba.Widget | None = None + self._sub_width: float | None = None + self._sub_height: float | None = None self._ensure_standard_playlists_exist() @@ -76,7 +76,7 @@ class PlaylistBrowserWindow(ba.Window): 1.05 if uiscale is ba.UIScale.MEDIUM else 0.9), stack_offset=(0, -26) if uiscale is ba.UIScale.SMALL else (0, 0))) - self._back_button: Optional[ba.Widget] = ba.buttonwidget( + self._back_button: ba.Widget | None = ba.buttonwidget( parent=self._root_widget, position=(59 + x_inset, self._height - 70), size=(120, 60), @@ -125,7 +125,7 @@ class PlaylistBrowserWindow(ba.Window): position=((self._width - self._scroll_width) * 0.5, 65 + scroll_offs)) ba.containerwidget(edit=self._scrollwidget, claims_left_right=True) - self._subcontainer: Optional[ba.Widget] = None + self._subcontainer: ba.Widget | None = None self._config_name_full = self._pvars.config_name + ' Playlists' self._last_config = None @@ -393,7 +393,7 @@ class PlaylistBrowserWindow(ba.Window): if x == 0: ba.widget(edit=btn, left_widget=self._back_button) - print_name: Optional[Union[str, ba.Lstr]] + print_name: str | ba.Lstr | None if name == '__default__': print_name = self._pvars.default_list_name else: @@ -432,7 +432,7 @@ class PlaylistBrowserWindow(ba.Window): mark_unowned=True) for entry in playlist: mapname = entry['settings']['map'] - maptype: Optional[type[ba.Map]] + maptype: type[ba.Map] | None try: maptype = get_map_class(mapname) except ba.NotFoundError: diff --git a/assets/src/ba_data/python/bastd/ui/playlist/customizebrowser.py b/assets/src/ba_data/python/bastd/ui/playlist/customizebrowser.py index e802521c..c786aea9 100644 --- a/assets/src/ba_data/python/bastd/ui/playlist/customizebrowser.py +++ b/assets/src/ba_data/python/bastd/ui/playlist/customizebrowser.py @@ -12,7 +12,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Optional + from typing import Any class PlaylistCustomizeBrowserWindow(ba.Window): @@ -28,7 +28,7 @@ class PlaylistCustomizeBrowserWindow(ba.Window): # pylint: disable=too-many-statements # pylint: disable=cyclic-import from bastd.ui import playlist - scale_origin: Optional[tuple[float, float]] + scale_origin: tuple[float, float] | None if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() @@ -234,8 +234,8 @@ class PlaylistCustomizeBrowserWindow(ba.Window): if self._config_name_full not in ba.app.config: ba.app.config[self._config_name_full] = {} - self._selected_playlist_name: Optional[str] = None - self._selected_playlist_index: Optional[int] = None + self._selected_playlist_name: str | None = None + self._selected_playlist_index: int | None = None self._playlist_widgets: list[ba.Widget] = [] self._refresh(select_playlist=select_playlist) @@ -539,7 +539,7 @@ class PlaylistCustomizeBrowserWindow(ba.Window): return if self._selected_playlist_name is None: return - plst: Optional[list[dict[str, Any]]] + plst: list[dict[str, Any]] | None if self._selected_playlist_name == '__default__': plst = self._pvars.get_default_list_call() else: diff --git a/assets/src/ba_data/python/bastd/ui/playlist/edit.py b/assets/src/ba_data/python/bastd/ui/playlist/edit.py index 2b9e4c4b..42846d0a 100644 --- a/assets/src/ba_data/python/bastd/ui/playlist/edit.py +++ b/assets/src/ba_data/python/bastd/ui/playlist/edit.py @@ -10,7 +10,6 @@ import ba import _ba if TYPE_CHECKING: - from typing import Optional from bastd.ui.playlist.editcontroller import PlaylistEditController @@ -22,7 +21,7 @@ class PlaylistEditWindow(ba.Window): transition: str = 'in_right'): # pylint: disable=too-many-statements # pylint: disable=too-many-locals - prev_selection: Optional[str] + prev_selection: str | None self._editcontroller = editcontroller self._r = 'editGameListWindow' prev_selection = self._editcontroller.get_edit_ui_selection() diff --git a/assets/src/ba_data/python/bastd/ui/playlist/editcontroller.py b/assets/src/ba_data/python/bastd/ui/playlist/editcontroller.py index bf3e8326..a2a1c0b4 100644 --- a/assets/src/ba_data/python/bastd/ui/playlist/editcontroller.py +++ b/assets/src/ba_data/python/bastd/ui/playlist/editcontroller.py @@ -10,7 +10,7 @@ from typing import TYPE_CHECKING import ba if TYPE_CHECKING: - from typing import Any, Optional + from typing import Any class PlaylistEditController: @@ -34,7 +34,7 @@ class PlaylistEditController: self._sessiontype = sessiontype self._editing_game = False - self._editing_game_type: Optional[type[ba.GameActivity]] = None + self._editing_game_type: type[ba.GameActivity] | None = None self._pvars = PlaylistTypeVars(sessiontype) self._existing_playlist_name = existing_playlist_name self._config_name_full = self._pvars.config_name + ' Playlists' @@ -86,11 +86,11 @@ class PlaylistEditController: """(internal)""" return self._pvars.config_name - def get_existing_playlist_name(self) -> Optional[str]: + def get_existing_playlist_name(self) -> str | None: """(internal)""" return self._existing_playlist_name - def get_edit_ui_selection(self) -> Optional[str]: + def get_edit_ui_selection(self) -> str | None: """(internal)""" return self._edit_ui_selection @@ -156,7 +156,7 @@ class PlaylistEditController: transition='in_left').get_root_widget()) def _show_edit_ui(self, gametype: type[ba.GameActivity], - settings: Optional[dict[str, Any]]) -> None: + settings: dict[str, Any] | None) -> None: self._editing_game = (settings is not None) self._editing_game_type = gametype assert self._sessiontype is not None @@ -167,7 +167,7 @@ class PlaylistEditController: """(internal)""" self._show_edit_ui(gametype=gametype, settings=None) - def _edit_game_done(self, config: Optional[dict[str, Any]]) -> None: + def _edit_game_done(self, config: dict[str, Any] | None) -> None: from bastd.ui.playlist.edit import PlaylistEditWindow from bastd.ui.playlist.addgame import PlaylistAddGameWindow from ba.internal import get_type_name diff --git a/assets/src/ba_data/python/bastd/ui/playlist/editgame.py b/assets/src/ba_data/python/bastd/ui/playlist/editgame.py index 98441087..a4c00071 100644 --- a/assets/src/ba_data/python/bastd/ui/playlist/editgame.py +++ b/assets/src/ba_data/python/bastd/ui/playlist/editgame.py @@ -12,7 +12,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Callable, Optional, Union + from typing import Any, Callable class PlaylistEditGameWindow(ba.Window): @@ -21,8 +21,8 @@ class PlaylistEditGameWindow(ba.Window): def __init__(self, gametype: type[ba.GameActivity], sessiontype: type[ba.Session], - config: Optional[dict[str, Any]], - completion_call: Callable[[Optional[dict[str, Any]]], Any], + config: dict[str, Any] | None, + completion_call: Callable[[dict[str, Any] | None], Any], default_selection: str = None, transition: str = 'in_right', edit_info: dict[str, Any] = None): @@ -392,7 +392,7 @@ class PlaylistEditGameWindow(ba.Window): # Ok now wire up the column. try: # pylint: disable=unsubscriptable-object - prev_widgets: Optional[list[ba.Widget]] = None + prev_widgets: list[ba.Widget] | None = None for cwdg in widget_column: if prev_widgets is not None: # Wire our rightmost to their rightmost. @@ -466,9 +466,9 @@ class PlaylistEditGameWindow(ba.Window): def _add(self) -> None: self._completion_call(copy.deepcopy(self._getconfig())) - def _inc(self, ctrl: ba.Widget, min_val: Union[int, float], - max_val: Union[int, float], increment: Union[int, float], - setting_type: type, setting_name: str) -> None: + def _inc(self, ctrl: ba.Widget, min_val: int | float, max_val: int | float, + increment: int | float, setting_type: type, + setting_name: str) -> None: if setting_type == float: val = float(cast(str, ba.textwidget(query=ctrl))) else: diff --git a/assets/src/ba_data/python/bastd/ui/playlist/mapselect.py b/assets/src/ba_data/python/bastd/ui/playlist/mapselect.py index 2464e0fd..eecbd1af 100644 --- a/assets/src/ba_data/python/bastd/ui/playlist/mapselect.py +++ b/assets/src/ba_data/python/bastd/ui/playlist/mapselect.py @@ -11,7 +11,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Callable, Optional + from typing import Any, Callable class PlaylistMapSelectWindow(ba.Window): @@ -22,7 +22,7 @@ class PlaylistMapSelectWindow(ba.Window): sessiontype: type[ba.Session], config: dict[str, Any], edit_info: dict[str, Any], - completion_call: Callable[[Optional[dict[str, Any]]], Any], + completion_call: Callable[[dict[str, Any] | None], Any], transition: str = 'in_right'): from ba.internal import get_filtered_map_name self._gametype = gametype @@ -86,7 +86,7 @@ class PlaylistMapSelectWindow(ba.Window): selected_child=self._scrollwidget) ba.containerwidget(edit=self._scrollwidget, claims_left_right=True) - self._subcontainer: Optional[ba.Widget] = None + self._subcontainer: ba.Widget | None = None self._refresh() def _refresh(self, select_get_more_maps_button: bool = False) -> None: diff --git a/assets/src/ba_data/python/bastd/ui/playlist/share.py b/assets/src/ba_data/python/bastd/ui/playlist/share.py index 8355c39a..f2987ca1 100644 --- a/assets/src/ba_data/python/bastd/ui/playlist/share.py +++ b/assets/src/ba_data/python/bastd/ui/playlist/share.py @@ -12,7 +12,7 @@ import ba from bastd.ui import promocode if TYPE_CHECKING: - from typing import Any, Callable, Optional + from typing import Any, Callable class SharePlaylistImportWindow(promocode.PromoCodeWindow): @@ -26,7 +26,7 @@ class SharePlaylistImportWindow(promocode.PromoCodeWindow): origin_widget=origin_widget) self._on_success_callback = on_success_callback - def _on_import_response(self, response: Optional[dict[str, Any]]) -> None: + def _on_import_response(self, response: dict[str, Any] | None) -> None: if response is None: ba.screenmessage(ba.Lstr(resource='errorText'), color=(1, 0, 0)) ba.playsound(ba.getsound('error')) diff --git a/assets/src/ba_data/python/bastd/ui/playoptions.py b/assets/src/ba_data/python/bastd/ui/playoptions.py index 2d98d5dd..b200aec5 100644 --- a/assets/src/ba_data/python/bastd/ui/playoptions.py +++ b/assets/src/ba_data/python/bastd/ui/playoptions.py @@ -11,7 +11,7 @@ import ba from bastd.ui import popup if TYPE_CHECKING: - from typing import Any, Optional, Union + from typing import Any class PlayOptionsWindow(popup.PopupWindow): @@ -90,7 +90,7 @@ class PlayOptionsWindow(popup.PopupWindow): game_count = len(plst) for entry in plst: mapname = entry['settings']['map'] - maptype: Optional[type[ba.Map]] + maptype: type[ba.Map] | None try: maptype = get_map_class(mapname) except ba.NotFoundError: @@ -132,9 +132,9 @@ class PlayOptionsWindow(popup.PopupWindow): size=(self._width, self._height), scale=scale) - playlist_name: Union[str, ba.Lstr] = (self._pvars.default_list_name - if playlist == '__default__' else - playlist) + playlist_name: str | ba.Lstr = (self._pvars.default_list_name + if playlist == '__default__' else + playlist) self._title_text = ba.textwidget(parent=self.root_widget, position=(self._width * 0.5, self._height - 89 + 51), @@ -239,7 +239,7 @@ class PlayOptionsWindow(popup.PopupWindow): texture=ba.gettexture('lock')) # Team names/colors. - self._custom_colors_names_button: Optional[ba.Widget] + self._custom_colors_names_button: ba.Widget | None if self._sessiontype is ba.DualTeamSession: y_offs = 50 if show_shuffle_check_box else 0 self._custom_colors_names_button = ba.buttonwidget( diff --git a/assets/src/ba_data/python/bastd/ui/popup.py b/assets/src/ba_data/python/bastd/ui/popup.py index 8a50f8fb..21462633 100644 --- a/assets/src/ba_data/python/bastd/ui/popup.py +++ b/assets/src/ba_data/python/bastd/ui/popup.py @@ -11,7 +11,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Sequence, Callable, Optional, Union + from typing import Any, Sequence, Callable class PopupWindow: @@ -322,7 +322,7 @@ class PopupMenu: self._closing_call = closing_call self.set_choice(self._current_choice) self._on_value_change_call = on_value_change_call - self._window_widget: Optional[ba.Widget] = None + self._window_widget: ba.Widget | None = None # Complain if we outlive our button. ba.uicleanupcheck(self, self._button) @@ -347,7 +347,7 @@ class PopupMenu: """Return the menu's button widget.""" return self._button - def get_window_widget(self) -> Optional[ba.Widget]: + def get_window_widget(self) -> ba.Widget | None: """Return the menu's window widget (or None if nonexistent).""" return self._window_widget @@ -371,7 +371,7 @@ class PopupMenu: def set_choice(self, choice: str) -> None: """Set the selected choice.""" self._current_choice = choice - displayname: Union[str, ba.Lstr] + displayname: str | ba.Lstr if len(self._choices_display) == len(self._choices): displayname = self._choices_display[self._choices.index(choice)] else: diff --git a/assets/src/ba_data/python/bastd/ui/profile/browser.py b/assets/src/ba_data/python/bastd/ui/profile/browser.py index e9aef0b2..febfa833 100644 --- a/assets/src/ba_data/python/bastd/ui/profile/browser.py +++ b/assets/src/ba_data/python/bastd/ui/profile/browser.py @@ -10,7 +10,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Optional + from typing import Any class ProfileBrowserWindow(ba.Window): @@ -39,7 +39,7 @@ class ProfileBrowserWindow(ba.Window): ba.app.pause() # If they provided an origin-widget, scale up from that. - scale_origin: Optional[tuple[float, float]] + scale_origin: tuple[float, float] | None if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() @@ -162,7 +162,7 @@ class ProfileBrowserWindow(ba.Window): border=2, margin=0) v -= 255 - self._profiles: Optional[dict[str, dict[str, Any]]] = None + self._profiles: dict[str, dict[str, Any]] | None = None self._selected_profile = selected_profile self._profile_widgets: list[ba.Widget] = [] self._refresh() @@ -282,7 +282,7 @@ class ProfileBrowserWindow(ba.Window): items = list(self._profiles.items()) items.sort(key=lambda x: asserttype(x[0], str).lower()) index = 0 - account_name: Optional[str] + account_name: str | None if _ba.get_v1_account_state() == 'signed_in': account_name = _ba.get_v1_account_display_string() else: diff --git a/assets/src/ba_data/python/bastd/ui/profile/edit.py b/assets/src/ba_data/python/bastd/ui/profile/edit.py index d0df1374..64500c20 100644 --- a/assets/src/ba_data/python/bastd/ui/profile/edit.py +++ b/assets/src/ba_data/python/bastd/ui/profile/edit.py @@ -11,7 +11,6 @@ import _ba import ba if TYPE_CHECKING: - from typing import Optional from bastd.ui.colorpicker import ColorPicker @@ -27,7 +26,7 @@ class EditProfileWindow(ba.Window): self._in_main_menu).get_root_widget()) def __init__(self, - existing_profile: Optional[str], + existing_profile: str | None, in_main_menu: bool, transition: str = 'in_right'): # FIXME: Tidy this up a bit. diff --git a/assets/src/ba_data/python/bastd/ui/profile/upgrade.py b/assets/src/ba_data/python/bastd/ui/profile/upgrade.py index 0dc86dd3..3142dc96 100644 --- a/assets/src/ba_data/python/bastd/ui/profile/upgrade.py +++ b/assets/src/ba_data/python/bastd/ui/profile/upgrade.py @@ -12,7 +12,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Optional + from typing import Any from bastd.ui.profile.edit import EditProfileWindow @@ -30,7 +30,7 @@ class ProfileUpgradeWindow(ba.Window): uiscale = ba.app.ui.uiscale self._base_scale = (2.05 if uiscale is ba.UIScale.SMALL else 1.5 if uiscale is ba.UIScale.MEDIUM else 1.2) - self._upgrade_start_time: Optional[float] = None + self._upgrade_start_time: float | None = None self._name = edit_profile_window.getname() self._edit_profile_window = weakref.ref(edit_profile_window) @@ -106,7 +106,7 @@ class ProfileUpgradeWindow(ba.Window): h_align='center', v_align='center') - self._tickets_text: Optional[ba.Widget] + self._tickets_text: ba.Widget | None if not ba.app.ui.use_toolbars: self._tickets_text = ba.textwidget( parent=self._root_widget, @@ -128,14 +128,14 @@ class ProfileUpgradeWindow(ba.Window): callback=ba.WeakCall(self._profile_check_result)) self._cost = _ba.get_v1_account_misc_read_val('price.global_profile', 500) - self._status: Optional[str] = 'waiting' + self._status: str | None = 'waiting' self._update_timer = ba.Timer(1.0, ba.WeakCall(self._update), timetype=ba.TimeType.REAL, repeat=True) self._update() - def _profile_check_result(self, result: Optional[dict[str, Any]]) -> None: + def _profile_check_result(self, result: dict[str, Any] | None) -> None: if result is None: ba.textwidget( edit=self._status_text, diff --git a/assets/src/ba_data/python/bastd/ui/promocode.py b/assets/src/ba_data/python/bastd/ui/promocode.py index ce416a54..eb3bf01d 100644 --- a/assets/src/ba_data/python/bastd/ui/promocode.py +++ b/assets/src/ba_data/python/bastd/ui/promocode.py @@ -11,7 +11,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Optional + pass class PromoCodeWindow(ba.Window): @@ -19,7 +19,7 @@ class PromoCodeWindow(ba.Window): def __init__(self, modal: bool = False, origin_widget: ba.Widget = None): - scale_origin: Optional[tuple[float, float]] + scale_origin: tuple[float, float] | None if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() diff --git a/assets/src/ba_data/python/bastd/ui/purchase.py b/assets/src/ba_data/python/bastd/ui/purchase.py index c1a28b11..e5da1061 100644 --- a/assets/src/ba_data/python/bastd/ui/purchase.py +++ b/assets/src/ba_data/python/bastd/ui/purchase.py @@ -10,7 +10,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Optional + from typing import Any class PurchaseWindow(ba.Window): @@ -132,7 +132,7 @@ class PurchaseWindow(ba.Window): if self._items == ['pro']: _ba.purchase('pro') else: - ticket_count: Optional[int] + ticket_count: int | None try: ticket_count = _ba.get_v1_account_ticket_count() except Exception: diff --git a/assets/src/ba_data/python/bastd/ui/serverdialog.py b/assets/src/ba_data/python/bastd/ui/serverdialog.py index 1f98ef7b..f972d068 100644 --- a/assets/src/ba_data/python/bastd/ui/serverdialog.py +++ b/assets/src/ba_data/python/bastd/ui/serverdialog.py @@ -10,7 +10,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Optional + from typing import Any class ServerDialogWindow(ba.Window): @@ -47,7 +47,7 @@ class ServerDialogWindow(ba.Window): maxwidth=self._width * 0.85, max_height=(self._height - 110)) show_cancel = data.get('showCancel', True) - self._cancel_button: Optional[ba.Widget] + self._cancel_button: ba.Widget | None if show_cancel: self._cancel_button = ba.buttonwidget( parent=self._root_widget, diff --git a/assets/src/ba_data/python/bastd/ui/settings/advanced.py b/assets/src/ba_data/python/bastd/ui/settings/advanced.py index f511a7d7..665d86ff 100644 --- a/assets/src/ba_data/python/bastd/ui/settings/advanced.py +++ b/assets/src/ba_data/python/bastd/ui/settings/advanced.py @@ -11,7 +11,7 @@ import ba from bastd.ui import popup as popup_ui if TYPE_CHECKING: - from typing import Any, Optional + from typing import Any class AdvancedSettingsWindow(ba.Window): @@ -31,7 +31,7 @@ class AdvancedSettingsWindow(ba.Window): app = ba.app # If they provided an origin-widget, scale up from that. - scale_origin: Optional[tuple[float, float]] + scale_origin: tuple[float, float] | None if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() @@ -58,9 +58,9 @@ class AdvancedSettingsWindow(ba.Window): stack_offset=(0, -25) if uiscale is ba.UIScale.SMALL else (0, 0))) self._prev_lang = '' self._prev_lang_list: list[str] = [] - self._complete_langs_list: Optional[list] = None + self._complete_langs_list: list | None = None self._complete_langs_error = False - self._language_popup: Optional[popup_ui.PopupMenu] = None + self._language_popup: popup_ui.PopupMenu | None = None # In vr-mode, the internal keyboard is currently the *only* option, # so no need to show this. @@ -378,7 +378,7 @@ class AdvancedSettingsWindow(ba.Window): scale=1.0, maxwidth=430) - self._disable_gyro_check_box: Optional[ConfigCheckBox] = None + self._disable_gyro_check_box: ConfigCheckBox | None = None if self._show_disable_gyro: v -= 42 self._disable_gyro_check_box = ConfigCheckBox( @@ -391,7 +391,7 @@ class AdvancedSettingsWindow(ba.Window): scale=1.0, maxwidth=430) - self._always_use_internal_keyboard_check_box: Optional[ConfigCheckBox] + self._always_use_internal_keyboard_check_box: ConfigCheckBox | None if self._show_always_use_internal_keyboard: v -= 42 self._always_use_internal_keyboard_check_box = ConfigCheckBox( @@ -470,7 +470,7 @@ class AdvancedSettingsWindow(ba.Window): v -= self._spacing * 0.6 - self._vr_test_button: Optional[ba.Widget] + self._vr_test_button: ba.Widget | None if self._do_vr_test_button: v -= self._extra_button_spacing self._vr_test_button = ba.buttonwidget( @@ -484,7 +484,7 @@ class AdvancedSettingsWindow(ba.Window): else: self._vr_test_button = None - self._net_test_button: Optional[ba.Widget] + self._net_test_button: ba.Widget | None if self._do_net_test_button: v -= self._extra_button_spacing self._net_test_button = ba.buttonwidget( @@ -694,7 +694,7 @@ class AdvancedSettingsWindow(ba.Window): self._save_state() ba.timer(0.1, ba.WeakCall(self._rebuild), timetype=ba.TimeType.REAL) - def _completed_langs_cb(self, results: Optional[dict[str, Any]]) -> None: + def _completed_langs_cb(self, results: dict[str, Any] | None) -> None: if results is not None and results['langs'] is not None: self._complete_langs_list = results['langs'] self._complete_langs_error = False diff --git a/assets/src/ba_data/python/bastd/ui/settings/allsettings.py b/assets/src/ba_data/python/bastd/ui/settings/allsettings.py index 4c994acd..8b187738 100644 --- a/assets/src/ba_data/python/bastd/ui/settings/allsettings.py +++ b/assets/src/ba_data/python/bastd/ui/settings/allsettings.py @@ -10,7 +10,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Optional, Union + pass class AllSettingsWindow(ba.Window): @@ -28,7 +28,7 @@ class AllSettingsWindow(ba.Window): threading.Thread(target=self._preload_modules).start() ba.set_analytics_screen('Settings Window') - scale_origin: Optional[tuple[float, float]] + scale_origin: tuple[float, float] | None if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() @@ -98,7 +98,7 @@ class AllSettingsWindow(ba.Window): x_offs5 = x_offs3 def _b_title(x: float, y: float, button: ba.Widget, - text: Union[str, ba.Lstr]) -> None: + text: str | ba.Lstr) -> None: ba.textwidget(parent=self._root_widget, text=text, position=(x + basew * 0.47, y + baseh * 0.22), @@ -265,7 +265,7 @@ class AllSettingsWindow(ba.Window): try: sel_name = ba.app.ui.window_states.get(type(self), {}).get('sel_name') - sel: Optional[ba.Widget] + sel: ba.Widget | None if sel_name == 'Controllers': sel = self._controllers_button elif sel_name == 'Graphics': diff --git a/assets/src/ba_data/python/bastd/ui/settings/audio.py b/assets/src/ba_data/python/bastd/ui/settings/audio.py index 0e27e38f..9ca2979c 100644 --- a/assets/src/ba_data/python/bastd/ui/settings/audio.py +++ b/assets/src/ba_data/python/bastd/ui/settings/audio.py @@ -10,7 +10,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Optional + pass class AudioSettingsWindow(ba.Window): @@ -28,7 +28,7 @@ class AudioSettingsWindow(ba.Window): music = ba.app.music # If they provided an origin-widget, scale up from that. - scale_origin: Optional[tuple[float, float]] + scale_origin: tuple[float, float] | None if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() @@ -122,7 +122,7 @@ class AudioSettingsWindow(ba.Window): v -= 0.5 * spacing - self._vr_head_relative_audio_button: Optional[ba.Widget] + self._vr_head_relative_audio_button: ba.Widget | None if show_vr_head_relative_audio: v -= 40 ba.textwidget(parent=self._root_widget, @@ -165,7 +165,7 @@ class AudioSettingsWindow(ba.Window): else: self._vr_head_relative_audio_button = None - self._soundtrack_button: Optional[ba.Widget] + self._soundtrack_button: ba.Widget | None if show_soundtracks: v -= 1.2 * spacing self._soundtrack_button = ba.buttonwidget( @@ -259,7 +259,7 @@ class AudioSettingsWindow(ba.Window): def _restore_state(self) -> None: try: sel_name = ba.app.ui.window_states.get(type(self)) - sel: Optional[ba.Widget] + sel: ba.Widget | None if sel_name == 'SoundMinus': sel = self._sound_volume_numedit.minusbutton elif sel_name == 'SoundPlus': diff --git a/assets/src/ba_data/python/bastd/ui/settings/controls.py b/assets/src/ba_data/python/bastd/ui/settings/controls.py index 3da6c7cd..0c17fe81 100644 --- a/assets/src/ba_data/python/bastd/ui/settings/controls.py +++ b/assets/src/ba_data/python/bastd/ui/settings/controls.py @@ -10,7 +10,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Optional + pass class ControlsSettingsWindow(ba.Window): @@ -27,7 +27,7 @@ class ControlsSettingsWindow(ba.Window): from bastd.ui import popup as popup_ui self._have_selected_child = False - scale_origin: Optional[tuple[float, float]] + scale_origin: tuple[float, float] | None # If they provided an origin-widget, scale up from that. if origin_widget is not None: @@ -132,11 +132,11 @@ class ControlsSettingsWindow(ba.Window): ba.containerwidget(edit=self._root_widget, cancel_button=btn) # We need these vars to exist even if the buttons don't. - self._gamepads_button: Optional[ba.Widget] = None - self._touch_button: Optional[ba.Widget] = None - self._keyboard_button: Optional[ba.Widget] = None - self._keyboard_2_button: Optional[ba.Widget] = None - self._idevices_button: Optional[ba.Widget] = None + self._gamepads_button: ba.Widget | None = None + self._touch_button: ba.Widget | None = None + self._keyboard_button: ba.Widget | None = None + self._keyboard_2_button: ba.Widget | None = None + self._idevices_button: ba.Widget | None = None ba.textwidget(parent=self._root_widget, position=(0, height - 49), diff --git a/assets/src/ba_data/python/bastd/ui/settings/gamepad.py b/assets/src/ba_data/python/bastd/ui/settings/gamepad.py index b9511382..7f6f1840 100644 --- a/assets/src/ba_data/python/bastd/ui/settings/gamepad.py +++ b/assets/src/ba_data/python/bastd/ui/settings/gamepad.py @@ -10,7 +10,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Optional, Union, Callable + from typing import Any, Callable class GamepadSettingsWindow(ba.Window): @@ -134,7 +134,7 @@ class GamepadSettingsWindow(ba.Window): if val != -1: self._settings[skey] = val - back_button: Optional[ba.Widget] + back_button: ba.Widget | None if self._is_secondary: back_button = ba.buttonwidget(parent=self._root_widget, @@ -161,7 +161,7 @@ class GamepadSettingsWindow(ba.Window): ba.containerwidget(edit=self._root_widget, cancel_button=cancel_button) - save_button: Optional[ba.Widget] + save_button: ba.Widget | None if not self._is_secondary: save_button = ba.buttonwidget( parent=self._root_widget, @@ -471,7 +471,7 @@ class GamepadSettingsWindow(ba.Window): transition='in_scale', transition_out='out_scale') - def get_control_value_name(self, control: str) -> Union[str, ba.Lstr]: + def get_control_value_name(self, control: str) -> str | ba.Lstr: """(internal)""" # pylint: disable=too-many-return-statements assert self._settings is not None @@ -796,7 +796,7 @@ class AwaitGamepadInputWindow(ba.Window): size=(width, 25), color=(1, 1, 1, 0.3), text=str(self._counter)) - self._decrement_timer: Optional[ba.Timer] = ba.Timer( + self._decrement_timer: ba.Timer | None = ba.Timer( 1.0, ba.Call(self._decrement), repeat=True, diff --git a/assets/src/ba_data/python/bastd/ui/settings/gamepadadvanced.py b/assets/src/ba_data/python/bastd/ui/settings/gamepadadvanced.py index 116d0fec..d0eb6460 100644 --- a/assets/src/ba_data/python/bastd/ui/settings/gamepadadvanced.py +++ b/assets/src/ba_data/python/bastd/ui/settings/gamepadadvanced.py @@ -9,7 +9,7 @@ from typing import TYPE_CHECKING import ba if TYPE_CHECKING: - from typing import Optional, Any + from typing import Any from bastd.ui.settings import gamepad as gpsui @@ -334,7 +334,7 @@ class GamepadAdvancedSettingsWindow(ba.Window): pos: tuple[float, float], name: ba.Lstr, control: str, - message: Optional[ba.Lstr] = None) -> tuple[ba.Widget, ba.Widget]: + message: ba.Lstr | None = None) -> tuple[ba.Widget, ba.Widget]: if message is None: message = ba.Lstr(resource=self._parent_window.get_r() + '.pressAnyButtonText') diff --git a/assets/src/ba_data/python/bastd/ui/settings/graphics.py b/assets/src/ba_data/python/bastd/ui/settings/graphics.py index b4e5955a..7a0da71c 100644 --- a/assets/src/ba_data/python/bastd/ui/settings/graphics.py +++ b/assets/src/ba_data/python/bastd/ui/settings/graphics.py @@ -10,7 +10,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Optional + pass class GraphicsSettingsWindow(ba.Window): @@ -25,7 +25,7 @@ class GraphicsSettingsWindow(ba.Window): from bastd.ui import popup from bastd.ui.config import ConfigCheckBox, ConfigNumberEdit # if they provided an origin-widget, scale up from that - scale_origin: Optional[tuple[float, float]] + scale_origin: tuple[float, float] | None if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() @@ -103,7 +103,7 @@ class GraphicsSettingsWindow(ba.Window): size=(60, 60), label=ba.charstr(ba.SpecialChar.BACK)) - self._fullscreen_checkbox: Optional[ba.Widget] + self._fullscreen_checkbox: ba.Widget | None if self._show_fullscreen: v -= fullscreen_spacing_top self._fullscreen_checkbox = ConfigCheckBox( @@ -123,7 +123,7 @@ class GraphicsSettingsWindow(ba.Window): else: self._fullscreen_checkbox = None - self._gamma_controls: Optional[ConfigNumberEdit] + self._gamma_controls: ConfigNumberEdit | None if show_gamma: self._gamma_controls = gmc = ConfigNumberEdit( parent=self._root_widget, diff --git a/assets/src/ba_data/python/bastd/ui/settings/keyboard.py b/assets/src/ba_data/python/bastd/ui/settings/keyboard.py index 42c634cb..2e93f1fc 100644 --- a/assets/src/ba_data/python/bastd/ui/settings/keyboard.py +++ b/assets/src/ba_data/python/bastd/ui/settings/keyboard.py @@ -10,7 +10,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Optional + from typing import Any class ConfigKeyboardWindow(ba.Window): @@ -279,7 +279,7 @@ class AwaitKeyboardInputWindow(ba.Window): size=(width, 25), color=(1, 1, 1, 0.3), text=str(self._counter)) - self._decrement_timer: Optional[ba.Timer] = ba.Timer( + self._decrement_timer: ba.Timer | None = ba.Timer( 1.0, self._decrement, repeat=True, timetype=ba.TimeType.REAL) _ba.capture_keyboard_input(ba.WeakCall(self._button_callback)) diff --git a/assets/src/ba_data/python/bastd/ui/settings/nettesting.py b/assets/src/ba_data/python/bastd/ui/settings/nettesting.py index 0cfee590..536e4e0a 100644 --- a/assets/src/ba_data/python/bastd/ui/settings/nettesting.py +++ b/assets/src/ba_data/python/bastd/ui/settings/nettesting.py @@ -15,7 +15,7 @@ import ba from bastd.ui.settings.testing import TestingWindow if TYPE_CHECKING: - from typing import Callable, Any, Optional + from typing import Callable, Any class NetTestingWindow(ba.Window): @@ -284,7 +284,7 @@ def _test_fetch(baseaddr: str) -> None: raise RuntimeError('Got unexpected response data.') -def _test_nearby_zone_ping(nearest_zone: Optional[tuple[str, float]]) -> None: +def _test_nearby_zone_ping(nearest_zone: tuple[str, float] | None) -> None: """Try to ping nearest v2 zone.""" if nearest_zone is None: raise RuntimeError('No nearest zone.') diff --git a/assets/src/ba_data/python/bastd/ui/settings/plugins.py b/assets/src/ba_data/python/bastd/ui/settings/plugins.py index 13706eff..b8723683 100644 --- a/assets/src/ba_data/python/bastd/ui/settings/plugins.py +++ b/assets/src/ba_data/python/bastd/ui/settings/plugins.py @@ -9,7 +9,7 @@ from typing import TYPE_CHECKING import ba if TYPE_CHECKING: - from typing import Optional + pass class PluginSettingsWindow(ba.Window): @@ -22,7 +22,7 @@ class PluginSettingsWindow(ba.Window): app = ba.app # If they provided an origin-widget, scale up from that. - scale_origin: Optional[tuple[float, float]] + scale_origin: tuple[float, float] | None if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() diff --git a/assets/src/ba_data/python/bastd/ui/settings/testing.py b/assets/src/ba_data/python/bastd/ui/settings/testing.py index 54e8349e..d1f7fb6d 100644 --- a/assets/src/ba_data/python/bastd/ui/settings/testing.py +++ b/assets/src/ba_data/python/bastd/ui/settings/testing.py @@ -11,7 +11,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Callable, Optional + from typing import Any, Callable class TestingWindow(ba.Window): @@ -21,7 +21,7 @@ class TestingWindow(ba.Window): title: ba.Lstr, entries: list[dict[str, Any]], transition: str = 'in_right', - back_call: Optional[Callable[[], ba.Window]] = None): + back_call: Callable[[], ba.Window] | None = None): uiscale = ba.app.ui.uiscale self._width = 600 self._height = 324 if uiscale is ba.UIScale.SMALL else 400 diff --git a/assets/src/ba_data/python/bastd/ui/soundtrack/browser.py b/assets/src/ba_data/python/bastd/ui/soundtrack/browser.py index 5cf74aaa..dd98728d 100644 --- a/assets/src/ba_data/python/bastd/ui/soundtrack/browser.py +++ b/assets/src/ba_data/python/bastd/ui/soundtrack/browser.py @@ -11,7 +11,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Optional + from typing import Any class SoundtrackBrowserWindow(ba.Window): @@ -24,7 +24,7 @@ class SoundtrackBrowserWindow(ba.Window): # pylint: disable=too-many-statements # If they provided an origin-widget, scale up from that. - scale_origin: Optional[tuple[float, float]] + scale_origin: tuple[float, float] | None if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() @@ -195,9 +195,9 @@ class SoundtrackBrowserWindow(ba.Window): if ba.app.ui.use_toolbars else self._scrollwidget) self._col = ba.columnwidget(parent=scrollwidget, border=2, margin=0) - self._soundtracks: Optional[dict[str, Any]] = None - self._selected_soundtrack: Optional[str] = None - self._selected_soundtrack_index: Optional[int] = None + self._soundtracks: dict[str, Any] | None = None + self._selected_soundtrack: str | None = None + self._selected_soundtrack_index: int | None = None self._soundtrack_widgets: list[ba.Widget] = [] self._allow_changing_soundtracks = False self._refresh() diff --git a/assets/src/ba_data/python/bastd/ui/soundtrack/edit.py b/assets/src/ba_data/python/bastd/ui/soundtrack/edit.py index 7e08f0f0..5ab08cac 100644 --- a/assets/src/ba_data/python/bastd/ui/soundtrack/edit.py +++ b/assets/src/ba_data/python/bastd/ui/soundtrack/edit.py @@ -11,14 +11,14 @@ from typing import TYPE_CHECKING, cast import ba if TYPE_CHECKING: - from typing import Any, Union, Optional + from typing import Any class SoundtrackEditWindow(ba.Window): """Window for editing a soundtrack.""" def __init__(self, - existing_soundtrack: Optional[Union[str, dict[str, Any]]], + existing_soundtrack: str | dict[str, Any] | None, transition: str = 'in_right'): # pylint: disable=too-many-statements appconfig = ba.app.config @@ -68,8 +68,8 @@ class SoundtrackEditWindow(ba.Window): if 'Soundtracks' not in appconfig: appconfig['Soundtracks'] = {} - self._soundtrack_name: Optional[str] - self._existing_soundtrack_name: Optional[str] + self._soundtrack_name: str | None + self._existing_soundtrack_name: str | None if existing_soundtrack is not None: # if they passed just a name, pull info from that soundtrack if isinstance(existing_soundtrack, str): @@ -185,8 +185,8 @@ class SoundtrackEditWindow(ba.Window): # FIXME: We should probably convert this to use translations. type_names_translated = ba.app.lang.get_resource('soundtrackTypeNames') - prev_type_button: Optional[ba.Widget] = None - prev_test_button: Optional[ba.Widget] = None + prev_type_button: ba.Widget | None = None + prev_test_button: ba.Widget | None = None for index, song_type in enumerate(types): row = ba.rowwidget(parent=self._col, @@ -322,11 +322,10 @@ class SoundtrackEditWindow(ba.Window): mode=ba.MusicPlayMode.TEST, testsoundtrack=self._soundtrack) - def _get_entry_button_display_name(self, - entry: Any) -> Union[str, ba.Lstr]: + def _get_entry_button_display_name(self, entry: Any) -> str | ba.Lstr: music = ba.app.music etype = music.get_soundtrack_entry_type(entry) - ename: Union[str, ba.Lstr] + ename: str | ba.Lstr if etype == 'default': ename = ba.Lstr(resource=self._r + '.defaultGameMusicText') elif etype in ('musicFile', 'musicFolder'): @@ -335,7 +334,7 @@ class SoundtrackEditWindow(ba.Window): ename = music.get_soundtrack_entry_name(entry) return ename - def _get_entry_button_display_icon_type(self, entry: Any) -> Optional[str]: + def _get_entry_button_display_icon_type(self, entry: Any) -> str | None: music = ba.app.music etype = music.get_soundtrack_entry_type(entry) if etype == 'musicFile': diff --git a/assets/src/ba_data/python/bastd/ui/soundtrack/entrytypeselect.py b/assets/src/ba_data/python/bastd/ui/soundtrack/entrytypeselect.py index 142a6bc4..e3bc6503 100644 --- a/assets/src/ba_data/python/bastd/ui/soundtrack/entrytypeselect.py +++ b/assets/src/ba_data/python/bastd/ui/soundtrack/entrytypeselect.py @@ -10,7 +10,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Callable, Optional + from typing import Any, Callable class SoundtrackEntryTypeSelectWindow(ba.Window): @@ -144,7 +144,7 @@ class SoundtrackEntryTypeSelectWindow(ba.Window): MacMusicAppPlaylistSelectWindow) ba.containerwidget(edit=self._root_widget, transition='out_left') - current_playlist_entry: Optional[str] + current_playlist_entry: str | None if (music.get_soundtrack_entry_type( self._current_entry) == 'iTunesPlaylist'): current_playlist_entry = music.get_soundtrack_entry_name( @@ -181,13 +181,13 @@ class SoundtrackEntryTypeSelectWindow(ba.Window): valid_file_extensions=[], allow_folders=True).get_root_widget()) - def _music_file_selector_cb(self, result: Optional[str]) -> None: + def _music_file_selector_cb(self, result: str | None) -> None: if result is None: self._callback(self._current_entry) else: self._callback({'type': 'musicFile', 'name': result}) - def _music_folder_selector_cb(self, result: Optional[str]) -> None: + def _music_folder_selector_cb(self, result: str | None) -> None: if result is None: self._callback(self._current_entry) else: diff --git a/assets/src/ba_data/python/bastd/ui/soundtrack/macmusicapp.py b/assets/src/ba_data/python/bastd/ui/soundtrack/macmusicapp.py index ff50e6b9..d5b030a9 100644 --- a/assets/src/ba_data/python/bastd/ui/soundtrack/macmusicapp.py +++ b/assets/src/ba_data/python/bastd/ui/soundtrack/macmusicapp.py @@ -10,14 +10,14 @@ from typing import TYPE_CHECKING import ba if TYPE_CHECKING: - from typing import Any, Optional, Callable + from typing import Any, Callable class MacMusicAppPlaylistSelectWindow(ba.Window): """Window for selecting an iTunes playlist.""" def __init__(self, callback: Callable[[Any], Any], - existing_playlist: Optional[str], existing_entry: Any): + existing_playlist: str | None, existing_entry: Any): from ba.macmusicapp import MacMusicAppMusicPlayer self._r = 'editSoundtrackWindow' self._callback = callback diff --git a/assets/src/ba_data/python/bastd/ui/specialoffer.py b/assets/src/ba_data/python/bastd/ui/specialoffer.py index 0457f4b4..82a20d43 100644 --- a/assets/src/ba_data/python/bastd/ui/specialoffer.py +++ b/assets/src/ba_data/python/bastd/ui/specialoffer.py @@ -11,7 +11,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Optional, Union + from typing import Any class SpecialOfferWindow(ba.Window): @@ -31,7 +31,7 @@ class SpecialOfferWindow(ba.Window): # If not, abort and go into zombie mode (the user should never see # us that way). - real_price: Optional[str] + real_price: str | None # Misnomer: 'pro' actually means offer 'pro_sale'. if offer['item'] in ['pro', 'pro_fullprice']: @@ -149,7 +149,7 @@ class SpecialOfferWindow(ba.Window): color=(0.3, 1, 0.3)) self._flash_on = False - self._flashing_timer: Optional[ba.Timer] = ba.Timer( + self._flashing_timer: ba.Timer | None = ba.Timer( 0.05, ba.WeakCall(self._flash_cycle), repeat=True, @@ -363,7 +363,7 @@ class SpecialOfferWindow(ba.Window): from ba import SpecialChar if not self._root_widget: return - sval: Union[str, ba.Lstr] + sval: str | ba.Lstr if _ba.get_v1_account_state() == 'signed_in': sval = (ba.charstr(SpecialChar.TICKET) + str(_ba.get_v1_account_ticket_count())) @@ -391,7 +391,7 @@ class SpecialOfferWindow(ba.Window): # With bundle sales, the price is the name of the IAP. _ba.purchase(self._offer['price']) else: - ticket_count: Optional[int] + ticket_count: int | None try: ticket_count = _ba.get_v1_account_ticket_count() except Exception: diff --git a/assets/src/ba_data/python/bastd/ui/store/browser.py b/assets/src/ba_data/python/bastd/ui/store/browser.py index 9eb9f571..3966567f 100644 --- a/assets/src/ba_data/python/bastd/ui/store/browser.py +++ b/assets/src/ba_data/python/bastd/ui/store/browser.py @@ -14,7 +14,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Callable, Optional, Union, Sequence + from typing import Any, Callable, Sequence class StoreBrowserWindow(ba.Window): @@ -45,7 +45,7 @@ class StoreBrowserWindow(ba.Window): ba.set_analytics_screen('Store Window') - scale_origin: Optional[tuple[float, float]] + scale_origin: tuple[float, float] | None # If they provided an origin-widget, scale up from that. if origin_widget is not None: @@ -56,8 +56,8 @@ class StoreBrowserWindow(ba.Window): self._transition_out = 'out_right' scale_origin = None - self.button_infos: Optional[dict[str, dict[str, Any]]] = None - self.update_buttons_timer: Optional[ba.Timer] = None + self.button_infos: dict[str, dict[str, Any]] | None = None + self.update_buttons_timer: ba.Timer | None = None self._status_textwidget_update_timer = None self._back_location = back_location @@ -68,12 +68,12 @@ class StoreBrowserWindow(ba.Window): self._x_inset = x_inset = 100 if uiscale is ba.UIScale.SMALL else 0 self._height = (578 if uiscale is ba.UIScale.SMALL else 645 if uiscale is ba.UIScale.MEDIUM else 800) - self._current_tab: Optional[StoreBrowserWindow.TabID] = None + self._current_tab: StoreBrowserWindow.TabID | None = None extra_top = 30 if uiscale is ba.UIScale.SMALL else 0 self._request: Any = None self._r = 'store' - self._last_buy_time: Optional[float] = None + self._last_buy_time: float | None = None super().__init__(root_widget=ba.containerwidget( size=(self._width, self._height + extra_top), @@ -96,8 +96,8 @@ class StoreBrowserWindow(ba.Window): on_activate_call=self._back) ba.containerwidget(edit=self._root_widget, cancel_button=btn) - self._ticket_count_text: Optional[ba.Widget] = None - self._get_tickets_button: Optional[ba.Widget] = None + self._ticket_count_text: ba.Widget | None = None + self._get_tickets_button: ba.Widget | None = None if ba.app.allow_ticket_purchases: self._get_tickets_button = ba.buttonwidget( @@ -265,8 +265,8 @@ class StoreBrowserWindow(ba.Window): self._scroll_width = self._width - scroll_buffer_h self._scroll_height = self._height - 180 - self._scrollwidget: Optional[ba.Widget] = None - self._status_textwidget: Optional[ba.Widget] = None + self._scrollwidget: ba.Widget | None = None + self._status_textwidget: ba.Widget | None = None self._restore_state() def _update_get_tickets_button_pos(self) -> None: @@ -322,7 +322,7 @@ class StoreBrowserWindow(ba.Window): from ba import SpecialChar if not self._root_widget: return - sval: Union[str, ba.Lstr] + sval: str | ba.Lstr if _ba.get_v1_account_state() == 'signed_in': sval = ba.charstr(SpecialChar.TICKET) + str( _ba.get_v1_account_ticket_count()) @@ -387,7 +387,7 @@ class StoreBrowserWindow(ba.Window): ba.WeakCall(self._on_response, data), timetype=ba.TimeType.REAL) - def _on_response(self, data: Optional[dict[str, Any]]) -> None: + def _on_response(self, data: dict[str, Any] | None) -> None: # FIXME: clean this up. # pylint: disable=protected-access window = self._window() @@ -401,7 +401,7 @@ class StoreBrowserWindow(ba.Window): # Actually start the purchase locally. def _purchase_check_result(self, item: str, is_ticket_purchase: bool, - result: Optional[dict[str, Any]]) -> None: + result: dict[str, Any] | None) -> None: if result is None: ba.playsound(ba.getsound('error')) ba.screenmessage( @@ -564,8 +564,8 @@ class StoreBrowserWindow(ba.Window): purchased = _ba.get_purchased(b_type) sale_opacity = 0.0 - sale_title_text: Union[str, ba.Lstr] = '' - sale_time_text: Union[str, ba.Lstr] = '' + sale_title_text: str | ba.Lstr = '' + sale_time_text: str | ba.Lstr = '' if purchased: title_color = (0.8, 0.7, 0.9, 1.0) @@ -686,7 +686,7 @@ class StoreBrowserWindow(ba.Window): ba.textwidget(edit=b_info['descriptionText'], color=description_color) - def _on_response(self, data: Optional[dict[str, Any]]) -> None: + def _on_response(self, data: dict[str, Any] | None) -> None: # pylint: disable=too-many-statements # clear status text.. @@ -719,7 +719,7 @@ class StoreBrowserWindow(ba.Window): store_data = get_store_layout() self._tab = sdata['tab'] self._sections = copy.deepcopy(store_data[sdata['tab']]) - self._height: Optional[float] = None + self._height: float | None = None uiscale = ba.app.ui.uiscale @@ -856,7 +856,7 @@ class StoreBrowserWindow(ba.Window): maxwidth=700, transition_delay=0.4) - prev_row_buttons: Optional[list] = None + prev_row_buttons: list | None = None this_row_buttons = [] delay = 0.3 @@ -1021,7 +1021,7 @@ class StoreBrowserWindow(ba.Window): def _restore_state(self) -> None: from efro.util import enum_by_value try: - sel: Optional[ba.Widget] + sel: ba.Widget | None sel_name = ba.app.ui.window_states.get(type(self), {}).get('sel_name') assert isinstance(sel_name, (str, type(None))) diff --git a/assets/src/ba_data/python/bastd/ui/store/item.py b/assets/src/ba_data/python/bastd/ui/store/item.py index f7e6198f..5a98eddd 100644 --- a/assets/src/ba_data/python/bastd/ui/store/item.py +++ b/assets/src/ba_data/python/bastd/ui/store/item.py @@ -9,7 +9,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Optional + from typing import Any def instantiate_store_item_display(item_name: str, @@ -39,7 +39,7 @@ def instantiate_store_item_display(item_name: str, item['name'] = title = get_store_item_name_translated(item_name) - btn: Optional[ba.Widget] + btn: ba.Widget | None if button: item['button'] = btn = ba.buttonwidget(parent=parent_widget, position=b_pos, @@ -61,9 +61,9 @@ def instantiate_store_item_display(item_name: str, tint_tex = None tint_color = None tint2_color = None - tex_name: Optional[str] = None - desc: Optional[str] = None - modes: Optional[ba.Lstr] = None + tex_name: str | None = None + desc: str | None = None + modes: ba.Lstr | None = None if item_name.startswith('characters.'): character = ba.app.spaz_appearances[item_info['character']] @@ -272,7 +272,7 @@ def instantiate_store_item_display(item_name: str, # the user knows how much this is worth. total_worth_item = _ba.get_v1_account_misc_read_val('twrths', {}).get(item_name) - total_worth_price: Optional[str] + total_worth_price: str | None if total_worth_item is not None: price = _ba.get_price(total_worth_item) total_worth_price = (get_clean_price(price) diff --git a/assets/src/ba_data/python/bastd/ui/tabs.py b/assets/src/ba_data/python/bastd/ui/tabs.py index b3dc38a0..99ae0dbf 100644 --- a/assets/src/ba_data/python/bastd/ui/tabs.py +++ b/assets/src/ba_data/python/bastd/ui/tabs.py @@ -10,7 +10,7 @@ from typing import TYPE_CHECKING, TypeVar, Generic import ba if TYPE_CHECKING: - from typing import Any, Callable, Optional + from typing import Any, Callable @dataclass @@ -71,7 +71,8 @@ class TabRow(Generic[T]): color=(0.52, 0.48, 0.63), textcolor=(0.65, 0.6, 0.7)) # unlit - def _tick_and_call(self, call: Optional[Callable], arg: Any) -> None: + def _tick_and_call(self, call: Callable[[Any], None] | None, + arg: Any) -> None: ba.playsound(ba.getsound('click01')) if call is not None: call(arg) diff --git a/assets/src/ba_data/python/bastd/ui/tournamententry.py b/assets/src/ba_data/python/bastd/ui/tournamententry.py index 7419c4c8..f5213804 100644 --- a/assets/src/ba_data/python/bastd/ui/tournamententry.py +++ b/assets/src/ba_data/python/bastd/ui/tournamententry.py @@ -11,7 +11,7 @@ import ba from bastd.ui import popup if TYPE_CHECKING: - from typing import Any, Callable, Optional + from typing import Any, Callable class TournamentEntryWindow(popup.PopupWindow): @@ -56,7 +56,7 @@ class TournamentEntryWindow(popup.PopupWindow): self._purchase_name = 'tournament_entry_0' self._purchase_price_name = 'price.tournament_entry_0' - self._purchase_price: Optional[int] = None + self._purchase_price: int | None = None self._on_close_call = on_close_call if scale is None: @@ -153,7 +153,7 @@ class TournamentEntryWindow(popup.PopupWindow): text='', maxwidth=95, color=(0, 0.8, 0)) - self._pay_with_ad_btn: Optional[ba.Widget] + self._pay_with_ad_btn: ba.Widget | None if self._do_ad_btn: btn = self._pay_with_ad_btn = ba.buttonwidget( parent=self.root_widget, @@ -214,8 +214,8 @@ class TournamentEntryWindow(popup.PopupWindow): else: self._pay_with_ad_btn = None - self._get_tickets_button: Optional[ba.Widget] = None - self._ticket_count_text: Optional[ba.Widget] = None + self._get_tickets_button: ba.Widget | None = None + self._ticket_count_text: ba.Widget | None = None if not ba.app.ui.use_toolbars: if ba.app.allow_ticket_purchases: self._get_tickets_button = ba.buttonwidget( @@ -270,7 +270,7 @@ class TournamentEntryWindow(popup.PopupWindow): maxwidth=100, color=(0.7, 0.7, 0.7)) - self._last_query_time: Optional[float] = None + self._last_query_time: float | None = None # If there seems to be a relatively-recent valid cached info for this # tournament, use it. Otherwise we'll kick off a query ourselves. @@ -303,8 +303,8 @@ class TournamentEntryWindow(popup.PopupWindow): self._update() self._restore_state() - def _on_tournament_query_response(self, data: Optional[dict[str, - Any]]) -> None: + def _on_tournament_query_response(self, + data: dict[str, Any] | None) -> None: accounts = ba.app.accounts_v1 self._running_query = False if data is not None: @@ -511,7 +511,7 @@ class TournamentEntryWindow(popup.PopupWindow): return # Deny if we don't have enough tickets. - ticket_count: Optional[int] + ticket_count: int | None try: ticket_count = _ba.get_v1_account_ticket_count() except Exception: diff --git a/assets/src/ba_data/python/bastd/ui/watch.py b/assets/src/ba_data/python/bastd/ui/watch.py index c7e871e6..fc870c8c 100644 --- a/assets/src/ba_data/python/bastd/ui/watch.py +++ b/assets/src/ba_data/python/bastd/ui/watch.py @@ -12,7 +12,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Optional + from typing import Any class WatchWindow(ba.Window): @@ -24,13 +24,13 @@ class WatchWindow(ba.Window): TEST_TAB = 'test_tab' def __init__(self, - transition: Optional[str] = 'in_right', + transition: str | None = 'in_right', origin_widget: ba.Widget = None): # pylint: disable=too-many-locals # pylint: disable=too-many-statements from bastd.ui.tabs import TabRow ba.set_analytics_screen('Watch Window') - scale_origin: Optional[tuple[float, float]] + scale_origin: tuple[float, float] | None if origin_widget is not None: self._transition_out = 'out_scale' scale_origin = origin_widget.get_screen_space_center() @@ -40,20 +40,20 @@ class WatchWindow(ba.Window): scale_origin = None ba.app.ui.set_main_menu_location('Watch') self._tab_data: dict[str, Any] = {} - self._my_replays_scroll_width: Optional[float] = None - self._my_replays_watch_replay_button: Optional[ba.Widget] = None - self._scrollwidget: Optional[ba.Widget] = None - self._columnwidget: Optional[ba.Widget] = None - self._my_replay_selected: Optional[str] = None - self._my_replays_rename_window: Optional[ba.Widget] = None - self._my_replay_rename_text: Optional[ba.Widget] = None + self._my_replays_scroll_width: float | None = None + self._my_replays_watch_replay_button: ba.Widget | None = None + self._scrollwidget: ba.Widget | None = None + self._columnwidget: ba.Widget | None = None + self._my_replay_selected: str | None = None + self._my_replays_rename_window: ba.Widget | None = None + self._my_replay_rename_text: ba.Widget | None = None self._r = 'watchWindow' uiscale = ba.app.ui.uiscale self._width = 1240 if uiscale is ba.UIScale.SMALL else 1040 x_inset = 100 if uiscale is ba.UIScale.SMALL else 0 self._height = (578 if uiscale is ba.UIScale.SMALL else 670 if uiscale is ba.UIScale.MEDIUM else 800) - self._current_tab: Optional[WatchWindow.TabID] = None + self._current_tab: WatchWindow.TabID | None = None extra_top = 20 if uiscale is ba.UIScale.SMALL else 0 super().__init__(root_widget=ba.containerwidget( @@ -137,7 +137,7 @@ class WatchWindow(ba.Window): self._scroll_height + 2 * buffer_v), texture=ba.gettexture('scrollWidget'), model_transparent=ba.getmodel('softEdgeOutside')) - self._tab_container: Optional[ba.Widget] = None + self._tab_container: ba.Widget | None = None self._restore_state() @@ -503,7 +503,7 @@ class WatchWindow(ba.Window): def _restore_state(self) -> None: from efro.util import enum_by_value try: - sel: Optional[ba.Widget] + sel: ba.Widget | None sel_name = ba.app.ui.window_states.get(type(self), {}).get('sel_name') assert isinstance(sel_name, (str, type(None))) diff --git a/src/ballistica/ballistica.cc b/src/ballistica/ballistica.cc index 1641ce34..160f1064 100644 --- a/src/ballistica/ballistica.cc +++ b/src/ballistica/ballistica.cc @@ -21,7 +21,7 @@ namespace ballistica { // These are set automatically via script; don't modify them here. -const int kAppBuildNumber = 20615; +const int kAppBuildNumber = 20617; const char* kAppVersion = "1.7.2"; // Our standalone globals. diff --git a/src/ballistica/python/class/python_class_input_device.cc b/src/ballistica/python/class/python_class_input_device.cc index 1a6269b2..590e0800 100644 --- a/src/ballistica/python/class/python_class_input_device.cc +++ b/src/ballistica/python/class/python_class_input_device.cc @@ -31,7 +31,7 @@ void PythonClassInputDevice::SetupType(PyTypeObject* obj) { " on the actual device. (Can be used to determine whether to show\n" " them in controls-overlays, etc.).\n" "\n" - " player (Optional[ba.SessionPlayer]):\n" + " player (ba.SessionPlayer | None):\n" " The player associated with this input device.\n" "\n" " client_id (int):\n" diff --git a/src/ballistica/python/class/python_class_material.cc b/src/ballistica/python/class/python_class_material.cc index 8de56cbd..7d9b79a4 100644 --- a/src/ballistica/python/class/python_class_material.cc +++ b/src/ballistica/python/class/python_class_material.cc @@ -275,7 +275,7 @@ auto PythonClassMaterial::AddActions(PythonClassMaterial* self, PyObject* args, PyMethodDef PythonClassMaterial::tp_methods[] = { {"add_actions", (PyCFunction)AddActions, METH_VARARGS | METH_KEYWORDS, - "add_actions(actions: tuple, conditions: Optional[tuple] = None)\n" + "add_actions(actions: tuple, conditions: tuple | None = None)\n" " -> None\n" "\n" "Add one or more actions to the material, optionally with conditions.\n" diff --git a/src/ballistica/python/class/python_class_session_player.cc b/src/ballistica/python/class/python_class_session_player.cc index 953dc563..7b7d1c41 100644 --- a/src/ballistica/python/class/python_class_session_player.cc +++ b/src/ballistica/python/class/python_class_session_player.cc @@ -90,7 +90,7 @@ void PythonClassSessionPlayer::SetupType(PyTypeObject* obj) { " " ATTR_CHARACTER " (str):\n" " The character this player has selected in their profile.\n" "\n" - " " ATTR_ACTIVITYPLAYER " (Optional[ba.Player]):\n" + " " ATTR_ACTIVITYPLAYER " (ba.Player | None):\n" " The current game-specific instance for this player.\n"; // clang-format on @@ -695,7 +695,7 @@ PyMethodDef PythonClassSessionPlayer::tp_methods[] = { "\n" "Return whether the underlying player is still in the game."}, {"assigninput", (PyCFunction)AssignInputCall, METH_VARARGS | METH_KEYWORDS, - "assigninput(type: Union[ba.InputType, tuple[ba.InputType, ...]],\n" + "assigninput(type: ba.InputType | tuple[ba.InputType, ...],\n" " call: Callable) -> None\n" "\n" "Set the python callable to be run for one or more types of input."}, @@ -724,11 +724,11 @@ PyMethodDef PythonClassSessionPlayer::tp_methods[] = { "\n" "(internal)"}, {"setactivity", (PyCFunction)SetActivity, METH_VARARGS | METH_KEYWORDS, - "setactivity(activity: Optional[ba.Activity]) -> None\n" + "setactivity(activity: ba.Activity | None) -> None\n" "\n" "(internal)"}, {"setnode", (PyCFunction)SetNode, METH_VARARGS | METH_KEYWORDS, - "setnode(node: Optional[Node]) -> None\n" + "setnode(node: Node | None) -> None\n" "\n" "(internal)"}, {"get_icon", (PyCFunction)GetIcon, METH_NOARGS, diff --git a/src/ballistica/python/class/python_class_widget.cc b/src/ballistica/python/class/python_class_widget.cc index 5311ee6b..81ee6cd2 100644 --- a/src/ballistica/python/class/python_class_widget.cc +++ b/src/ballistica/python/class/python_class_widget.cc @@ -278,7 +278,7 @@ PyMethodDef PythonClassWidget::tp_methods[] = { "of the screen. This can be useful for placing pop-up windows and other\n" "special cases."}, {"get_selected_child", (PyCFunction)GetSelectedChild, METH_NOARGS, - "get_selected_child() -> Optional[ba.Widget]\n" + "get_selected_child() -> ba.Widget | None\n" "\n" "Returns the selected child Widget or None if nothing is selected."}, // NOLINTNEXTLINE (signed bitwise stuff) diff --git a/src/ballistica/python/methods/python_methods_app.cc b/src/ballistica/python/methods/python_methods_app.cc index 51a2d652..25a8fff6 100644 --- a/src/ballistica/python/methods/python_methods_app.cc +++ b/src/ballistica/python/methods/python_methods_app.cc @@ -911,8 +911,7 @@ auto PythonMethodsApp::GetMethods() -> std::vector { "(internal)\n"}, {"time_format_check", (PyCFunction)PyTimeFormatCheck, METH_VARARGS | METH_KEYWORDS, - "time_format_check(time_format: ba.TimeFormat, length: Union[float, " - "int])\n" + "time_format_check(time_format: ba.TimeFormat, length: float | int)\n" " -> None\n" "\n" "(internal)\n" @@ -996,7 +995,7 @@ auto PythonMethodsApp::GetMethods() -> std::vector { {"screenmessage", (PyCFunction)PyScreenMessage, METH_VARARGS | METH_KEYWORDS, - "screenmessage(message: Union[str, ba.Lstr],\n" + "screenmessage(message: str | ba.Lstr,\n" " color: Sequence[float] = None, top: bool = False,\n" " image: dict[str, Any] = None, log: bool = False,\n" " clients: Sequence[int] = None, transient: bool = False) -> None\n" @@ -1169,7 +1168,7 @@ auto PythonMethodsApp::GetMethods() -> std::vector { {"get_foreground_host_session", (PyCFunction)PyGetForegroundHostSession, METH_VARARGS | METH_KEYWORDS, - "get_foreground_host_session() -> Optional[ba.Session]\n" + "get_foreground_host_session() -> ba.Session | None\n" "\n" "(internal)\n" "\n" diff --git a/src/ballistica/python/methods/python_methods_gameplay.cc b/src/ballistica/python/methods/python_methods_gameplay.cc index b3d0559b..5e7b73c3 100644 --- a/src/ballistica/python/methods/python_methods_gameplay.cc +++ b/src/ballistica/python/methods/python_methods_gameplay.cc @@ -658,7 +658,7 @@ auto PythonMethodsGameplay::GetMethods() -> std::vector { {"get_foreground_host_activity", (PyCFunction)PyGetForegroundHostActivity, METH_VARARGS | METH_KEYWORDS, - "get_foreground_host_activity() -> Optional[ba.Activity]\n" + "get_foreground_host_activity() -> ba.Activity | None\n" "\n" "(internal)\n" "\n" @@ -678,7 +678,7 @@ auto PythonMethodsGameplay::GetMethods() -> std::vector { {"emitfx", (PyCFunction)PyEmitFx, METH_VARARGS | METH_KEYWORDS, "emitfx(position: Sequence[float],\n" - " velocity: Optional[Sequence[float]] = None,\n" + " velocity: Sequence[float] | None = None,\n" " count: int = 10, scale: float = 1.0, spread: float = 1.0,\n" " chunk_type: str = 'rock', emit_type: str ='chunks',\n" " tendril_type: str = 'smoke') -> None\n" diff --git a/src/ballistica/python/methods/python_methods_graphics.cc b/src/ballistica/python/methods/python_methods_graphics.cc index 4af0ef13..3ae7f913 100644 --- a/src/ballistica/python/methods/python_methods_graphics.cc +++ b/src/ballistica/python/methods/python_methods_graphics.cc @@ -304,7 +304,7 @@ auto PyGetDisplayResolution(PyObject* self, PyObject* args) -> PyObject* { auto PythonMethodsGraphics::GetMethods() -> std::vector { return { {"get_display_resolution", PyGetDisplayResolution, METH_VARARGS, - "get_display_resolution() -> Optional[tuple[int, int]]\n" + "get_display_resolution() -> tuple[int, int] | None\n" "\n" "(internal)\n" "\n" diff --git a/src/ballistica/python/methods/python_methods_input.cc b/src/ballistica/python/methods/python_methods_input.cc index a38b9620..d1ffdf2f 100644 --- a/src/ballistica/python/methods/python_methods_input.cc +++ b/src/ballistica/python/methods/python_methods_input.cc @@ -232,7 +232,7 @@ auto PythonMethodsInput::GetMethods() -> std::vector { {"set_ui_input_device", (PyCFunction)PySetUIInputDevice, METH_VARARGS | METH_KEYWORDS, - "set_ui_input_device(input_device: Optional[ba.InputDevice]) -> None\n" + "set_ui_input_device(input_device: ba.InputDevice | None) -> None\n" "\n" "(internal)\n" "\n" diff --git a/src/ballistica/python/methods/python_methods_ui.cc b/src/ballistica/python/methods/python_methods_ui.cc index 7712a52b..18f5468a 100644 --- a/src/ballistica/python/methods/python_methods_ui.cc +++ b/src/ballistica/python/methods/python_methods_ui.cc @@ -2365,7 +2365,7 @@ auto PythonMethodsUI::GetMethods() -> std::vector { "(internal)"}, {"chatmessage", (PyCFunction)PyChatMessage, METH_VARARGS | METH_KEYWORDS, - "chatmessage(message: Union[str, ba.Lstr],\n" + "chatmessage(message: str | ba.Lstr,\n" " clients: Sequence[int] = None,\n" " sender_override: str = None) -> None\n" "\n" @@ -2387,8 +2387,8 @@ auto PythonMethodsUI::GetMethods() -> std::vector { {"show_app_invite", (PyCFunction)PyShowAppInvite, METH_VARARGS | METH_KEYWORDS, - "show_app_invite(title: Union[str, ba.Lstr],\n" - " message: Union[str, ba.Lstr],\n" + "show_app_invite(title: str | ba.Lstr,\n" + " message: str | ba.Lstr,\n" " code: str) -> None\n" "\n" "(internal)\n" @@ -2410,7 +2410,7 @@ auto PythonMethodsUI::GetMethods() -> std::vector { {"fade_screen", (PyCFunction)PyFadeScreen, METH_VARARGS | METH_KEYWORDS, "fade_screen(to: int = 0, time: float = 0.25,\n" - " endcall: Optional[Callable[[], None]] = None) -> None\n" + " endcall: Callable[[], None] | None = None) -> None\n" "\n" "(internal)\n" "\n" @@ -2453,7 +2453,7 @@ auto PythonMethodsUI::GetMethods() -> std::vector { " size: Sequence[float] = None,\n" " position: Sequence[float] = None,\n" " on_activate_call: Callable = None,\n" - " label: Union[str, ba.Lstr] = None,\n" + " label: str | ba.Lstr | None = None,\n" " color: Sequence[float] = None,\n" " down_widget: ba.Widget = None,\n" " up_widget: ba.Widget = None,\n" @@ -2500,7 +2500,7 @@ auto PythonMethodsUI::GetMethods() -> std::vector { " parent: ba.Widget = None,\n" " size: Sequence[float] = None,\n" " position: Sequence[float] = None,\n" - " text: Union[ba.Lstr, str] = None,\n" + " text: str | ba.Lstr | None = None,\n" " value: bool = None,\n" " on_value_change_call: Callable[[bool], None] = None,\n" " on_select_call: Callable[[], None] = None,\n" @@ -2677,7 +2677,7 @@ auto PythonMethodsUI::GetMethods() -> std::vector { {"textwidget", (PyCFunction)PyTextWidget, METH_VARARGS | METH_KEYWORDS, "textwidget(edit: ba.Widget = None, parent: ba.Widget = None,\n" " size: Sequence[float] = None, position: Sequence[float] = None,\n" - " text: Union[str, ba.Lstr] = None, v_align: str = None,\n" + " text: str | ba.Lstr | None = None, v_align: str = None,\n" " h_align: str = None, editable: bool = None, padding: float = None,\n" " on_return_press_call: Callable[[], None] = None,\n" " on_activate_call: Callable[[], None] = None,\n" @@ -2687,7 +2687,7 @@ auto PythonMethodsUI::GetMethods() -> std::vector { " on_select_call: Callable[[], None] = None,\n" " always_highlight: bool = None, draw_controller: ba.Widget = None,\n" " scale: float = None, corner_scale: float = None,\n" - " description: Union[str, ba.Lstr] = None,\n" + " description: str | ba.Lstr | None = None,\n" " transition_delay: float = None, maxwidth: float = None,\n" " max_height: float = None, flatness: float = None,\n" " shadow: float = None, autoselect: bool = None, rotate: float = " diff --git a/tests/test_efro/test_dataclassio.py b/tests/test_efro/test_dataclassio.py index 64283aaa..83de627e 100644 --- a/tests/test_efro/test_dataclassio.py +++ b/tests/test_efro/test_dataclassio.py @@ -8,7 +8,7 @@ from __future__ import annotations from enum import Enum import datetime from dataclasses import field, dataclass -from typing import TYPE_CHECKING, Optional, Any, Sequence, Union, Annotated +from typing import TYPE_CHECKING, Any, Sequence, Annotated import pytest @@ -66,12 +66,12 @@ def test_assign() -> None: fval: float = 1.0 nval: _NestedClass = field(default_factory=_NestedClass) enval: _EnumTest = _EnumTest.TEST1 - oival: Optional[int] = None + oival: int | None = None oival2: int | None = None - osval: Optional[str] = None - obval: Optional[bool] = None - ofval: Optional[float] = None - oenval: Optional[_EnumTest] = _EnumTest.TEST1 + osval: str | None = None + obval: bool | None = None + ofval: float | None = None + oenval: _EnumTest | None = _EnumTest.TEST1 lsval: list[str] = field(default_factory=list) lival: list[int] = field(default_factory=list) lbval: list[bool] = field(default_factory=list) @@ -81,7 +81,7 @@ def test_assign() -> None: anyval: Any = 1 dictval: dict[int, str] = field(default_factory=dict) tupleval: tuple[int, str, bool] = (1, 'foo', False) - datetimeval: Optional[datetime.datetime] = None + datetimeval: datetime.datetime | None = None class _TestClass2: pass @@ -342,31 +342,31 @@ def test_prep() -> None: @ioprepped @dataclass class _TestClass2: - ival: Union[int, str] + ival: int | str @ioprepped @dataclass class _TestClass3: - uval: Union[int, None] + uval: int | None with pytest.raises(TypeError): @ioprepped @dataclass class _TestClass4: - ival: Union[int, str] + ival: int | str # This will get simplified down to simply int by get_type_hints so is ok. @ioprepped @dataclass class _TestClass5: - ival: Union[int] + ival: int | int # This will get simplified down to a valid 2 member union so is ok @ioprepped @dataclass class _TestClass6: - ival: Union[int, None, int, None] + ival: int | None | int | None # Disallow dict entries with types other than str, int, or enums # having those value types. @@ -417,10 +417,10 @@ def test_validate() -> None: sval: str = '' bval: bool = True fval: float = 1.0 - oival: Optional[int] = None - osval: Optional[str] = None - obval: Optional[bool] = None - ofval: Optional[float] = None + oival: int | None = None + osval: str | None = None + obval: bool | None = None + ofval: float | None = None # Should pass by default. tclass = _TestClass() @@ -665,7 +665,7 @@ def test_name_clashes() -> None: @dataclass class _RecursiveTest: val: int - child: Optional[_RecursiveTest] = None + child: _RecursiveTest | None = None def test_recursive() -> None: @@ -1022,12 +1022,12 @@ def test_soft_default() -> None: @ioprepped @dataclass class _TestClassE4: - lval: Annotated[Optional[str], IOAttrs(soft_default=None)] + lval: Annotated[str | None, IOAttrs(soft_default=None)] @ioprepped @dataclass class _TestClassE5: - lval: Annotated[Optional[str], IOAttrs(soft_default='foo')] + lval: Annotated[str | None, IOAttrs(soft_default='foo')] # Now try more in-depth examples: nested type mismatches like this # are currently not caught at prep-time but ARE caught during inputting. @@ -1042,7 +1042,7 @@ def test_soft_default() -> None: @ioprepped @dataclass class _TestClassE7: - lval: Annotated[Optional[bool], IOAttrs(soft_default=12)] + lval: Annotated[bool | None, IOAttrs(soft_default=12)] with pytest.raises(TypeError): dataclass_from_dict(_TestClassE7, {}) diff --git a/tests/test_efro/test_rpc.py b/tests/test_efro/test_rpc.py index ddf50489..073fb270 100644 --- a/tests/test_efro/test_rpc.py +++ b/tests/test_efro/test_rpc.py @@ -19,7 +19,7 @@ from efro.error import CommunicationError from efro.dataclassio import ioprepped, dataclass_from_json, dataclass_to_json if TYPE_CHECKING: - from typing import Optional, Awaitable + from typing import Awaitable ADDR = '127.0.0.1' # Randomize this a bit to avoid failing on parallel testing. @@ -53,7 +53,7 @@ class _ServerClientCommon: def __init__(self, keepalive_interval: float, keepalive_timeout: float, debug_print: bool) -> None: - self._endpoint: Optional[RPCEndpoint] = None + self._endpoint: RPCEndpoint | None = None self._keepalive_interval = keepalive_interval self._keepalive_timeout = keepalive_timeout self._debug_print = debug_print @@ -71,7 +71,7 @@ class _ServerClientCommon: async def send_message(self, message: _Message, - timeout: Optional[float] = None) -> _Message: + timeout: float | None = None) -> _Message: """Send high level messages.""" assert self._endpoint is not None response = await self._endpoint.send_message( @@ -111,7 +111,7 @@ class _Server(_ServerClientCommon): super().__init__(keepalive_interval=keepalive_interval, keepalive_timeout=keepalive_timeout, debug_print=debug_print) - self.listener: Optional[asyncio.base_events.Server] = None + self.listener: asyncio.base_events.Server | None = None async def start(self) -> None: """Start serving. Call this before run().""" diff --git a/tools/bacommon/cloud.py b/tools/bacommon/cloud.py index 2ae4e0ad..197a1de5 100644 --- a/tools/bacommon/cloud.py +++ b/tools/bacommon/cloud.py @@ -4,7 +4,7 @@ from __future__ import annotations from dataclasses import dataclass, field -from typing import TYPE_CHECKING, Annotated, Optional +from typing import TYPE_CHECKING, Annotated from enum import Enum from efro.message import Message, Response @@ -66,7 +66,7 @@ class LoginProxyStateQueryResponse(Response): state: Annotated[State, IOAttrs('s')] # On success, these will be filled out. - credentials: Annotated[Optional[str], IOAttrs('tk')] + credentials: Annotated[str | None, IOAttrs('tk')] @ioprepped diff --git a/tools/bacommon/servermanager.py b/tools/bacommon/servermanager.py index 5516dbb2..8dd5b1d0 100644 --- a/tools/bacommon/servermanager.py +++ b/tools/bacommon/servermanager.py @@ -5,7 +5,7 @@ from __future__ import annotations from enum import Enum from dataclasses import field, dataclass -from typing import TYPE_CHECKING, Optional, Any +from typing import TYPE_CHECKING, Any from efro.dataclassio import ioprepped @@ -60,11 +60,11 @@ class ServerConfig: # playlist editor in the regular version of the game. # This will give you a numeric code you can enter here to host that # playlist. - playlist_code: Optional[int] = None + playlist_code: int | None = None # Alternately, you can embed playlist data here instead of using codes. # Make sure to set session_type to the correct type for the data here. - playlist_inline: Optional[list[dict[str, Any]]] = None + playlist_inline: list[dict[str, Any]] | None = None # Whether to shuffle the playlist or play its games in designated order. playlist_shuffle: bool = True @@ -105,7 +105,7 @@ class ServerConfig: # currently-signed-in account's id. To fetch info about an account, # your back-end server can use the following url: # https://legacy.ballistica.net/accountquery?id=ACCOUNT_ID_HERE - stats_url: Optional[str] = None + stats_url: str | None = None # If present, the server subprocess will attempt to gracefully exit after # this amount of time. A graceful exit can occur at the end of a series @@ -113,32 +113,32 @@ class ServerConfig: # default) will then spin up a fresh subprocess. This mechanism can be # useful to clear out any memory leaks or other accumulated bad state # in the server subprocess. - clean_exit_minutes: Optional[float] = None + clean_exit_minutes: float | None = None # If present, the server subprocess will shut down immediately after this # amount of time. This can be useful as a fallback for clean_exit_time. # The server manager will then spin up a fresh server subprocess if # auto-restart is enabled (the default). - unclean_exit_minutes: Optional[float] = None + unclean_exit_minutes: float | None = None # If present, the server subprocess will shut down immediately if this # amount of time passes with no activity from any players. The server # manager will then spin up a fresh server subprocess if auto-restart is # enabled (the default). - idle_exit_minutes: Optional[float] = None + idle_exit_minutes: float | None = None # Should the tutorial be shown at the beginning of games? show_tutorial: bool = False # Team names (teams mode only). - team_names: Optional[tuple[str, str]] = None + team_names: tuple[str, str] | None = None # Team colors (teams mode only). - team_colors: Optional[tuple[tuple[float, float, float], - tuple[float, float, float]]] = None + team_colors: tuple[tuple[float, float, float], tuple[float, float, + float]] | None = None # (internal) stress-testing mode. - stress_test_players: Optional[int] = None + stress_test_players: int | None = None # NOTE: as much as possible, communication from the server-manager to the @@ -171,15 +171,15 @@ class ShutdownCommand(ServerCommand): class ChatMessageCommand(ServerCommand): """Chat message from the server.""" message: str - clients: Optional[list[int]] + clients: list[int] | None @dataclass class ScreenMessageCommand(ServerCommand): """Screen-message from the server.""" message: str - color: Optional[tuple[float, float, float]] - clients: Optional[list[int]] + color: tuple[float, float, float] | None + clients: list[int] | None @dataclass @@ -191,4 +191,4 @@ class ClientListCommand(ServerCommand): class KickCommand(ServerCommand): """Kick a client.""" client_id: int - ban_time: Optional[int] + ban_time: int | None diff --git a/tools/batools/assetstaging.py b/tools/batools/assetstaging.py index 489ef400..d174c39f 100755 --- a/tools/batools/assetstaging.py +++ b/tools/batools/assetstaging.py @@ -15,7 +15,7 @@ from typing import TYPE_CHECKING from efrotools import PYVER if TYPE_CHECKING: - from typing import Optional + pass # Suffix for the pyc files we include in stagings. # We're using deterministic opt pyc files; see PEP 552. @@ -32,11 +32,11 @@ class Config: self.projroot = projroot # We always calc src relative to this script. self.src = self.projroot + '/assets/build' - self.dst: Optional[str] = None - self.serverdst: Optional[str] = None - self.win_extras_src: Optional[str] = None - self.win_platform: Optional[str] = None - self.win_type: Optional[str] = None + self.dst: str | None = None + self.serverdst: str | None = None + self.win_extras_src: str | None = None + self.win_platform: str | None = None + self.win_type: str | None = None self.include_audio = True self.include_models = True self.include_collide_models = True @@ -46,11 +46,11 @@ class Config: self.include_fonts = True self.include_json = True self.include_pylib = False - self.pylib_src_name: Optional[str] = None + self.pylib_src_name: str | None = None self.include_payload_file = False - self.tex_suffix: Optional[str] = None + self.tex_suffix: str | None = None self.is_payload_full = False - self.debug: Optional[bool] = None + self.debug: bool | None = None def _parse_android_args(self, args: list[str]) -> None: # On Android we get nitpicky with what @@ -470,7 +470,7 @@ def stage_server_file(projroot: str, mode: str, infilename: str, raise RuntimeError(f"Unknown server file for staging: '{basename}'.") -def main(projroot: str, args: Optional[list[str]] = None) -> None: +def main(projroot: str, args: list[str] | None = None) -> None: """Stage assets for a build.""" if args is None: diff --git a/tools/batools/build.py b/tools/batools/build.py index 77127229..63e0ee4a 100644 --- a/tools/batools/build.py +++ b/tools/batools/build.py @@ -732,11 +732,9 @@ def _get_server_config_template_yaml(projroot: str) -> str: before_equal_sign, vval_raw = line.split('=', 1) before_equal_sign = before_equal_sign.strip() vval_raw = vval_raw.strip() - # vname, _vtype, veq, vval_raw = line.split() - vname, _vtype = before_equal_sign.split() + vname = before_equal_sign.split()[0] assert vname.endswith(':') vname = vname[:-1] - # assert veq == '=' vval: Any if vval_raw == 'field(default_factory=list)': vval = [] diff --git a/tools/batools/docs.py b/tools/batools/docs.py index fe2d5566..e5bfc547 100755 --- a/tools/batools/docs.py +++ b/tools/batools/docs.py @@ -14,15 +14,15 @@ from efro.error import CleanError from efro.terminal import Clr if TYPE_CHECKING: - from typing import Optional + pass @dataclass class AttributeInfo: """Info about an attribute of a class.""" name: str - attr_type: Optional[str] = None - docs: Optional[str] = None + attr_type: str | None = None + docs: str | None = None def parse_docs_attrs(attrs: list[AttributeInfo], docs: str) -> str: @@ -39,15 +39,15 @@ def parse_docs_attrs(attrs: list[AttributeInfo], docs: str) -> str: docs = '\n'.join(docs_lines[:attr_line]) # Go through remaining lines creating attrs and docs for each. - cur_attr: Optional[AttributeInfo] = None + cur_attr: AttributeInfo | None = None for i in range(attr_line + 1, len(docs_lines)): line = docs_lines[i].strip() # A line with a single alphanumeric word preceding a colon # is a new attr. - splits = line.split(' ') - if (len(splits) in (1, 2) - and splits[0].replace('_', '').isalnum()): + splits = line.split(' ', maxsplit=1) + if (splits[0].replace('_', '').isalnum() + and splits[-1].endswith(':')): if cur_attr is not None: attrs.append(cur_attr) cur_attr = AttributeInfo(name=splits[0]) diff --git a/tools/batools/dummymodule.py b/tools/batools/dummymodule.py index 47ae4c5f..3e284383 100755 --- a/tools/batools/dummymodule.py +++ b/tools/batools/dummymodule.py @@ -21,7 +21,7 @@ from efrotools import get_files_hash if TYPE_CHECKING: from types import ModuleType - from typing import Sequence, Any, Optional + from typing import Sequence, Any from batools.docs import AttributeInfo @@ -179,24 +179,21 @@ def _writefuncs(parent: Any, funcnames: Sequence[str], indent: int, elif returns == 'ba.Lstr': returnstr = ('import ba # pylint: disable=cyclic-import\n' "return ba.Lstr(value='')") - elif returns in ('ba.Activity', 'Optional[ba.Activity]', - 'ba.Activity | None'): + elif returns in {'ba.Activity', 'ba.Activity | None'}: returnstr = ( 'import ba # pylint: disable=cyclic-import\nreturn ' + 'ba.Activity(settings={})') - elif returns in ('ba.Session', 'Optional[ba.Session]', - 'ba.Session | None'): + elif returns in {'ba.Session', 'ba.Session | None'}: returnstr = ( 'import ba # pylint: disable=cyclic-import\nreturn ' + 'ba.Session([])') - elif returns in ('Optional[ba.SessionPlayer]', - 'ba.SessionPlayer | None'): + elif returns == 'ba.SessionPlayer | None': returnstr = ('import ba # pylint: disable=cyclic-import\n' 'return ba.SessionPlayer()') - elif returns in ('Optional[ba.Player]', 'ba.Player | None'): + elif returns == 'ba.Player | None': returnstr = ('import ba # pylint: disable=cyclic-import\n' 'return ba.Player()') - elif returns.startswith('ba.'): + elif returns.startswith('ba.') and ' | None' not in returns: # We cant import ba at module level so let's # do it within funcs as needed. @@ -208,21 +205,20 @@ def _writefuncs(parent: Any, funcnames: Sequence[str], indent: int, # (could use the equivalent _ba class perhaps) # sig = sig.split('->')[0] - elif returns in ['object', 'Any']: + elif returns in {'object', 'Any'}: # We use 'object' when we mean "can vary" # don't want pylint making assumptions in this case. returnstr = 'return _uninferrable()' elif returns == 'tuple[float, float]': returnstr = 'return (0.0, 0.0)' - elif returns in ('Optional[str]', 'str | None'): + elif returns == 'str | None': returnstr = "return ''" elif returns == 'tuple[float, float, float, float]': returnstr = 'return (0.0, 0.0, 0.0, 0.0)' - elif returns in ('Optional[ba.Widget]', 'ba.Widget | None'): + elif returns == 'ba.Widget | None': returnstr = 'return Widget()' - elif returns in ('Optional[ba.InputDevice]', - 'ba.InputDevice | None'): + elif returns == 'ba.InputDevice | None': returnstr = 'return InputDevice()' elif returns == 'list[ba.Widget]': returnstr = 'return [Widget()]' @@ -230,19 +226,18 @@ def _writefuncs(parent: Any, funcnames: Sequence[str], indent: int, returnstr = 'return (0.0, 0.0, 0.0)' elif returns == 'list[str]': returnstr = "return ['blah', 'blah2']" - elif returns == 'Union[float, int]': + elif returns == 'float | int': returnstr = 'return 0.0' elif returns == 'dict[str, Any]': returnstr = "return {'foo': 'bar'}" - elif returns in ('Optional[tuple[int, int]]', - 'tuple[int, int] | None', 'tuple[int, int]'): + elif returns in {'tuple[int, int] | None', 'tuple[int, int]'}: returnstr = 'return (0, 0)' elif returns == 'list[dict[str, Any]]': returnstr = "return [{'foo': 'bar'}]" - elif returns in [ + elif returns in { 'session.Session', 'team.Team', '_app.App', 'appconfig.AppConfig' - ]: + }: returnstr = ('from ba import ' + returns.split('.')[0] + '; return ' + returns + '()') elif returns in [ @@ -358,9 +353,9 @@ def _special_class_cases(classname: str) -> str: ' name_color: Sequence[float] = (0.0, 0.0, 0.0)\n' ' tint_color: Sequence[float] = (0.0, 0.0, 0.0)\n' ' tint2_color: Sequence[float] = (0.0, 0.0, 0.0)\n' - " text: Union[ba.Lstr, str] = ''\n" - ' texture: Optional[ba.Texture] = None\n' - ' tint_texture: Optional[ba.Texture] = None\n' + " text: ba.Lstr | str = ''\n" + ' texture: ba.Texture | None = None\n' + ' tint_texture: ba.Texture | None = None\n' ' times: Sequence[int] = (1,2,3,4,5)\n' ' values: Sequence[float] = (1.0, 2.0, 3.0, 4.0)\n' ' offset: float = 0.0\n' @@ -369,7 +364,7 @@ def _special_class_cases(classname: str) -> str: ' input2: float = 0.0\n' ' input3: float = 0.0\n' ' flashing: bool = False\n' - ' scale: Union[float, Sequence[float]] = 0.0\n' # FIXME + ' scale: float | Sequence[float] = 0.0\n' # FIXME ' opacity: float = 0.0\n' ' loop: bool = False\n' ' time1: int = 0\n' @@ -383,13 +378,13 @@ def _special_class_cases(classname: str) -> str: ' pickup_materials: Sequence[ba.Material] = ()\n' ' extras_material: Sequence[ba.Material] = ()\n' ' rotate: float = 0.0\n' - ' hold_node: Optional[ba.Node] = None\n' + ' hold_node: ba.Node | None = None\n' ' hold_body: int = 0\n' ' host_only: bool = False\n' ' premultiplied: bool = False\n' - ' source_player: Optional[ba.Player] = None\n' - ' model_opaque: Optional[ba.Model] = None\n' - ' model_transparent: Optional[ba.Model] = None\n' + ' source_player: ba.Player | None = None\n' + ' model_opaque: ba.Model | None = None\n' + ' model_transparent: ba.Model | None = None\n' ' damage_smoothed: float = 0.0\n' ' gravity_scale: float = 1.0\n' ' punch_power: float = 0.0\n' @@ -420,13 +415,13 @@ def _special_class_cases(classname: str) -> str: ' music_count: int = 0\n' ' hurt: float = 0.0\n' ' always_show_health_bar: bool = False\n' - ' mini_billboard_1_texture: Optional[ba.Texture] = None\n' + ' mini_billboard_1_texture: ba.Texture | None = None\n' ' mini_billboard_1_start_time: int = 0\n' ' mini_billboard_1_end_time: int = 0\n' - ' mini_billboard_2_texture: Optional[ba.Texture] = None\n' + ' mini_billboard_2_texture: ba.Texture | None = None\n' ' mini_billboard_2_start_time: int = 0\n' ' mini_billboard_2_end_time: int = 0\n' - ' mini_billboard_3_texture: Optional[ba.Texture] = None\n' + ' mini_billboard_3_texture: ba.Texture | None = None\n' ' mini_billboard_3_start_time: int = 0\n' ' mini_billboard_3_end_time: int = 0\n' ' boxing_gloves_flashing: bool = False\n' @@ -447,9 +442,9 @@ def _special_class_cases(classname: str) -> str: ' = (-1, -1, -1, 1, 1, 1)\n' ' shadow_range: Sequence[float] = (0, 0, 0, 0)\n' " counter_text: str = ''\n" - ' counter_texture: Optional[ba.Texture] = None\n' + ' counter_texture: ba.Texture | None = None\n' ' shattered: int = 0\n' - ' billboard_texture: Optional[ba.Texture] = None\n' + ' billboard_texture: ba.Texture | None = None\n' ' billboard_cross_out: bool = False\n' ' billboard_opacity: float = 0.0\n' ' slow_motion: bool = False\n' @@ -476,7 +471,7 @@ def _special_class_cases(classname: str) -> str: return out -def _filterdoc(docstr: str, funcname: Optional[str] = None) -> str: +def _filterdoc(docstr: str, funcname: str | None = None) -> str: docslines = docstr.splitlines() if (funcname and docslines and docslines[0] @@ -489,8 +484,8 @@ def _filterdoc(docstr: str, funcname: Optional[str] = None) -> str: # Assuming that each line between 'Attributes:' and '\n\n' belongs to # attrs descriptions. empty_lines_count = 0 - attributes_line: Optional[int] = None - attrs_definitions_last_line: Optional[int] = None + attributes_line: int | None = None + attrs_definitions_last_line: int | None = None for i, line in enumerate(docslines): if line.strip() in ['Attrs:', 'Attributes:']: if attributes_line is not None: @@ -681,7 +676,7 @@ def generate(sources_hash: str, outfilename: str) -> None: 'from ba._generated.enums import TimeFormat, TimeType\n' '\n' 'if TYPE_CHECKING:\n' - ' from typing import Any, Callable, Optional, Union, Literal\n' + ' from typing import Any, Callable, Literal\n' ' from ba._app import App\n' ' import ba\n' '\n' diff --git a/tools/batools/pcommand.py b/tools/batools/pcommand.py index a9e00912..e369497b 100644 --- a/tools/batools/pcommand.py +++ b/tools/batools/pcommand.py @@ -11,7 +11,7 @@ from typing import TYPE_CHECKING from efrotools.pcommand import PROJROOT if TYPE_CHECKING: - from typing import Optional + pass def stage_server_file() -> None: @@ -36,7 +36,7 @@ def py_examine() -> None: filename = Path(sys.argv[2]) line = int(sys.argv[3]) column = int(sys.argv[4]) - selection: Optional[str] = (None if sys.argv[5] == '' else sys.argv[5]) + selection: str | None = (None if sys.argv[5] == '' else sys.argv[5]) operation = sys.argv[6] # This stuff assumes it is being run from project root. @@ -569,7 +569,7 @@ def wsl_path_to_win() -> None: escape = False if len(sys.argv) < 3: raise CleanError('Expected at least 1 path arg.') - wsl_path: Optional[str] = None + wsl_path: str | None = None for arg in sys.argv[2:]: if arg == '--create': create = True diff --git a/tools/efro/dataclassio/_api.py b/tools/efro/dataclassio/_api.py index 9c0597b7..13eb5f9e 100644 --- a/tools/efro/dataclassio/_api.py +++ b/tools/efro/dataclassio/_api.py @@ -18,7 +18,7 @@ from efro.dataclassio._inputter import _Inputter from efro.dataclassio._base import Codec if TYPE_CHECKING: - from typing import Any, Optional + from typing import Any T = TypeVar('T') @@ -69,7 +69,7 @@ def dataclass_to_dict(obj: Any, def dataclass_to_json(obj: Any, coerce_to_float: bool = True, pretty: bool = False, - sort_keys: Optional[bool] = None) -> str: + sort_keys: bool | None = None) -> str: """Utility function; return a json string from a dataclass instance. Basically json.dumps(dataclass_to_dict(...)). diff --git a/tools/efro/dataclassio/_base.py b/tools/efro/dataclassio/_base.py index 0d0a8a93..ee7834da 100644 --- a/tools/efro/dataclassio/_base.py +++ b/tools/efro/dataclassio/_base.py @@ -13,7 +13,7 @@ from typing import TYPE_CHECKING, get_args from typing import _AnnotatedAlias # type: ignore if TYPE_CHECKING: - from typing import Any, Optional, Callable, Union + from typing import Any, Callable # Types which we can pass through as-is. SIMPLE_TYPES = {int, bool, str, float, type(None)} @@ -31,8 +31,7 @@ def _raise_type_error(fieldpath: str, valuetype: type, if len(expected) == 1: expected_str = expected[0].__name__ else: - names = ', '.join(t.__name__ for t in expected) - expected_str = f'Union[{names}]' + expected_str = ' | '.join(t.__name__ for t in expected) raise TypeError(f'Invalid value type for "{fieldpath}";' f' expected "{expected_str}", got' f' "{valuetype.__name__}".') @@ -128,21 +127,21 @@ class IOAttrs: MISSING = _MissingType() - storagename: Optional[str] = None + storagename: str | None = None store_default: bool = True whole_days: bool = False whole_hours: bool = False soft_default: Any = MISSING - soft_default_factory: Union[Callable[[], Any], _MissingType] = MISSING + soft_default_factory: Callable[[], Any] | _MissingType = MISSING def __init__( self, - storagename: Optional[str] = storagename, + storagename: str | None = storagename, store_default: bool = store_default, whole_days: bool = whole_days, whole_hours: bool = whole_hours, soft_default: Any = MISSING, - soft_default_factory: Union[Callable[[], Any], _MissingType] = MISSING, + soft_default_factory: Callable[[], Any] | _MissingType = MISSING, ): # Only store values that differ from class defaults to keep @@ -216,12 +215,12 @@ def _get_origin(anntype: Any) -> Any: return anntype if origin is None else origin -def _parse_annotated(anntype: Any) -> tuple[Any, Optional[IOAttrs]]: +def _parse_annotated(anntype: Any) -> tuple[Any, IOAttrs | None]: """Parse Annotated() constructs, returning annotated type & IOAttrs.""" # If we get an Annotated[foo, bar, eep] we take # foo as the actual type, and we look for IOAttrs instances in # bar/eep to affect our behavior. - ioattrs: Optional[IOAttrs] = None + ioattrs: IOAttrs | None = None if isinstance(anntype, _AnnotatedAlias): annargs = get_args(anntype) for annarg in annargs[1:]: diff --git a/tools/efro/dataclassio/_inputter.py b/tools/efro/dataclassio/_inputter.py index 34c1e5fe..85f45160 100644 --- a/tools/efro/dataclassio/_inputter.py +++ b/tools/efro/dataclassio/_inputter.py @@ -23,7 +23,7 @@ from efro.dataclassio._base import (Codec, _parse_annotated, EXTRA_ATTRS_ATTR, from efro.dataclassio._prep import PrepSession if TYPE_CHECKING: - from typing import Any, Optional + from typing import Any from efro.dataclassio._base import IOAttrs from efro.dataclassio._outputter import _Outputter @@ -44,7 +44,7 @@ class _Inputter(Generic[T]): self._coerce_to_float = coerce_to_float self._allow_unknown_attrs = allow_unknown_attrs self._discard_unknown_attrs = discard_unknown_attrs - self._soft_default_validator: Optional[_Outputter] = None + self._soft_default_validator: _Outputter | None = None if not allow_unknown_attrs and discard_unknown_attrs: raise ValueError('discard_unknown_attrs cannot be True' @@ -63,7 +63,7 @@ class _Inputter(Generic[T]): return out def _value_from_input(self, cls: type, fieldpath: str, anntype: Any, - value: Any, ioattrs: Optional[IOAttrs]) -> Any: + value: Any, ioattrs: IOAttrs | None) -> Any: """Convert an assigned value to what a dataclass field expects.""" # pylint: disable=too-many-return-statements # pylint: disable=too-many-branches @@ -270,7 +270,7 @@ class _Inputter(Generic[T]): fieldpath=fieldpath) def _dict_from_input(self, cls: type, fieldpath: str, anntype: Any, - value: Any, ioattrs: Optional[IOAttrs]) -> Any: + value: Any, ioattrs: IOAttrs | None) -> Any: # pylint: disable=too-many-branches # pylint: disable=too-many-locals @@ -370,7 +370,7 @@ class _Inputter(Generic[T]): def _sequence_from_input(self, cls: type, fieldpath: str, anntype: Any, value: Any, seqtype: type, - ioattrs: Optional[IOAttrs]) -> Any: + ioattrs: IOAttrs | None) -> Any: # Because we are json-centric, we expect a list for all sequences. if type(value) is not list: @@ -396,7 +396,7 @@ class _Inputter(Generic[T]): for i in value) def _datetime_from_input(self, cls: type, fieldpath: str, value: Any, - ioattrs: Optional[IOAttrs]) -> Any: + ioattrs: IOAttrs | None) -> Any: # For firestore we expect a datetime object. if self._codec is Codec.FIRESTORE: @@ -428,7 +428,7 @@ class _Inputter(Generic[T]): return out def _tuple_from_input(self, cls: type, fieldpath: str, anntype: Any, - value: Any, ioattrs: Optional[IOAttrs]) -> Any: + value: Any, ioattrs: IOAttrs | None) -> Any: out: list = [] diff --git a/tools/efro/dataclassio/_outputter.py b/tools/efro/dataclassio/_outputter.py index 159648c6..03965e1c 100644 --- a/tools/efro/dataclassio/_outputter.py +++ b/tools/efro/dataclassio/_outputter.py @@ -23,7 +23,7 @@ from efro.dataclassio._base import (Codec, _parse_annotated, EXTRA_ATTRS_ATTR, from efro.dataclassio._prep import PrepSession if TYPE_CHECKING: - from typing import Any, Optional + from typing import Any from efro.dataclassio._base import IOAttrs @@ -64,7 +64,7 @@ class _Outputter: recursion_level=0) assert prep is not None fields = dataclasses.fields(obj) - out: Optional[dict[str, Any]] = {} if self._create else None + out: dict[str, Any] | None = {} if self._create else None for field in fields: fieldname = field.name if fieldpath: @@ -127,7 +127,7 @@ class _Outputter: return out def _process_value(self, cls: type, fieldpath: str, anntype: Any, - value: Any, ioattrs: Optional[IOAttrs]) -> Any: + value: Any, ioattrs: IOAttrs | None) -> Any: # pylint: disable=too-many-return-statements # pylint: disable=too-many-branches # pylint: disable=too-many-statements @@ -308,7 +308,7 @@ class _Outputter: return value def _process_dict(self, cls: type, fieldpath: str, anntype: Any, - value: dict, ioattrs: Optional[IOAttrs]) -> Any: + value: dict, ioattrs: IOAttrs | None) -> Any: # pylint: disable=too-many-branches if not isinstance(value, dict): raise TypeError(f'Expected a dict for {fieldpath};' @@ -330,7 +330,7 @@ class _Outputter: # Ok; we've got a definite key type (which we verified as valid # during prep). Make sure all keys match it. - out: Optional[dict] = {} if self._create else None + out: dict | None = {} if self._create else None keyanntype, valanntype = childtypes # str keys we just export directly since that's supported by json. diff --git a/tools/efro/dataclassio/_prep.py b/tools/efro/dataclassio/_prep.py index c6fd503f..704fb72a 100644 --- a/tools/efro/dataclassio/_prep.py +++ b/tools/efro/dataclassio/_prep.py @@ -21,7 +21,7 @@ from efro.dataclassio._base import (_parse_annotated, _get_origin, SIMPLE_TYPES) if TYPE_CHECKING: - from typing import Any, Optional + from typing import Any from efro.dataclassio._base import IOAttrs T = TypeVar('T') @@ -115,12 +115,12 @@ class PrepData: class PrepSession: """Context for a prep.""" - def __init__(self, explicit: bool, globalns: Optional[dict] = None): + def __init__(self, explicit: bool, globalns: dict | None = None): self.explicit = explicit self.globalns = globalns def prep_dataclass(self, cls: type, - recursion_level: int) -> Optional[PrepData]: + recursion_level: int) -> PrepData | None: """Run prep on a dataclass if necessary and return its prep data. The only case where this will return None is for recursive types @@ -232,7 +232,7 @@ class PrepSession: return prepdata def prep_type(self, cls: type, attrname: str, anntype: Any, - ioattrs: Optional[IOAttrs], recursion_level: int) -> None: + ioattrs: IOAttrs | None, recursion_level: int) -> None: """Run prep on a dataclass.""" # pylint: disable=too-many-return-statements # pylint: disable=too-many-branches diff --git a/tools/efro/message/_module.py b/tools/efro/message/_module.py index 4e278bb4..16c09828 100644 --- a/tools/efro/message/_module.py +++ b/tools/efro/message/_module.py @@ -11,7 +11,7 @@ from typing import TYPE_CHECKING from efro.message._protocol import MessageProtocol if TYPE_CHECKING: - from typing import Optional + pass def create_sender_module( @@ -20,8 +20,8 @@ def create_sender_module( enable_sync_sends: bool, enable_async_sends: bool, private: bool = False, - protocol_module_level_import_code: Optional[str] = None, - build_time_protocol_create_code: Optional[str] = None, + protocol_module_level_import_code: str | None = None, + build_time_protocol_create_code: str | None = None, ) -> str: """Create a Python module defining a MessageSender subclass. @@ -59,8 +59,8 @@ def create_receiver_module( protocol_create_code: str, is_async: bool, private: bool = False, - protocol_module_level_import_code: Optional[str] = None, - build_time_protocol_create_code: Optional[str] = None, + protocol_module_level_import_code: str | None = None, + build_time_protocol_create_code: str | None = None, ) -> str: """"Create a Python module defining a MessageReceiver subclass. diff --git a/tools/efro/rpc.py b/tools/efro/rpc.py index 1e72012d..6afc3103 100644 --- a/tools/efro/rpc.py +++ b/tools/efro/rpc.py @@ -19,7 +19,7 @@ from efro.dataclassio import (dataclass_to_json, dataclass_from_json, ioprepped, IOAttrs) if TYPE_CHECKING: - from typing import Literal, Awaitable, Callable, Optional + from typing import Literal, Awaitable, Callable # Terminology: # Packet: A chunk of data consisting of a type and some type-dependent @@ -64,7 +64,7 @@ class _InFlightMessage: """Represents a message that is out on the wire.""" def __init__(self) -> None: - self._response: Optional[bytes] = None + self._response: bytes | None = None self._got_response = asyncio.Event() self.wait_task = asyncio.create_task(self._wait()) @@ -134,7 +134,7 @@ class RPCEndpoint: self._out_packets: list[bytes] = [] self._have_out_packets = asyncio.Event() self._run_called = False - self._peer_info: Optional[_PeerInfo] = None + self._peer_info: _PeerInfo | None = None self._keepalive_interval = keepalive_interval self._keepalive_timeout = keepalive_timeout @@ -143,7 +143,7 @@ class RPCEndpoint: self._tasks: list[weakref.ref[asyncio.Task]] = [] # When we last got a keepalive or equivalent (time.monotonic value) - self._last_keepalive_receive_time: Optional[float] = None + self._last_keepalive_receive_time: float | None = None # (Start near the end to make sure our looping logic is sound). self._next_message_id = 65530 @@ -201,7 +201,7 @@ class RPCEndpoint: async def send_message(self, message: bytes, - timeout: Optional[float] = None) -> bytes: + timeout: float | None = None) -> bytes: """Send a message to the peer and return a response. If timeout is not provided, the default will be used. diff --git a/tools/efrotools/android.py b/tools/efrotools/android.py index bd3ccc7c..9ab91786 100644 --- a/tools/efrotools/android.py +++ b/tools/efrotools/android.py @@ -7,7 +7,7 @@ from typing import TYPE_CHECKING from dataclasses import dataclass if TYPE_CHECKING: - from typing import Optional + pass @dataclass @@ -27,7 +27,7 @@ def filter_gradle_file(buildfilename: str, enabled_tags: set[str]) -> None: original = infile.read() lines = original.splitlines() - current_section: Optional[GradleFilterSection] = None + current_section: GradleFilterSection | None = None for i, line in enumerate(lines): if line.strip().startswith('// EFRO_IF'): if current_section is not None: diff --git a/tools/efrotools/build.py b/tools/efrotools/build.py index f6278e29..ab9d53a0 100644 --- a/tools/efrotools/build.py +++ b/tools/efrotools/build.py @@ -12,7 +12,7 @@ from typing import TYPE_CHECKING from efro.terminal import Clr if TYPE_CHECKING: - from typing import Optional, Callable + from typing import Callable class Lazybuild: @@ -37,10 +37,10 @@ class Lazybuild: target: str, srcpaths: list[str], command: str, - dirfilter: Optional[Callable[[str, str], bool]] = None, - filefilter: Optional[Callable[[str, str], bool]] = None, - srcpaths_fullclean: Optional[list[str]] = None, - command_fullclean: Optional[str] = None) -> None: + dirfilter: Callable[[str, str], bool] | None = None, + filefilter: Callable[[str, str], bool] | None = None, + srcpaths_fullclean: list[str] | None = None, + command_fullclean: str | None = None) -> None: self.target = target self.srcpaths = srcpaths self.command = command diff --git a/tools/efrotools/filecache.py b/tools/efrotools/filecache.py index 7854d108..1a4fdb69 100644 --- a/tools/efrotools/filecache.py +++ b/tools/efrotools/filecache.py @@ -17,7 +17,7 @@ from efrotools import get_files_hash # pylint: enable=useless-suppression if TYPE_CHECKING: - from typing import Optional, Sequence, Any + from typing import Sequence, Any from pathlib import Path @@ -26,7 +26,7 @@ class FileCache: def __init__(self, path: Path): self._path = path - self.curhashes: dict[str, Optional[str]] = {} + self.curhashes: dict[str, str | None] = {} self.mtimes: dict[str, float] = {} self.entries: dict[str, Any] if not os.path.exists(path): diff --git a/tools/efrotools/filecommand.py b/tools/efrotools/filecommand.py index 098e8586..bbde1f8f 100644 --- a/tools/efrotools/filecommand.py +++ b/tools/efrotools/filecommand.py @@ -10,7 +10,7 @@ from threading import Condition, Thread import os if TYPE_CHECKING: - from typing import Iterable, Optional, Callable + from typing import Iterable, Callable class _FileBatchesRun: @@ -18,7 +18,7 @@ class _FileBatchesRun: def __init__(self, paths: list[str], batch_size: int, - file_filter: Optional[Callable[[str], bool]], + file_filter: Callable[[str], bool] | None, include_mac_packages: bool = False) -> None: self.condition = Condition() self.paths = paths @@ -106,7 +106,7 @@ class _FileBatchesRun: def file_batches( paths: list[str], batch_size: int = 1, - file_filter: Optional[Callable[[str], bool]] = None, + file_filter: Callable[[str], bool] | None = None, include_mac_packages: bool = False, ) -> Iterable[list[str]]: """Efficiently yield batches of files to operate on. diff --git a/tools/efrotools/makefile.py b/tools/efrotools/makefile.py index a840c0fd..96415561 100644 --- a/tools/efrotools/makefile.py +++ b/tools/efrotools/makefile.py @@ -9,13 +9,13 @@ from dataclasses import dataclass from typing import TYPE_CHECKING if TYPE_CHECKING: - from typing import Optional + pass @dataclass class Section: """Represents a section of a Makefile.""" - name: Optional[str] + name: str | None paragraphs: list[Paragraph] diff --git a/tools/efrotools/message.py b/tools/efrotools/message.py index d66cc9bb..12fd20fb 100644 --- a/tools/efrotools/message.py +++ b/tools/efrotools/message.py @@ -11,7 +11,7 @@ from typing import TYPE_CHECKING from efrotools.code import format_yapf_str if TYPE_CHECKING: - from typing import Optional + pass def standard_message_sender_gen_pcommand( @@ -40,8 +40,8 @@ def standard_message_sender_gen_pcommand( # In embedded situations we have to pass different code to import # the protocol at build time than we do in our runtime code (where # there is only a dummy import for type-checking purposes) - protocol_module_level_import_code: Optional[str] - build_time_protocol_create_code: Optional[str] + protocol_module_level_import_code: str | None + build_time_protocol_create_code: str | None if embedded: protocol_module_level_import_code = ( f'\n# Dummy import for type-checking purposes.\n' @@ -101,8 +101,8 @@ def standard_message_receiver_gen_pcommand( # In embedded situations we have to pass different code to import # the protocol at build time than we do in our runtime code (where # there is only a dummy import for type-checking purposes) - protocol_module_level_import_code: Optional[str] - build_time_protocol_create_code: Optional[str] + protocol_module_level_import_code: str | None + build_time_protocol_create_code: str | None if embedded: protocol_module_level_import_code = ( f'\n# Dummy import for type-checking purposes.\n' diff --git a/tools/efrotools/sync.py b/tools/efrotools/sync.py index db37d9a1..55d277db 100644 --- a/tools/efrotools/sync.py +++ b/tools/efrotools/sync.py @@ -15,7 +15,7 @@ from typing import TYPE_CHECKING from efro.terminal import Clr if TYPE_CHECKING: - from typing import Optional, Sequence + from typing import Sequence class Mode(Enum): @@ -49,7 +49,7 @@ class SyncItem: """Defines a file or directory to be synced from another project.""" src_project_id: str src_path: str - dst_path: Optional[str] = None + dst_path: str | None = None def run_standard_syncs(projectroot: Path, mode: Mode, @@ -293,8 +293,8 @@ def get_dst_file_info(dstfile: Path) -> tuple[str, str, str]: if not dstlines: raise ValueError(f'no lines found in {dstfile}') found = False - offs: Optional[int] = None - marker_hash: Optional[str] = None + offs: int | None = None + marker_hash: str | None = None for offs in range(2): checkline = 1 + offs if 'EFRO_SYNC_HASH' in dstlines[checkline]: diff --git a/tools/efrotools/xcode.py b/tools/efrotools/xcode.py index 142befa5..9548d4c2 100644 --- a/tools/efrotools/xcode.py +++ b/tools/efrotools/xcode.py @@ -18,7 +18,7 @@ from efro.error import CleanError from efro.util import assert_never if TYPE_CHECKING: - from typing import Any, Optional + from typing import Any class _Section(Enum): @@ -56,9 +56,9 @@ class XCodeBuild: self._args = args self._output: list[str] = [] self._verbose = os.environ.get('XCODEBUILDVERBOSE', '0') == '1' - self._section: Optional[_Section] = None + self._section: _Section | None = None self._section_line_count = 0 - self._returncode: Optional[int] = None + self._returncode: int | None = None self._project: str = self._argstr(args, '-project') self._scheme: str = self._argstr(args, '-scheme') self._configuration: str = self._argstr(args, '-configuration') @@ -441,7 +441,7 @@ class XCodeBuild: self, line: str, prefix: str = None, - prefix_index: Optional[int] = 1, + prefix_index: int | None = 1, ignore_line_starts: list[str] = None, ignore_line_start_tails: list[str] = None) -> None: @@ -494,8 +494,8 @@ def project_build_path(projroot: str, project_path: str, scheme: str, config_path = os.path.join(projroot, '.cache', 'xcode_build_path') config: dict[str, dict[str, Any]] = {} - build_dir: Optional[str] = None - executable_path: Optional[str] = None + build_dir: str | None = None + executable_path: str | None = None if os.path.exists(config_path): with open(config_path, encoding='utf-8') as infile: