finished purging Optional and Union

This commit is contained in:
Eric Froemling 2022-06-24 10:57:56 -07:00
parent d2b18d99ca
commit 164ff528c3
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
119 changed files with 791 additions and 812 deletions

View File

@ -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"
}

View File

@ -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!)

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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.

View File

@ -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

View File

@ -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."""

View File

@ -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.')

View File

@ -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

View File

@ -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:

View File

@ -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.

View File

@ -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,

View File

@ -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,

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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()

View File

@ -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.

View File

@ -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

View File

@ -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'),

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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',

View File

@ -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 [

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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)))

View File

@ -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,

View File

@ -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

View File

@ -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,

View File

@ -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:

View File

@ -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}',

View File

@ -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(

View File

@ -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()

View File

@ -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':

View File

@ -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)

View File

@ -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

View File

@ -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':

View File

@ -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':

View File

@ -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:

View File

@ -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:

View File

@ -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)

View File

@ -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:

View File

@ -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:

View File

@ -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()

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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'))

View File

@ -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(

View File

@ -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:

View File

@ -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:

View File

@ -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.

View File

@ -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,

View File

@ -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()

View File

@ -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:

View File

@ -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,

View File

@ -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

View File

@ -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':

View File

@ -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':

View File

@ -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),

View File

@ -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,

View File

@ -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')

View File

@ -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,

View File

@ -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))

View File

@ -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.')

View File

@ -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()

View File

@ -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

View File

@ -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()

View File

@ -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':

View File

@ -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:

View File

@ -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

View File

@ -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:

View File

@ -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)))

View File

@ -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)

View File

@ -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)

View File

@ -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:

View File

@ -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)))

View File

@ -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.

View File

@ -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"

View File

@ -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"

View File

@ -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,

View File

@ -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)

View File

@ -911,8 +911,7 @@ auto PythonMethodsApp::GetMethods() -> std::vector<PyMethodDef> {
"(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<PyMethodDef> {
{"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<PyMethodDef> {
{"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"

View File

@ -658,7 +658,7 @@ auto PythonMethodsGameplay::GetMethods() -> std::vector<PyMethodDef> {
{"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<PyMethodDef> {
{"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"

View File

@ -304,7 +304,7 @@ auto PyGetDisplayResolution(PyObject* self, PyObject* args) -> PyObject* {
auto PythonMethodsGraphics::GetMethods() -> std::vector<PyMethodDef> {
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"

View File

@ -232,7 +232,7 @@ auto PythonMethodsInput::GetMethods() -> std::vector<PyMethodDef> {
{"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"

View File

@ -2365,7 +2365,7 @@ auto PythonMethodsUI::GetMethods() -> std::vector<PyMethodDef> {
"(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<PyMethodDef> {
{"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<PyMethodDef> {
{"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<PyMethodDef> {
" 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<PyMethodDef> {
" 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<PyMethodDef> {
{"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<PyMethodDef> {
" 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 = "

View File

@ -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, {})

View File

@ -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()."""

View File

@ -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

View File

@ -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

View File

@ -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:

Some files were not shown because too many files have changed in this diff Show More