diff --git a/.efrocachemap b/.efrocachemap index 1f083ef7..c1d409b4 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -4114,10 +4114,10 @@ "assets/build/windows/x64/python.exe": "https://files.ballistica.net/cache/ba1/25/a7/dc87c1be41605eb6fefd0145144c", "assets/build/windows/x64/python37.dll": "https://files.ballistica.net/cache/ba1/b9/e4/d912f56e42e9991bcbb4c804cfcb", "assets/build/windows/x64/pythonw.exe": "https://files.ballistica.net/cache/ba1/6c/bb/b6f52c306aa4e88061510e96cefe", - "build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/6b/88/a8f82a340a0fba36edfe95298871", - "build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d3/72/4ad974215d1cfd0db7f14af5f6c3", - "build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/82/c3/388d9a77f8bde608d7cdf2891ad3", - "build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/6c/6f/d2ffeecb1e9a18678b1ec1695198", - "build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/77/68/e7ac990ee0ec25dd6a459e637d9f", - "build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/e8/ce/1091fea9004ca76f6b8ccde8b839" + "build/prefab/linux/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/85/4e/8e17f105c42bd7c399f4f60c43b3", + "build/prefab/linux/release/ballisticacore": "https://files.ballistica.net/cache/ba1/eb/b5/3a5b133d3a1d5a3de35fd3cfbbbc", + "build/prefab/mac/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/de/ce/80e52a4d428d8500a2095d6ce470", + "build/prefab/mac/release/ballisticacore": "https://files.ballistica.net/cache/ba1/28/15/aecd6c5dd487f607e47da088bee2", + "build/prefab/windows/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/c6/78/f6383a7b421ecaac09d5cfd02107", + "build/prefab/windows/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/cf/7e/aa37853a635b2b89ea32f98db407" } \ No newline at end of file diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml index 8c54e556..4e4b6cf0 100644 --- a/.idea/dictionaries/ericf.xml +++ b/.idea/dictionaries/ericf.xml @@ -1483,6 +1483,7 @@ sclx scly scorescreen + scoreteam scoretxt scoreval scorever diff --git a/assets/src/ba_data/python/_ba.py b/assets/src/ba_data/python/_ba.py index 16b4c4d9..ada4d241 100644 --- a/assets/src/ba_data/python/_ba.py +++ b/assets/src/ba_data/python/_ba.py @@ -34,7 +34,7 @@ NOTE: This file was autogenerated by gendummymodule; do not edit by hand. """ # (hash we can use to see if this file is out of date) -# SOURCES_HASH=126196922259492504803685031830587478733 +# SOURCES_HASH=106879997712807296258529817433289194930 # I'm sorry Pylint. I know this file saddens you. Be strong. # pylint: disable=useless-suppression @@ -2191,12 +2191,12 @@ def get_price(item: str) -> Optional[str]: return "" -def get_public_login_id() -> str: - """get_public_login_id() -> str +def get_public_login_id() -> Optional[str]: + """get_public_login_id() -> Optional[str] (internal) """ - return str() + return "" def get_public_party_enabled() -> bool: diff --git a/assets/src/ba_data/python/ba/_achievement.py b/assets/src/ba_data/python/ba/_achievement.py index 3f6cd30a..34b74212 100644 --- a/assets/src/ba_data/python/ba/_achievement.py +++ b/assets/src/ba_data/python/ba/_achievement.py @@ -83,7 +83,7 @@ def award_local_achievement(achname: str) -> None: """For non-game-based achievements such as controller-connection ones.""" try: ach = get_achievement(achname) - if ach is not None and not ach.complete: + if not ach.complete: # Report new achievements to the game-service. _ba.report_achievement(achname) @@ -680,7 +680,7 @@ class Achievement: # Just piggy-back onto any current activity # (should we use the session instead?..) - activity = _ba.getactivity(doraise=False) + activity: Optional[ba.Activity] = _ba.getactivity(doraise=False) # If this gets called while this achievement is occupying a slot # already, ignore it. (probably should never happen in real diff --git a/assets/src/ba_data/python/ba/_app.py b/assets/src/ba_data/python/ba/_app.py index 29c6fedb..bb625c88 100644 --- a/assets/src/ba_data/python/ba/_app.py +++ b/assets/src/ba_data/python/ba/_app.py @@ -398,13 +398,13 @@ class App: # Gameplay. self.teams_series_length = 7 self.ffa_series_length = 24 - self.coop_session_args: dict = {} + self.coop_session_args: Dict = {} # UI. self.uicontroller: Optional[ba.UIController] = None self.main_menu_window: Optional[_ba.Widget] = None # FIXME: Kill this. - self.window_states: dict = {} # FIXME: Kill this. - self.windows: dict = {} # FIXME: Kill this. + self.window_states: Dict = {} # FIXME: Kill this. + self.windows: Dict = {} # FIXME: Kill this. self.main_window: Optional[str] = None # FIXME: Kill this. self.main_menu_selection: Optional[str] = None # FIXME: Kill this. self.have_party_queue_window = False @@ -416,9 +416,9 @@ class App: self.first_main_menu = True # FIXME: Move to mainmenu class. self.did_menu_intro = False # FIXME: Move to mainmenu class. self.main_menu_resume_callbacks: list = [] # can probably go away - self.special_offer = None - self.league_rank_cache: dict = {} - self.tournament_info: dict = {} + self.special_offer: Optional[Dict] = None + self.league_rank_cache: Dict = {} + self.tournament_info: Dict = {} self.account_tournament_list: Optional[Tuple[int, List[str]]] = None self.ping_thread_count = 0 self.invite_confirm_windows: List[Any] = [] # FIXME: Don't use Any. @@ -635,7 +635,7 @@ class App: If there's a foreground host-activity that says it's pausable, tell it to pause ..we now no longer pause if there are connected clients. """ - activity = _ba.get_foreground_host_activity() + activity: Optional[ba.Activity] = _ba.get_foreground_host_activity() if (activity is not None and activity.allow_pausing and not _ba.have_connected_clients()): from ba import _gameutils, _lang @@ -698,7 +698,7 @@ class App: # If we're in a host-session, tell them to end. # This lets them tear themselves down gracefully. - host_session = _ba.get_foreground_host_session() + host_session: Optional[ba.Session] = _ba.get_foreground_host_session() if host_session is not None: # Kick off a little transaction so we'll hopefully have all the diff --git a/assets/src/ba_data/python/ba/_apputils.py b/assets/src/ba_data/python/ba/_apputils.py index c7a7bd73..25a77d7d 100644 --- a/assets/src/ba_data/python/ba/_apputils.py +++ b/assets/src/ba_data/python/ba/_apputils.py @@ -173,8 +173,7 @@ def garbage_collect(session_end: bool = True) -> None: gc.collect() # Can be handy to print this to check for leaks between games. - # noinspection PyUnreachableCode - if False: # pylint: disable=using-constant-test + if bool(False): print('PY OBJ COUNT', len(gc.get_objects())) if gc.garbage: print('PYTHON GC FOUND', len(gc.garbage), 'UNCOLLECTIBLE OBJECTS:') diff --git a/assets/src/ba_data/python/ba/_coopsession.py b/assets/src/ba_data/python/ba/_coopsession.py index f30f2316..c0f212c3 100644 --- a/assets/src/ba_data/python/ba/_coopsession.py +++ b/assets/src/ba_data/python/ba/_coopsession.py @@ -192,7 +192,7 @@ class CoopSession(Session): # If there's *no* players left in the current activity but there *is* # in the session, restart the activity to pull them into the game # (or quit if they're just in the lobby). - if activity is not None and not activity.players and self.players: + if not activity.players and self.players: # Special exception for tourney games; don't auto-restart these. if self.tournament_id is not None: diff --git a/assets/src/ba_data/python/ba/_dependency.py b/assets/src/ba_data/python/ba/_dependency.py index b7ba86cc..082f05ef 100644 --- a/assets/src/ba_data/python/ba/_dependency.py +++ b/assets/src/ba_data/python/ba/_dependency.py @@ -409,8 +409,7 @@ class TestClass(DependencyComponent): def test_depset() -> None: """Test call to try this stuff out...""" - # noinspection PyUnreachableCode - if False: # pylint: disable=using-constant-test + if bool(False): print('running test_depset()...') def doit() -> None: diff --git a/assets/src/ba_data/python/ba/_gameresults.py b/assets/src/ba_data/python/ba/_gameresults.py index 47146043..1db48666 100644 --- a/assets/src/ba_data/python/ba/_gameresults.py +++ b/assets/src/ba_data/python/ba/_gameresults.py @@ -52,7 +52,8 @@ class TeamGameResults: def __init__(self) -> None: """Instantiate a results instance.""" self._game_set = False - self._scores: Dict[int, Tuple[ReferenceType[ba.Team], int]] = {} + self._scores: Dict[int, Tuple[ReferenceType[ba.Team], + Optional[int]]] = {} self._teams: Optional[List[ReferenceType[ba.Team]]] = None self._player_info: Optional[List[Dict[str, Any]]] = None self._lower_is_better: Optional[bool] = None @@ -183,19 +184,21 @@ class TeamGameResults: if score[0]() is not None and score[1] is not None ] for score in scores: + assert score[1] is not None sval = winners.setdefault(score[1], []) team = score[0]() assert team is not None sval.append(team) results: List[Tuple[Optional[int], List[ba.Team]]] = list(winners.items()) - results.sort(reverse=not self._lower_is_better) + results.sort(reverse=not self._lower_is_better, key=lambda x: x[0]) # Also group the 'None' scores. none_teams: List[ba.Team] = [] for score in self._scores.values(): - if score[0]() is not None and score[1] is None: - none_teams.append(score[0]()) + scoreteam = score[0]() + if scoreteam is not None and score[1] is None: + none_teams.append(scoreteam) # Add the Nones to the list (either as winners or losers # depending on the rules). diff --git a/assets/src/ba_data/python/ba/_gameutils.py b/assets/src/ba_data/python/ba/_gameutils.py index 059eef51..4de43c43 100644 --- a/assets/src/ba_data/python/ba/_gameutils.py +++ b/assets/src/ba_data/python/ba/_gameutils.py @@ -27,7 +27,7 @@ import _ba from ba._enums import TimeType, TimeFormat, SpecialChar if TYPE_CHECKING: - from typing import Any, Dict, Sequence + from typing import Any, Dict, Sequence, Optional import ba TROPHY_CHARS = { @@ -97,7 +97,7 @@ def sharedobj(name: str) -> Any: # We store these on the current context; whether its an activity or # session. - activity = _ba.getactivity(doraise=False) + activity: Optional[ba.Activity] = _ba.getactivity(doraise=False) if activity is not None: # Grab shared-objs dict. @@ -141,7 +141,7 @@ def sharedobj(name: str) -> Any: "unrecognized shared object (activity context): '" + name + "'") else: - session = _ba.getsession(doraise=False) + session: Optional[ba.Session] = _ba.getsession(doraise=False) if session is not None: # Grab shared-objs dict (creating if necessary). diff --git a/assets/src/ba_data/python/ba/_general.py b/assets/src/ba_data/python/ba/_general.py index 92519239..e948c4f6 100644 --- a/assets/src/ba_data/python/ba/_general.py +++ b/assets/src/ba_data/python/ba/_general.py @@ -39,9 +39,8 @@ def getclass(name: str, subclassof: Type[T]) -> Type[T]: Category: General Utility Functions - If 'subclassof' is given, the class will be checked to make sure - it is a subclass of the provided class, and a TypeError will be - raised if not. + The class will be checked to make sure it is a subclass of the provided + 'subclassof' class, and a TypeError will be raised if not. """ import importlib splits = name.split('.') @@ -50,7 +49,7 @@ def getclass(name: str, subclassof: Type[T]) -> Type[T]: module = importlib.import_module(modulename) cls: Type = getattr(module, classname) - if subclassof is not None and not issubclass(cls, subclassof): + if not issubclass(cls, subclassof): raise TypeError(name + ' is not a subclass of ' + str(subclassof)) return cls diff --git a/assets/src/ba_data/python/ba/_lang.py b/assets/src/ba_data/python/ba/_lang.py index 8707f76a..b9c54f17 100644 --- a/assets/src/ba_data/python/ba/_lang.py +++ b/assets/src/ba_data/python/ba/_lang.py @@ -432,6 +432,7 @@ def get_valid_languages() -> List[str]: def is_custom_unicode_char(char: str) -> bool: """Return whether a char is in the custom unicode range we use.""" - if not isinstance(char, str) or len(char) != 1: - raise Exception("Invalid Input; not unicode or not length 1") + assert isinstance(char, str) + if len(char) != 1: + raise Exception("Invalid Input; must be length 1") return 0xE000 <= ord(char) <= 0xF8FF diff --git a/assets/src/ba_data/python/ba/_level.py b/assets/src/ba_data/python/ba/_level.py index d5271d9b..687bae40 100644 --- a/assets/src/ba_data/python/ba/_level.py +++ b/assets/src/ba_data/python/ba/_level.py @@ -117,7 +117,8 @@ class Level: def set_complete(self, val: bool) -> None: """Set whether or not this level is complete.""" old_val = self.complete - assert isinstance(old_val, bool) and isinstance(val, bool) + assert isinstance(old_val, bool) + assert isinstance(val, bool) if val != old_val: config = self._get_config_dict() config['Complete'] = val diff --git a/assets/src/ba_data/python/ba/_lobby.py b/assets/src/ba_data/python/ba/_lobby.py index 85ff0f1d..f3941a74 100644 --- a/assets/src/ba_data/python/ba/_lobby.py +++ b/assets/src/ba_data/python/ba/_lobby.py @@ -55,7 +55,8 @@ class JoinInfo: # If we have a keyboard, grab keys for punch and pickup. # FIXME: This of course is only correct on the local device; # Should change this for net games. - keyboard = _ba.get_input_device('Keyboard', '#1', doraise=False) + keyboard: Optional[ba.InputDevice] = _ba.get_input_device( + 'Keyboard', '#1', doraise=False) if keyboard is not None: punch_key = keyboard.get_button_name( _input.get_device_value(keyboard, 'buttonPunch')) @@ -398,8 +399,7 @@ class Chooser: # list might have changed. input_device = self._player.get_input_device() is_remote = input_device.is_remote_client - is_test_input = (input_device is not None - and input_device.name.startswith('TestInput')) + is_test_input = input_device.name.startswith('TestInput') # Pull this player's list of unlocked characters. if is_remote: diff --git a/assets/src/ba_data/python/ba/_modutils.py b/assets/src/ba_data/python/ba/_modutils.py index b4d8cd2a..e24fe638 100644 --- a/assets/src/ba_data/python/ba/_modutils.py +++ b/assets/src/ba_data/python/ba/_modutils.py @@ -19,11 +19,16 @@ # SOFTWARE. # ----------------------------------------------------------------------------- """Functionality related to modding.""" +from __future__ import annotations +from typing import TYPE_CHECKING import os import _ba +if TYPE_CHECKING: + from typing import Optional + def get_human_readable_user_scripts_path() -> str: """Return a human readable location of user-scripts. @@ -32,7 +37,7 @@ def get_human_readable_user_scripts_path() -> str: """ from ba import _lang app = _ba.app - path = app.user_scripts_directory + path: Optional[str] = app.user_scripts_directory if path is None: return '' @@ -40,7 +45,8 @@ def get_human_readable_user_scripts_path() -> str: # only visible to the user's processes and thus not really useful printed # in its entirety; lets print it as /myfilepath. if app.platform == 'android': - ext_storage_path = (_ba.android_get_external_storage_path()) + ext_storage_path: Optional[str] = ( + _ba.android_get_external_storage_path()) if (ext_storage_path is not None and app.user_scripts_directory.startswith(ext_storage_path)): path = ('<' + @@ -75,7 +81,7 @@ def show_user_scripts() -> None: # they can see it. if app.platform == 'android': try: - usd = app.user_scripts_directory + usd: Optional[str] = app.user_scripts_directory if usd is not None and os.path.isdir(usd): file_name = usd + '/about_this_folder.txt' with open(file_name, 'w') as outfile: diff --git a/assets/src/ba_data/python/ba/_music.py b/assets/src/ba_data/python/ba/_music.py index ac960533..4230a40f 100644 --- a/assets/src/ba_data/python/ba/_music.py +++ b/assets/src/ba_data/python/ba/_music.py @@ -83,7 +83,7 @@ class MusicPlayer: def __init__(self) -> None: self._have_set_initial_volume = False - self._entry_to_play = None + self._entry_to_play: Optional[Any] = None self._volume = 1.0 self._actually_playing = False diff --git a/assets/src/ba_data/python/ba/_netutils.py b/assets/src/ba_data/python/ba/_netutils.py index 8369d335..f28eaab1 100644 --- a/assets/src/ba_data/python/ba/_netutils.py +++ b/assets/src/ba_data/python/ba/_netutils.py @@ -32,6 +32,7 @@ import _ba if TYPE_CHECKING: from typing import Any, Dict, Union, Callable, Optional import socket + import ba ServerCallbackType = Callable[[Union[None, Dict[str, Any]]], None] @@ -82,7 +83,7 @@ class ServerCallThread(threading.Thread): self._context = _ba.Context('current') # Save and restore the context we were created from. - activity = _ba.getactivity(doraise=False) + activity: Optional[ba.Activity] = _ba.getactivity(doraise=False) self._activity = weakref.ref( activity) if activity is not None else None diff --git a/assets/src/ba_data/python/ba/_session.py b/assets/src/ba_data/python/ba/_session.py index cdfeac9d..52671049 100644 --- a/assets/src/ba_data/python/ba/_session.py +++ b/assets/src/ba_data/python/ba/_session.py @@ -746,7 +746,7 @@ class Session: # Pass it to the current activity if it has already begun # (otherwise it'll get passed once begin is called). - pass_to_activity = (activity is not None and activity.has_begun() + pass_to_activity = (activity.has_begun() and not activity.is_joining_activity) # If we're not allowing mid-game joins, don't pass; just announce diff --git a/assets/src/ba_data/python/ba/_stats.py b/assets/src/ba_data/python/ba/_stats.py index 6954aea2..6a24cea2 100644 --- a/assets/src/ba_data/python/ba/_stats.py +++ b/assets/src/ba_data/python/ba/_stats.py @@ -256,7 +256,7 @@ class Stats: self.orchestrahitsound3: Optional[ba.Sound] = None self.orchestrahitsound4: Optional[ba.Sound] = None - def set_activity(self, activity: ba.Activity) -> None: + def set_activity(self, activity: Optional[ba.Activity]) -> None: """Set the current activity for this instance.""" self._activity = None if activity is None else weakref.ref(activity) diff --git a/assets/src/ba_data/python/ba/_tournament.py b/assets/src/ba_data/python/ba/_tournament.py index f5491a3a..38b0768c 100644 --- a/assets/src/ba_data/python/ba/_tournament.py +++ b/assets/src/ba_data/python/ba/_tournament.py @@ -30,7 +30,7 @@ if TYPE_CHECKING: from typing import Dict, List, Any -def get_tournament_prize_strings(entry: Dict[str, Any]) -> List: +def get_tournament_prize_strings(entry: Dict[str, Any]) -> List[str]: """Given a tournament entry, return strings for its prize levels.""" # pylint: disable=too-many-locals from ba._enums import SpecialChar @@ -54,22 +54,9 @@ def get_tournament_prize_strings(entry: Dict[str, Any]) -> List: pvval = '' if trophy_type is not None: pvval += get_trophy_string(trophy_type) - # trophy_chars = { - # '1': SpecialChar.TROPHY1, - # '2': SpecialChar.TROPHY2, - # '3': SpecialChar.TROPHY3, - # '0a': SpecialChar.TROPHY0A, - # '0b': SpecialChar.TROPHY0B, - # '4': SpecialChar.TROPHY4 - # } - # if trophy_type in trophy_chars: - # pvval += _bs.specialchar(trophy_chars[trophy_type]) - # else: - # from ba import err - # err.print_error( - # f"unrecognized trophy type: {trophy_type}", once=True) - # if we've got trophies but not for this entry, throw some space - # in to compensate so the ticket counts line up + + # If we've got trophies but not for this entry, throw some space + # in to compensate so the ticket counts line up. if prize is not None: pvval = _ba.charstr( SpecialChar.TICKET_BACKING) + str(prize) + pvval diff --git a/assets/src/ba_data/python/bastd/activity/coopscorescreen.py b/assets/src/ba_data/python/bastd/activity/coopscorescreen.py index f96ca753..a1ed3fa2 100644 --- a/assets/src/ba_data/python/bastd/activity/coopscorescreen.py +++ b/assets/src/ba_data/python/bastd/activity/coopscorescreen.py @@ -674,7 +674,8 @@ class CoopScoreScreen(ba.Activity): our_score = None try: - our_high_scores.sort(reverse=self._score_order == 'increasing') + our_high_scores.sort(reverse=self._score_order == 'increasing', + key=lambda x: x[0]) except Exception: ba.print_exception('Error sorting scores') print('our_high_scores:', our_high_scores) @@ -711,8 +712,7 @@ class CoopScoreScreen(ba.Activity): order=self._score_order, tournament_id=self.session.tournament_id, score_type=self._score_type, - campaign=self._campaign.name - if self._campaign is not None else None, + campaign=self._campaign.name, level=self._level_name) # Apply the transactions we've been adding locally. @@ -924,7 +924,8 @@ class CoopScoreScreen(ba.Activity): results.remove(score) break results.append(our_score_entry) - results.sort(reverse=self._score_order == 'increasing') + results.sort(reverse=self._score_order == 'increasing', + key=lambda x: x[0]) # If we're not submitting our own score, we still want to change the # name of our own score to 'Me'. @@ -1028,8 +1029,9 @@ class CoopScoreScreen(ba.Activity): self._score_link) self._score_loading_status = None if 'tournamentSecondsRemaining' in results: - self._tournament_time_remaining = ( - results['tournamentSecondsRemaining']) + secs_remaining = results['tournamentSecondsRemaining'] + assert isinstance(secs_remaining, int) + self._tournament_time_remaining = secs_remaining self._tournament_time_remaining_text_timer = ba.Timer( 1.0, ba.WeakCall( @@ -1088,7 +1090,7 @@ class CoopScoreScreen(ba.Activity): elif p_count == 4: scale = 0.5 - # make sure there's at least 10.. + # Make sure there's at least 10. while len(self._show_info['tops']) < 10: self._show_info['tops'].append([0, '-']) @@ -1400,10 +1402,10 @@ class CoopScoreScreen(ba.Activity): transition_delay=1.0).autoretain() new_best = (best_rank > self._old_best_rank and best_rank > 0.0) - was_string = ('' if self._old_best_rank is None else ba.Lstr( - value=' ${A}', - subs=[('${A}', ba.Lstr(resource='scoreWasText')), - ('${COUNT}', str(self._old_best_rank))])) + was_string = ba.Lstr(value=' ${A}', + subs=[('${A}', + ba.Lstr(resource='scoreWasText')), + ('${COUNT}', str(self._old_best_rank))]) if not self._newly_complete: Text(ba.Lstr(value='${A}${B}', subs=[('${A}', diff --git a/assets/src/ba_data/python/bastd/activity/multiteamendscreen.py b/assets/src/ba_data/python/bastd/activity/multiteamendscreen.py index 4abff20b..f3f399c9 100644 --- a/assets/src/ba_data/python/bastd/activity/multiteamendscreen.py +++ b/assets/src/ba_data/python/bastd/activity/multiteamendscreen.py @@ -80,11 +80,11 @@ class TeamSeriesVictoryScoreScreenActivity(TeamsScoreScreenActivity): player_entries.append( (prec.player.team.sessiondata['score'], prec.get_name(full=True), prec)) - player_entries.sort(reverse=True) + player_entries.sort(reverse=True, key=lambda x: x[0]) else: for _pkey, prec in self.stats.get_records().items(): player_entries.append((prec.score, prec.name_full, prec)) - player_entries.sort(reverse=True) + player_entries.sort(reverse=True, key=lambda x: x[0]) ts_height = 300.0 ts_h_offs = -390.0 diff --git a/assets/src/ba_data/python/bastd/activity/teamsscorescreen.py b/assets/src/ba_data/python/bastd/activity/teamsscorescreen.py index 316823f7..181534b6 100644 --- a/assets/src/ba_data/python/bastd/activity/teamsscorescreen.py +++ b/assets/src/ba_data/python/bastd/activity/teamsscorescreen.py @@ -135,7 +135,8 @@ class TeamsScoreScreenActivity(ScoreScreenActivity): if player_entry is not None: player_records.append(player_entry) else: - raise Exception('FIXME; CODE PATH NEEDS FIXING') + print('FIXME; CODE PATH NEEDS FIXING') + player_records = [] # player_records = [[ # _get_prec_score(p), name, p # ] for name, p in list(self.stats.get_records().items())] diff --git a/assets/src/ba_data/python/bastd/actor/controlsguide.py b/assets/src/ba_data/python/bastd/actor/controlsguide.py index 8809cc69..3b54729d 100644 --- a/assets/src/ba_data/python/bastd/actor/controlsguide.py +++ b/assets/src/ba_data/python/bastd/actor/controlsguide.py @@ -264,7 +264,8 @@ class ControlsGuide(ba.Actor): # If we have a touchscreen, we only fade in if we have a player with # an input device that is *not* the touchscreen. - touchscreen = _ba.get_input_device('TouchScreen', '#1', doraise=False) + touchscreen: Optional[ba.InputDevice] = _ba.get_input_device( + 'TouchScreen', '#1', doraise=False) if touchscreen is not None: # We look at the session's players; not the activity's. diff --git a/assets/src/ba_data/python/bastd/actor/image.py b/assets/src/ba_data/python/bastd/actor/image.py index 1faa4950..05aff991 100644 --- a/assets/src/ba_data/python/bastd/actor/image.py +++ b/assets/src/ba_data/python/bastd/actor/image.py @@ -170,9 +170,7 @@ class Image(ba.Actor): ba.animate(cmb, 'input1', keys) ba.animate(self.node, 'opacity', o_keys) else: - if (transition is not self.Transition.FADE_IN - and transition is not None): - ba.print_error(f'Invalid transition: "{transition}"') + assert transition is self.Transition.FADE_IN or transition is None cmb.input0 = position[0] cmb.input1 = position[1] cmb.connectattr('output', self.node, 'position') diff --git a/assets/src/ba_data/python/bastd/actor/spazbot.py b/assets/src/ba_data/python/bastd/actor/spazbot.py index 6e3a71c2..9e14de07 100644 --- a/assets/src/ba_data/python/bastd/actor/spazbot.py +++ b/assets/src/ba_data/python/bastd/actor/spazbot.py @@ -187,9 +187,9 @@ class SpazBot(basespaz.Spaz): """ assert self.node botpt = ba.Vec3(self.node.position) - closest_dist = None - closest_vel = None - closest = None + closest_dist: Optional[float] = None + closest_vel: Optional[ba.Vec3] = None + closest: Optional[ba.Vec3] = None assert self._player_pts is not None for plpt, plvel in self._player_pts: dist = (plpt - botpt).length() @@ -985,7 +985,7 @@ class BotSet: try: if player.is_alive(): assert isinstance(player.actor, basespaz.Spaz) - assert player.actor is not None and player.actor.node + assert player.actor.node player_pts.append((ba.Vec3(player.actor.node.position), ba.Vec3(player.actor.node.velocity))) except Exception: @@ -999,7 +999,7 @@ class BotSet: """Immediately clear out any bots in the set.""" # Don't do this if the activity is shutting down or dead. - activity = ba.getactivity(doraise=False) + activity: Optional[ba.Activity] = ba.getactivity(doraise=False) if activity is None or activity.is_expired(): return diff --git a/assets/src/ba_data/python/bastd/actor/text.py b/assets/src/ba_data/python/bastd/actor/text.py index ea67965f..3e9003c2 100644 --- a/assets/src/ba_data/python/bastd/actor/text.py +++ b/assets/src/ba_data/python/bastd/actor/text.py @@ -215,9 +215,7 @@ class Text(ba.Actor): ba.animate(cmb, 'input1', keys) ba.animate(self.node, 'opacity', o_keys) else: - if (transition is not self.Transition.FADE_IN - and transition is not None): - ba.print_error(f'Invalid transition: "{transition}"') + assert transition is self.Transition.FADE_IN or transition is None cmb.input0 = position[0] cmb.input1 = position[1] cmb.connectattr('output', self.node, 'position') diff --git a/assets/src/ba_data/python/bastd/game/conquest.py b/assets/src/ba_data/python/bastd/game/conquest.py index 7509f92e..f7430357 100644 --- a/assets/src/ba_data/python/bastd/game/conquest.py +++ b/assets/src/ba_data/python/bastd/game/conquest.py @@ -45,16 +45,17 @@ class ConquestFlag(Flag): self._team: Optional[ba.Team] = None self.light: Optional[ba.Node] = None - def set_team(self, team: ba.Team) -> None: - """Set the team that owns this flag.""" - self._team = None if team is None else team - @property def team(self) -> ba.Team: """The team that owns this flag.""" assert self._team is not None return self._team + @team.setter + def team(self, team: ba.Team) -> None: + """Set the team that owns this flag.""" + self._team = team + # ba_meta export game class ConquestGame(ba.TeamGameActivity): @@ -165,7 +166,7 @@ class ConquestGame(ba.TeamGameActivity): # Give teams a flag to start with. for i in range(len(self.teams)): - self._flags[i].set_team(self.teams[i]) + self._flags[i].team = self.teams[i] light = self._flags[i].light assert light node = self._flags[i].node @@ -227,9 +228,12 @@ class ConquestGame(ba.TeamGameActivity): flag = flagnode.getdelegate() except Exception: return # Player may have left and his body hit the flag. + assert isinstance(player, ba.Player) + assert isinstance(flag, ConquestFlag) + assert flag.light if flag.team is not player.team: - flag.set_team(player.team) + flag.team = player.team flag.light.color = player.team.color flag.node.color = player.team.color self.stats.player_scored(player, 10, screenmessage=False) diff --git a/assets/src/ba_data/python/bastd/game/elimination.py b/assets/src/ba_data/python/bastd/game/elimination.py index 89700e30..58c4cf8d 100644 --- a/assets/src/ba_data/python/bastd/game/elimination.py +++ b/assets/src/ba_data/python/bastd/game/elimination.py @@ -400,7 +400,8 @@ class EliminationGame(ba.TeamGameActivity): self.map.get_start_position(team.get_id())) points.append( ((start_pos - player_pos).length(), start_pos)) - points.sort() + # Hmm.. we need to sorting vectors too? + points.sort(key=lambda x: x[0]) return points[-1][1] return None diff --git a/assets/src/ba_data/python/bastd/game/football.py b/assets/src/ba_data/python/bastd/game/football.py index ff8b3cc6..a7a9361d 100644 --- a/assets/src/ba_data/python/bastd/game/football.py +++ b/assets/src/ba_data/python/bastd/game/football.py @@ -590,8 +590,8 @@ class FootballCoopGame(ba.CoopGameActivity): return flagpos = ba.Vec3(self._flag.node.position) - closest_bot = None - closest_dist = None + closest_bot: Optional[spazbot.SpazBot] = None + closest_dist = 0.0 # Always gets assigned first time through. for bot in bots: # If a bot is picked up, he should forget about the flag. if bot.held_count > 0: @@ -600,8 +600,8 @@ class FootballCoopGame(ba.CoopGameActivity): botpos = ba.Vec3(bot.node.position) botdist = (botpos - flagpos).length() if closest_bot is None or botdist < closest_dist: - closest_dist = botdist closest_bot = bot + closest_dist = botdist if closest_bot is not None: closest_bot.target_flag = self._flag diff --git a/assets/src/ba_data/python/bastd/game/onslaught.py b/assets/src/ba_data/python/bastd/game/onslaught.py index dca402c2..959c603e 100644 --- a/assets/src/ba_data/python/bastd/game/onslaught.py +++ b/assets/src/ba_data/python/bastd/game/onslaught.py @@ -959,9 +959,9 @@ class OnslaughtGame(ba.CoopGameActivity): max_dudes, group_count, max_level) - all_entries: List[Dict[str, Any]] = [] + all_entries: List[Optional[Dict[str, Any]]] = [] for group in distribution: - entries: List[Dict[str, Any]] = [] + entries: List[Optional[Dict[str, Any]]] = [] for entry in group: bot_level = bot_levels[entry[0] - 1] bot_type = bot_level[random.randrange(len(bot_level))] diff --git a/assets/src/ba_data/python/bastd/game/race.py b/assets/src/ba_data/python/bastd/game/race.py index 5640e9b7..f4331510 100644 --- a/assets/src/ba_data/python/bastd/game/race.py +++ b/assets/src/ba_data/python/bastd/game/race.py @@ -139,7 +139,7 @@ class RaceGame(ba.TeamGameActivity): self._score_sound = ba.getsound('score') self._swipsound = ba.getsound('swip') self._last_team_time: Optional[float] = None - self._front_race_region = None + self._front_race_region: Optional[int] = None self._nub_tex = ba.gettexture('nub') self._beep_1_sound = ba.getsound('raceBeep1') self._beep_2_sound = ba.getsound('raceBeep2') @@ -190,7 +190,7 @@ class RaceGame(ba.TeamGameActivity): def _flash_player(self, player: ba.Player, scale: float) -> None: assert isinstance(player.actor, PlayerSpaz) - assert player.actor is not None and player.actor.node + assert player.actor.node pos = player.actor.node.position light = ba.newnode('light', attrs={ @@ -213,9 +213,11 @@ class RaceGame(ba.TeamGameActivity): player = playernode.getdelegate().getplayer() except Exception: player = None + assert isinstance(player, ba.Player) region = region_node.getdelegate() if not player or not region: return + assert isinstance(region, RaceRegion) last_region = player.gamedata['last_region'] this_region = region.index @@ -227,6 +229,7 @@ class RaceGame(ba.TeamGameActivity): # blown over a region, etc). if this_region > last_region + 2: if player.is_alive(): + assert player.actor player.actor.handlemessage(ba.DieMessage()) ba.screenmessage(ba.Lstr( translate=('statements', 'Killing ${NAME} for' @@ -273,6 +276,7 @@ class RaceGame(ba.TeamGameActivity): # Flash where the player is. self._flash_player(player, 1.0) player.gamedata['finished'] = True + assert player.actor player.actor.handlemessage( ba.DieMessage(immediate=True)) @@ -305,6 +309,7 @@ class RaceGame(ba.TeamGameActivity): # Print their lap number over their head. try: + assert isinstance(player.actor, PlayerSpaz) mathnode = ba.newnode('math', owner=player.actor.node, attrs={ @@ -529,7 +534,7 @@ class RaceGame(ba.TeamGameActivity): pos: Optional[ba.Vec3] try: assert isinstance(player.actor, PlayerSpaz) - assert player.actor is not None and player.actor.node + assert player.actor.node pos = ba.Vec3(player.actor.node.position) except Exception: pos = None @@ -550,9 +555,7 @@ class RaceGame(ba.TeamGameActivity): p_list = [[player.gamedata['distance'], player] for player in self.players] - p_list.sort(reverse=True) - # FIXME - need another way to sort p_list. - # It tries to compare ba.Player objects. + p_list.sort(reverse=True, key=lambda x: x[0]) for i, plr in enumerate(p_list): try: plr[1].gamedata['rank'] = i diff --git a/assets/src/ba_data/python/bastd/game/runaround.py b/assets/src/ba_data/python/bastd/game/runaround.py index 32ba00e5..7cb58478 100644 --- a/assets/src/ba_data/python/bastd/game/runaround.py +++ b/assets/src/ba_data/python/bastd/game/runaround.py @@ -725,7 +725,7 @@ class RunaroundGame(ba.CoopGameActivity): t_sec = 0.0 base_delay = 0.5 delay = 0.0 - bot_types: List[Dict[str, Any]] = [] + bot_types: List[Optional[Dict[str, Any]]] = [] if self._preset in ['endless', 'endless_tournament']: level = self._wave diff --git a/assets/src/ba_data/python/bastd/game/thelaststand.py b/assets/src/ba_data/python/bastd/game/thelaststand.py index 08f87f32..3b8c1fd4 100644 --- a/assets/src/ba_data/python/bastd/game/thelaststand.py +++ b/assets/src/ba_data/python/bastd/game/thelaststand.py @@ -198,7 +198,7 @@ class TheLastStandGame(ba.CoopGameActivity): try: if player.is_alive(): assert isinstance(player.actor, playerspaz.PlayerSpaz) - assert player.actor is not None and player.actor.node + assert player.actor.node playerpts.append(player.actor.node.position) except Exception as exc: print('ERROR in _update_bots', exc) diff --git a/assets/src/ba_data/python/bastd/tutorial.py b/assets/src/ba_data/python/bastd/tutorial.py index ecc5d2d9..8523cb95 100644 --- a/assets/src/ba_data/python/bastd/tutorial.py +++ b/assets/src/ba_data/python/bastd/tutorial.py @@ -243,8 +243,7 @@ class TutorialActivity(ba.Activity): ba.set_analytics_screen('Tutorial Start') _ba.increment_analytics_count('Tutorial start') - # noinspection PyUnreachableCode - if 0: # pylint: disable=using-constant-test + if bool(False): # Buttons on top. text_y = 140 buttons_y = 250 diff --git a/assets/src/ba_data/python/bastd/ui/appinvite.py b/assets/src/ba_data/python/bastd/ui/appinvite.py index 54163130..f11475be 100644 --- a/assets/src/ba_data/python/bastd/ui/appinvite.py +++ b/assets/src/ba_data/python/bastd/ui/appinvite.py @@ -322,6 +322,7 @@ def handle_app_invites_press(force_code: bool = False) -> None: 'enableAppInvites', False) and not app.on_tv) if force_code: do_app_invites = False + # FIXME: Should update this to grab a code before showing the invite UI. if do_app_invites: AppInviteWindow() @@ -330,7 +331,7 @@ def handle_app_invites_press(force_code: bool = False) -> None: ba.Lstr(resource='gatherWindow.requestingAPromoCodeText'), color=(0, 1, 0)) - def handle_result(result: Dict[str, Any]) -> None: + def handle_result(result: Optional[Dict[str, Any]]) -> None: with ba.Context('ui'): if result is None: ba.screenmessage(ba.Lstr(resource='errorText'), diff --git a/assets/src/ba_data/python/bastd/ui/coop/browser.py b/assets/src/ba_data/python/bastd/ui/coop/browser.py index 902fcd02..e4f8c464 100644 --- a/assets/src/ba_data/python/bastd/ui/coop/browser.py +++ b/assets/src/ba_data/python/bastd/ui/coop/browser.py @@ -357,19 +357,14 @@ class CoopBrowserWindow(ba.Window): # Update all of our tourney buttons based on whats in data. for i, tbtn in enumerate(self._tournament_buttons): - entry: Optional[Dict[str, Any]] - try: - assert data is not None - entry = data[i] - except Exception: - entry = None - prize_y_offs = (0 if entry is None else 34 if 'prizeRange3' in - entry else 20 if 'prizeRange2' in entry else 12) + assert data is not None + entry: Dict[str, Any] = data[i] + prize_y_offs = (34 if 'prizeRange3' in entry else + 20 if 'prizeRange2' in entry else 12) x_offs = 90 # This seems to be a false alarm. # pylint: disable=unbalanced-tuple-unpacking - assert entry is not None pr1, pv1, pr2, pv2, pr3, pv3 = ( get_tournament_prize_strings(entry)) # pylint: enable=unbalanced-tuple-unpacking @@ -427,7 +422,7 @@ class CoopBrowserWindow(ba.Window): leader_name = '-' leader_score: Union[str, ba.Lstr] = '-' - if entry is not None and entry['scores']: + if entry['scores']: score = tbtn['leader'] = copy.deepcopy(entry['scores'][0]) leader_name = score[1] leader_score = ( @@ -441,15 +436,13 @@ class CoopBrowserWindow(ba.Window): ba.textwidget(edit=tbtn['current_leader_name_text'], text=ba.Lstr(value=leader_name)) - self._tournament_leader_score_type = (None if entry is None else - entry['scoreType']) + self._tournament_leader_score_type = (entry['scoreType']) ba.textwidget(edit=tbtn['current_leader_score_text'], text=leader_score) ba.buttonwidget(edit=tbtn['more_scores_button'], - label='-' if entry is None else ba.Lstr( - resource=self._r + '.seeMoreText')) + label=ba.Lstr(resource=self._r + '.seeMoreText')) out_of_time_text: Union[str, ba.Lstr] = ( - '-' if entry is None or 'totalTime' not in entry else ba.Lstr( + '-' if 'totalTime' not in entry else ba.Lstr( resource=self._r + '.ofTotalTimeText', subs=[('${TOTAL}', ba.timestring(entry['totalTime'], @@ -458,16 +451,13 @@ class CoopBrowserWindow(ba.Window): ba.textwidget(edit=tbtn['time_remaining_out_of_text'], text=out_of_time_text) - tbtn['time_remaining'] = 0 if entry is None else entry[ - 'timeRemaining'] + tbtn['time_remaining'] = entry['timeRemaining'] tbtn['has_time_remaining'] = entry is not None - tbtn['tournament_id'] = (None if entry is None else - entry['tournamentID']) + tbtn['tournament_id'] = entry['tournamentID'] tbtn['required_league'] = (None if 'requiredLeague' not in entry else entry['requiredLeague']) - game = (None if entry is None else - ba.app.tournament_info[tbtn['tournament_id']]['game']) + game = ba.app.tournament_info[tbtn['tournament_id']]['game'] if game is None: ba.textwidget(edit=tbtn['button_text'], text='-') @@ -491,7 +481,7 @@ class CoopBrowserWindow(ba.Window): levelname).get_preview_texture(), opacity=1.0 if enabled else 0.5) - fee = None if entry is None else entry['fee'] + fee = entry['fee'] if fee is None: fee_var = None diff --git a/assets/src/ba_data/python/bastd/ui/gather.py b/assets/src/ba_data/python/bastd/ui/gather.py index fc63e4f4..68c6ccbc 100644 --- a/assets/src/ba_data/python/bastd/ui/gather.py +++ b/assets/src/ba_data/python/bastd/ui/gather.py @@ -149,7 +149,7 @@ class GatherWindow(ba.Window): tabs_def: List[Tuple[str, ba.Lstr]] = [ ('about', ba.Lstr(resource=self._r + '.aboutText')) ] - if True and _ba.get_account_misc_read_val('enablePublicParties', True): + if _ba.get_account_misc_read_val('enablePublicParties', True): tabs_def.append( ('internet', ba.Lstr(resource=self._r + '.internetText'))) if platform == 'android' and subplatform == 'google': @@ -1451,8 +1451,7 @@ class GatherWindow(ba.Window): key=lambda p: ( p['queue'] is None, # Show non-queued last. p['ping'] if p['ping'] is not None else 999999, - p['index'], - p)) + p['index'])) existing_selection = self._public_party_list_selection first = True diff --git a/assets/src/ba_data/python/bastd/ui/kiosk.py b/assets/src/ba_data/python/bastd/ui/kiosk.py index 13ee9457..262ef871 100644 --- a/assets/src/ba_data/python/bastd/ui/kiosk.py +++ b/assets/src/ba_data/python/bastd/ui/kiosk.py @@ -203,8 +203,7 @@ class KioskWindow(ba.Window): self._b5: Optional[ba.Widget] self._b6: Optional[ba.Widget] - # noinspection PyUnreachableCode - if False: # pylint: disable=using-constant-test + if bool(False): ba.textwidget( parent=self._root_widget, size=(0, 0), @@ -312,8 +311,7 @@ class KioskWindow(ba.Window): self._b4 = self._b5 = self._b6 = None self._b7: Optional[ba.Widget] - # noinspection PyUnreachableCode - if False: # pylint: disable=using-constant-test + if bool(False): self._b7 = ba.buttonwidget( parent=self._root_widget, autoselect=True, diff --git a/assets/src/ba_data/python/bastd/ui/league/rankwindow.py b/assets/src/ba_data/python/bastd/ui/league/rankwindow.py index 8459cc0e..3e88d5ed 100644 --- a/assets/src/ba_data/python/bastd/ui/league/rankwindow.py +++ b/assets/src/ba_data/python/bastd/ui/league/rankwindow.py @@ -134,7 +134,7 @@ class LeagueRankWindow(ba.Window): self._season_popup_menu: Optional[popup_ui.PopupMenu] = None self._requested_season: Optional[str] = None - self._season = None + self._season: Optional[str] = None # take note of our account state; we'll refresh later if this changes self._account_state = _ba.get_account_state() diff --git a/assets/src/ba_data/python/bastd/ui/mainmenu.py b/assets/src/ba_data/python/bastd/ui/mainmenu.py index 242e5b1b..879b776d 100644 --- a/assets/src/ba_data/python/bastd/ui/mainmenu.py +++ b/assets/src/ba_data/python/bastd/ui/mainmenu.py @@ -703,7 +703,6 @@ class MainMenuWindow(ba.Window): v += v_offset h += h_offset h_offset += d_h_offset - custom_menu_entries = [] self._start_button = None ba.app.pause() diff --git a/assets/src/ba_data/python/bastd/ui/partyqueue.py b/assets/src/ba_data/python/bastd/ui/partyqueue.py index 2c769b92..19615265 100644 --- a/assets/src/ba_data/python/bastd/ui/partyqueue.py +++ b/assets/src/ba_data/python/bastd/ui/partyqueue.py @@ -293,7 +293,7 @@ class PartyQueueWindow(ba.Window): """(internal)""" return self._line_bottom - def on_account_press(self, account_id: str, + def on_account_press(self, account_id: Optional[str], origin_widget: ba.Widget) -> None: """A dude was clicked so we should show his account info.""" from bastd.ui.account import viewer diff --git a/assets/src/ba_data/python/bastd/ui/playlist/customizebrowser.py b/assets/src/ba_data/python/bastd/ui/playlist/customizebrowser.py index 9b96da1f..512b83b2 100644 --- a/assets/src/ba_data/python/bastd/ui/playlist/customizebrowser.py +++ b/assets/src/ba_data/python/bastd/ui/playlist/customizebrowser.py @@ -30,7 +30,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Type, Optional, Tuple, List + from typing import Any, Type, Optional, Tuple, List, Dict class PlaylistCustomizeBrowserWindow(ba.Window): @@ -562,6 +562,7 @@ class PlaylistCustomizeBrowserWindow(ba.Window): return if self._selected_playlist_name is None: return + plst: Optional[List[Dict[str, Any]]] if self._selected_playlist_name == '__default__': plst = self._pvars.get_default_list_call() else: diff --git a/assets/src/ba_data/python/bastd/ui/playlist/editgame.py b/assets/src/ba_data/python/bastd/ui/playlist/editgame.py index 1c9d7901..f96369b6 100644 --- a/assets/src/ba_data/python/bastd/ui/playlist/editgame.py +++ b/assets/src/ba_data/python/bastd/ui/playlist/editgame.py @@ -30,7 +30,7 @@ import _ba import ba if TYPE_CHECKING: - from typing import Type, Any, Dict, Callable, Optional, Union + from typing import Type, Any, Dict, Callable, Optional, Union, List class PlaylistEditGameWindow(ba.Window): @@ -197,7 +197,7 @@ class PlaylistEditGameWindow(ba.Window): # Keep track of all the selectable widgets we make so we can wire # them up conveniently. - widget_column = [] + widget_column: List[List[ba.Widget]] = [] # Map select button. ba.textwidget(parent=self._subcontainer, @@ -419,16 +419,17 @@ class PlaylistEditGameWindow(ba.Window): else: raise Exception() - # ok now wire up the column + # Ok now wire up the column. try: # pylint: disable=unsubscriptable-object - prev_widgets = None + prev_widgets: Optional[List[ba.Widget]] = None for cwdg in widget_column: if prev_widgets is not None: - # wire our rightmost to their rightmost + # Wire our rightmost to their rightmost. ba.widget(edit=prev_widgets[-1], down_widget=cwdg[-1]) ba.widget(cwdg[-1], up_widget=prev_widgets[-1]) - # wire our leftmost to their leftmost + + # Wire our leftmost to their leftmost. ba.widget(edit=prev_widgets[0], down_widget=cwdg[0]) ba.widget(cwdg[0], up_widget=prev_widgets[0]) prev_widgets = cwdg @@ -452,14 +453,14 @@ class PlaylistEditGameWindow(ba.Window): def _select_map(self) -> None: # pylint: disable=cyclic-import - from bastd.ui.playlist import mapselect + from bastd.ui.playlist.mapselect import PlaylistMapSelectWindow # Replace ourself with the map-select UI. ba.containerwidget(edit=self._root_widget, transition='out_left') - ba.app.main_menu_window = (mapselect.PlaylistMapSelectWindow( + ba.app.main_menu_window = PlaylistMapSelectWindow( self._gameclass, self._sessiontype, copy.deepcopy(self._getconfig()), self._edit_info, - self._completion_call).get_root_widget()) + self._completion_call).get_root_widget() def _choice_inc(self, setting_name: str, widget: ba.Widget, setting: Dict[str, Any], increment: int) -> None: diff --git a/assets/src/ba_data/python/bastd/ui/popup.py b/assets/src/ba_data/python/bastd/ui/popup.py index e5091bbe..426cf6b1 100644 --- a/assets/src/ba_data/python/bastd/ui/popup.py +++ b/assets/src/ba_data/python/bastd/ui/popup.py @@ -141,14 +141,7 @@ class PopupMenuWindow(PopupWindow): # we need to flatten them. choices_display_fin: List[str] = [] for choice_display in choices_display: - if isinstance(choice_display, ba.Lstr): - choices_display_fin.append(choice_display.evaluate()) - else: - ba.print_error( - 'PopupMenuWindow got a raw string in \'choices_display\';' - ' please pass ba.Lstr values only', - once=True) - choices_display_fin.append(choice_display) + choices_display_fin.append(choice_display.evaluate()) if maxwidth is None: maxwidth = width * 1.5 diff --git a/assets/src/ba_data/python/bastd/ui/settings/advanced.py b/assets/src/ba_data/python/bastd/ui/settings/advanced.py index 553b4ff6..275d5df5 100644 --- a/assets/src/ba_data/python/bastd/ui/settings/advanced.py +++ b/assets/src/ba_data/python/bastd/ui/settings/advanced.py @@ -69,7 +69,7 @@ class AdvancedSettingsWindow(ba.Window): stack_offset=(0, -25) if app.small_ui else (0, 0))) self._prev_lang = "" self._prev_lang_list: List[str] = [] - self._complete_langs_list = None + self._complete_langs_list: Optional[List] = None self._complete_langs_error = False self._language_popup: Optional[popup_ui.PopupMenu] = None diff --git a/assets/src/ba_data/python/bastd/ui/settings/controls.py b/assets/src/ba_data/python/bastd/ui/settings/controls.py index 252ebb63..0ac3c2c1 100644 --- a/assets/src/ba_data/python/bastd/ui/settings/controls.py +++ b/assets/src/ba_data/python/bastd/ui/settings/controls.py @@ -103,8 +103,7 @@ class ControlsSettingsWindow(ba.Window): show_space_2 = True height += space_height - # noinspection PyUnreachableCode - if True: # pylint: disable=using-constant-test + if bool(True): show_remote = True height += spacing else: diff --git a/assets/src/ba_data/python/bastd/ui/soundtrack/browser.py b/assets/src/ba_data/python/bastd/ui/soundtrack/browser.py index 0f67d867..68c5b5f0 100644 --- a/assets/src/ba_data/python/bastd/ui/soundtrack/browser.py +++ b/assets/src/ba_data/python/bastd/ui/soundtrack/browser.py @@ -289,10 +289,7 @@ class SoundtrackBrowserWindow(ba.Window): copy_word = copy_text.replace('${NAME}', '').strip() base_name = self._get_soundtrack_display_name( self._selected_soundtrack).evaluate() - if not isinstance(base_name, str): - print('expected uni base_name 3fj0') - assert isinstance(base_name, bytes) - base_name = base_name.decode('utf-8') + assert isinstance(base_name, str) # If it looks like a copy, strip digits and spaces off the end. if copy_word in base_name: diff --git a/assets/src/ba_data/python/bastd/ui/soundtrack/edit.py b/assets/src/ba_data/python/bastd/ui/soundtrack/edit.py index 0b8de05c..1b23e63d 100644 --- a/assets/src/ba_data/python/bastd/ui/soundtrack/edit.py +++ b/assets/src/ba_data/python/bastd/ui/soundtrack/edit.py @@ -205,8 +205,8 @@ class SoundtrackEditWindow(ba.Window): ] # FIXME: We should probably convert this to use translations. type_names_translated = get_resource('soundtrackTypeNames') - prev_type_button = None - prev_test_button = None + prev_type_button: Optional[ba.Widget] = None + prev_test_button: Optional[ba.Widget] = None for index, song_type in enumerate(types): row = ba.rowwidget(parent=self._col, size=(self._width - 40, 40)) diff --git a/assets/src/ba_data/python/bastd/ui/store/browser.py b/assets/src/ba_data/python/bastd/ui/store/browser.py index 1e0398fc..27dc949b 100644 --- a/assets/src/ba_data/python/bastd/ui/store/browser.py +++ b/assets/src/ba_data/python/bastd/ui/store/browser.py @@ -31,7 +31,8 @@ import _ba import ba if TYPE_CHECKING: - from typing import Any, Callable, Optional, Tuple, Dict, Union, Sequence + from typing import (Any, Callable, Optional, Tuple, Dict, Union, Sequence, + List) class StoreBrowserWindow(ba.Window): @@ -850,7 +851,7 @@ class StoreBrowserWindow(ba.Window): maxwidth=700, transition_delay=0.4) - prev_row_buttons = None + prev_row_buttons: Optional[List] = None this_row_buttons = [] delay = 0.3 diff --git a/assets/src/ba_data/python/bastd/ui/tournamententry.py b/assets/src/ba_data/python/bastd/ui/tournamententry.py index f7ef9175..f40bc191 100644 --- a/assets/src/ba_data/python/bastd/ui/tournamententry.py +++ b/assets/src/ba_data/python/bastd/ui/tournamententry.py @@ -518,10 +518,10 @@ class TournamentEntryWindow(popup.PopupWindow): try: ticket_count = _ba.get_account_ticket_count() except Exception: + # FIXME: should add a ba.NotSignedInError we can use here. ticket_count = None ticket_cost = self._purchase_price - if (ticket_count is not None and ticket_cost is not None - and ticket_count < ticket_cost): + if ticket_count is not None and ticket_count < ticket_cost: getcurrency.show_get_tickets_prompt() ba.playsound(ba.getsound('error')) return diff --git a/assets/src/ba_data/python/efro/util.py b/assets/src/ba_data/python/efro/util.py index 8f607758..aa777d4d 100644 --- a/assets/src/ba_data/python/efro/util.py +++ b/assets/src/ba_data/python/efro/util.py @@ -303,4 +303,6 @@ def make_hash(obj: Any) -> int: for k, v in new_obj.items(): new_obj[k] = make_hash(v) + # NOTE: there is sorted works correctly because it compares only + # unique first values (i.e. dict keys) return hash(tuple(frozenset(sorted(new_obj.items())))) diff --git a/assets/src/server/server.py b/assets/src/server/server.py index 3141f049..336b8b73 100755 --- a/assets/src/server/server.py +++ b/assets/src/server/server.py @@ -34,7 +34,7 @@ import traceback from typing import TYPE_CHECKING if TYPE_CHECKING: - from typing import Dict, Any, Sequence + from typing import Dict, Any, Sequence, Optional def _get_default_config() -> Dict[str, Any]: @@ -176,7 +176,8 @@ def _run_process_until_exit(process: subprocess.Popen, process.stdin.flush() config_dirty = False - code = process.poll() + code: Optional[int] = process.poll() + if code is not None: print('BallisticaCore exited with code ' + str(code)) break diff --git a/docs/ba_module.md b/docs/ba_module.md index 37a18cf8..42ce6af6 100644 --- a/docs/ba_module.md +++ b/docs/ba_module.md @@ -4270,7 +4270,7 @@ session.set_activity(foo) and then ba.newnode

set_activity()

-

set_activity(self, activity: ba.Activity) -> None

+

set_activity(self, activity: Optional[ba.Activity]) -> None

Set the current activity for this instance.

diff --git a/tools/efrotools/code.py b/tools/efrotools/code.py index edaea818..e3dd2837 100644 --- a/tools/efrotools/code.py +++ b/tools/efrotools/code.py @@ -467,8 +467,7 @@ def _apply_pylint_run_to_cache(projroot: Path, run: Any, dirtyfiles: List[str], # Let's print a list of modules with no detected deps so we can make sure # this is behaving. if no_deps_modules: - # noinspection PyUnreachableCode - if False: # pylint: disable=using-constant-test + if bool(False): print('NOTE: no dependencies found for:', ', '.join(no_deps_modules)) @@ -487,7 +486,7 @@ def _apply_pylint_run_to_cache(projroot: Path, run: Any, dirtyfiles: List[str], mname2 = paths_to_names.get(fname) if mname2 is None: raise Exception('unable to get module name for "' + fname + '"') - counts = (None if mname2 is None else stats_by_module.get(mname2)) + counts = stats_by_module.get(mname2) # 'statement' count seems to be new and always non-zero; ignore it if counts is not None: @@ -645,10 +644,12 @@ def _run_idea_inspections(projroot: Path, if result.returncode != 0: # In verbose mode this stuff got printed already. if not verbose: - stdout = (result.stdout.decode() if isinstance( - result.stdout, bytes) else str(result.stdout)) - stderr = (result.stderr.decode() if isinstance( - result.stdout, bytes) else str(result.stdout)) + stdout = ( + result.stdout.decode() if isinstance( # type: ignore + result.stdout, bytes) else str(result.stdout)) + stderr = ( + result.stderr.decode() if isinstance( # type: ignore + result.stdout, bytes) else str(result.stdout)) print(f'{displayname} inspection failure stdout:\n{stdout}' + f'{displayname} inspection failure stderr:\n{stderr}') raise RuntimeError(f"{displayname} inspection failed.") diff --git a/tools/efrotools/snippets.py b/tools/efrotools/snippets.py index d4f982c3..fd2d3270 100644 --- a/tools/efrotools/snippets.py +++ b/tools/efrotools/snippets.py @@ -317,6 +317,7 @@ def tool_config_install() -> None: warn_unused_ignores = True warn_return_any = True warn_redundant_casts = True + warn_unreachable=True disallow_incomplete_defs = True disallow_untyped_defs = True disallow_untyped_decorators = True