From 04d6cf3b5e82ec9c9f36ef266affb0d39ac0da59 Mon Sep 17 00:00:00 2001 From: Cal Corum Date: Mon, 9 Mar 2026 12:48:07 -0500 Subject: [PATCH] fix: replace star imports with explicit named imports across codebase MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert all `from x import *` to explicit imports in 12 files, resolving 925 F403/F405 ruff violations. Each name traced to its canonical source module. Also fixes: duplicate Session import (players.py), missing sample_team_data fixture param, duplicate method name paperdex_cardset_slash, unused commands import in package __init__ files, and Play type hint in play_lock.py. 3 pre-existing code bugs remain (F811 duplicate test names, F821 undefined `question` variable) — these need investigation, not mechanical fixes. Co-Authored-By: Claude Opus 4.6 --- cogs/admins.py | 19 ++- cogs/economy.py | 94 ++++++++++-- cogs/economy_new/__init__.py | 1 - cogs/gameplay.py | 9 +- cogs/players.py | 9 +- cogs/players_new/__init__.py | 1 - command_logic/logic_gameplay.py | 23 ++- db_calls_gameplay.py | 14 +- gauntlets.py | 2 +- helpers.py | 34 +++- helpers/__init__.py | 145 ++++++++++++++++-- helpers/main.py | 21 ++- in_game/ai_manager.py | 2 +- in_game/gameplay_models.py | 10 +- play_lock.py | 7 + .../players_refactor/test_team_management.py | 2 +- utilities/buttons.py | 2 +- 17 files changed, 339 insertions(+), 56 deletions(-) diff --git a/cogs/admins.py b/cogs/admins.py index 889e081..f30667c 100644 --- a/cogs/admins.py +++ b/cogs/admins.py @@ -1,15 +1,28 @@ import csv import json +import logging +import random +import discord import db_calls_gameplay +from typing import Literal, Optional from gauntlets import evolve_pokemon -from helpers import * from discord import Member from discord.ext import commands from discord import app_commands -from api_calls import * -from helpers import * +from api_calls import db_get, db_patch, db_post, team_hash +from discord_ui import Dropdown, DropdownView +from helpers.discord_utils import get_emoji, send_to_channel +from helpers.main import ( + get_blank_team_card, + get_card_embeds, + get_sheets, + get_team_by_owner, + player_desc, +) +from helpers.random_content import random_conf_gif, random_gif, random_no_gif +from helpers.utils import owner_only import in_game from in_game import ai_manager from in_game.gameplay_models import ( diff --git a/cogs/economy.py b/cogs/economy.py index 840699c..b8e1309 100644 --- a/cogs/economy.py +++ b/cogs/economy.py @@ -1,18 +1,88 @@ import copy - -import helpers -from helpers import * +import datetime import os import random - -import discord -from discord.ext import commands, tasks -from discord import app_commands, Member from typing import Optional -import datetime -from api_calls import db_get, db_post, db_patch, db_delete, get_team_by_abbrev -from help_text import * +import discord +from discord import app_commands, Member +from discord.ext import commands, tasks + +import helpers +from api_calls import ( + db_get, + db_post, + db_patch, + db_delete, + get_team_by_abbrev, + team_hash, +) +from discord_ui.confirmations import ButtonOptions, Confirm, Question +from discord_ui.selectors import ( + SelectBuyPacksCardset, + SelectBuyPacksTeam, + SelectOpenPack, + SelectView, +) +from help_text import ( + HELP_ENDGAME, + HELP_GAMEMODES, + HELP_NEWGAME, + HELP_PLAYGAME, + HELP_REWARDS_MONEY, + HELP_REWARDS_PREMIUM, + HELP_REWARDS_SHOP, + HELP_REWARDS_STANDARD, + HELP_SHEET_SCRIPTS, + HELP_START_HOW, + HELP_START_PLAY, + HELP_START_WHAT, + HELP_TS_DASH, + HELP_TS_MARKET, + HELP_TS_MENU, + HELP_TS_ROSTER, + SHEET_SHARE_STEPS, +) +from helpers.constants import ( + ALL_MLB_TEAMS, + IMAGES, + LIVE_CARDSET_ID, + PD_PLAYERS, + PD_PLAYERS_ROLE_NAME, + normalize_franchise, +) +from helpers.discord_utils import ( + get_channel, + get_emoji, + get_or_create_role, + get_team_embed, + logger, + send_to_channel, +) +from helpers.main import ( + app_legal_channel, + cardset_search, + confirm_pack_purchase, + display_cards, + get_all_pos, + get_blank_team_card, + get_card_embeds, + get_role, + get_sheets, + get_team_by_owner, + get_test_pack, + give_cards_to_team, + give_packs, + image_embed, + legal_channel, + post_ratings_guide, + refresh_sheet, + roll_for_cards, + share_channel, + team_summary_embed, +) +from helpers.search_utils import fuzzy_search +from helpers.utils import get_cal_user, get_roster_sheet, int_timestamp # date = f'{datetime.datetime.now().year}-{datetime.datetime.now().month}-{datetime.datetime.now().day}' # logger.basicConfig( @@ -2051,9 +2121,7 @@ class Economy(commands.Cog): for x in p_query["paperdex"]: await db_delete("paperdex", object_id=x["id"]) - await msg.edit( - content="All done with paperdex. Now I'll wipe out your team..." - ) + await msg.edit(content="All done with paperdex. Now I'll wipe out your team...") if db_delete("teams", object_id=team["id"]): await msg.edit(content="All done!") diff --git a/cogs/economy_new/__init__.py b/cogs/economy_new/__init__.py index 947bb25..54ddf75 100644 --- a/cogs/economy_new/__init__.py +++ b/cogs/economy_new/__init__.py @@ -11,7 +11,6 @@ # Economy Package - Shared imports only for setup function import logging -from discord.ext import commands async def setup(bot): diff --git a/cogs/gameplay.py b/cogs/gameplay.py index 8b8bfa6..89cc5f7 100644 --- a/cogs/gameplay.py +++ b/cogs/gameplay.py @@ -53,7 +53,14 @@ from command_logic.logic_gameplay import ( ) from command_logic.play_context import locked_play from dice import ab_roll -from exceptions import * +from exceptions import ( + GameException, + GameNotFoundException, + LineupsMissingException, + PlayNotFoundException, + PositionNotFoundException, + log_exception, +) import gauntlets from helpers import ( CARDSETS, diff --git a/cogs/players.py b/cogs/players.py index 26f9ef4..7c7adc7 100644 --- a/cogs/players.py +++ b/cogs/players.py @@ -16,13 +16,8 @@ from sqlmodel import Session import gauntlets import helpers -# import in_game.data_cache -# import in_game.simulations -# import in_game -# # from in_game import data_cache, simulations -# from in_game.data_cache import get_pd_pitchingcard, get_pd_battingcard, get_pd_player from in_game.gameplay_queries import get_team_or_none -from in_game.gameplay_models import Session, engine +from in_game.gameplay_models import engine from api_calls import db_get, db_post, db_patch, get_team_by_abbrev from helpers import ( ACTIVE_EVENT_LITERAL, @@ -989,7 +984,7 @@ class Players(commands.Cog): ) @commands.has_any_role(PD_PLAYERS_ROLE_NAME) @commands.check(legal_channel) - async def paperdex_cardset_slash(self, interaction: discord.Interaction): + async def paperdex_team_slash(self, interaction: discord.Interaction): team = await get_team_by_owner(interaction.user.id) if not team: await interaction.response.send_message( diff --git a/cogs/players_new/__init__.py b/cogs/players_new/__init__.py index 7797168..28ac27c 100644 --- a/cogs/players_new/__init__.py +++ b/cogs/players_new/__init__.py @@ -3,7 +3,6 @@ from .shared_utils import get_ai_records, get_record_embed, get_record_embed_legacy import logging -from discord.ext import commands __all__ = ["get_ai_records", "get_record_embed", "get_record_embed_legacy"] diff --git a/command_logic/logic_gameplay.py b/command_logic/logic_gameplay.py index 703f05a..4a463b6 100644 --- a/command_logic/logic_gameplay.py +++ b/command_logic/logic_gameplay.py @@ -10,7 +10,26 @@ from typing import Literal from api_calls import db_delete, db_get, db_post from dice import d_twenty_roll, frame_plate_check, sa_fielding_roll -from exceptions import * +from exceptions import ( + CardLegalityException, + CardNotFoundException, + DatabaseError, + GameException, + GameNotFoundException, + GoogleSheetsException, + InvalidResultException, + LineupsMissingException, + log_errors, + log_exception, + MissingRosterException, + NoPlayerResponseException, + PlayerNotFoundException, + PlayInitException, + PlayLockedException, + PlayNotFoundException, + PositionNotFoundException, + TeamNotFoundException, +) from gauntlets import post_result from helpers import ( COLORS, @@ -1286,8 +1305,6 @@ async def checks_log_interaction( f"{interaction.user.name} attempted {command_name} on locked play {this_play.id} " f"in game {this_game.id}. Rejecting duplicate submission." ) - from exceptions import PlayLockedException - raise PlayLockedException( "This play is already being processed. Please wait for the current action to complete.\n\n" "If this play appears stuck, go call dad." diff --git a/db_calls_gameplay.py b/db_calls_gameplay.py index e62cee6..8c9aaf0 100644 --- a/db_calls_gameplay.py +++ b/db_calls_gameplay.py @@ -5,7 +5,19 @@ import requests import pydantic from typing import Optional -from peewee import * +from peewee import ( + BooleanField, + CharField, + DatabaseError, + DateTimeField, + DoesNotExist, + FloatField, + fn, + ForeignKeyField, + IntegerField, + Model, + SqliteDatabase, +) from playhouse.shortcuts import model_to_dict from dataclasses import dataclass diff --git a/gauntlets.py b/gauntlets.py index f60d854..bc83945 100644 --- a/gauntlets.py +++ b/gauntlets.py @@ -7,7 +7,7 @@ import discord from sqlmodel import Session from discord import SelectOption -from exceptions import * +from exceptions import log_exception, PlayerNotFoundException from in_game import ai_manager import helpers from helpers import RARITY, get_or_create_role, send_to_channel, get_channel diff --git a/helpers.py b/helpers.py index 997c44d..b6fd67b 100644 --- a/helpers.py +++ b/helpers.py @@ -7,21 +7,43 @@ import random import discord import requests from discord.ext import commands -from api_calls import * +from api_calls import ( + db_get, + db_patch, + db_post, + logger, + team_hash, +) from bs4 import BeautifulSoup from typing import Optional, Union, List from in_game.gameplay_models import Team -from constants import * -from discord_ui import * -from random_content import * +from constants import ( + IMAGES, + LIVE_CARDSET_ID, + PD_SEASON, + PKMN_REF_URL, + RATINGS_BATTER_FORMULA, + RATINGS_PITCHER_FORMULA, + RATINGS_SHEET_KEY, + SBA_COLOR, +) +from discord_ui import ( + Confirm, + Pagination, +) from utils import ( get_roster_sheet, get_cal_user, ) -from search_utils import * -from discord_utils import * +from search_utils import fuzzy_search +from discord_utils import ( + get_channel, + get_emoji, + get_or_create_role, + get_team_embed, +) async def get_player_photo(player): diff --git a/helpers/__init__.py b/helpers/__init__.py index 8c7e39d..420ae45 100644 --- a/helpers/__init__.py +++ b/helpers/__init__.py @@ -17,14 +17,141 @@ Modules: - players: Player-related utilities (future) """ -# Import all functions from the original helpers.py to maintain backward compatibility -# This allows existing code to continue working during the migration -from helpers.main import * +# Re-export all public names for backward compatibility. +# Other modules do `from helpers import some_name`. +from helpers.main import ( # noqa: F401 + get_player_photo, + get_player_headshot, + get_team_by_owner, + team_role, + get_all_pos, + share_channel, + get_card_embeds, + image_embed, + is_shiny, + display_cards, + embed_pagination, + get_test_pack, + roll_for_cards, + give_packs, + get_sheets, + create_team_sheet, + refresh_sheet, + delete_sheet, + share_sheet, + get_blank_team_card, + get_rosters, + get_roster_lineups, + post_ratings_guide, + legal_channel, + app_legal_channel, + is_ephemeral_channel, + is_restricted_channel, + can_send_message, + send_safe_message, + get_role, + team_summary_embed, + give_cards_to_team, + get_ratings_guide, + paperdex_cardset_embed, + paperdex_team_embed, + get_pack_cover, + open_st_pr_packs, + get_choice_from_cards, + open_choice_pack, + confirm_pack_purchase, + player_desc, + player_pcard, + player_bcard, +) # Import from migrated modules -from .constants import * -from .utils import * -from .random_content import * -from .search_utils import * -from .discord_utils import * -from .scouting import * +from .constants import ( # noqa: F401 + SBA_SEASON, + PD_SEASON, + ranked_cardsets, + LIVE_CARDSET_ID, + LIVE_PROMO_CARDSET_ID, + MAX_CARDSET_ID, + CARDSETS, + SBA_COLOR, + PD_PLAYERS, + SBA_PLAYERS_ROLE_NAME, + PD_PLAYERS_ROLE_NAME, + ALL_CARDSET_NAMES, + PD_IMAGE_BUCKET, + PKMN_REF_URL, + RATINGS_BATTER_FORMULA, + RATINGS_PITCHER_FORMULA, + RATINGS_SHEET_KEY, + ALL_MLB_TEAMS, + FRANCHISE_NORMALIZE, + normalize_franchise, + IMAGES, + INFIELD_X_CHART, + OUTFIELD_X_CHART, + RARITY, + SELECT_CARDSET_OPTIONS, + ACTIVE_EVENT_LITERAL, + DEFENSE_LITERAL, + DEFENSE_NO_PITCHER_LITERAL, + COLORS, + INSULTS, +) +from .utils import ( # noqa: F401 + int_timestamp, + midnight_timestamp, + get_pos_abbrev, + position_name_to_abbrev, + user_has_role, + get_roster_sheet_legacy, + get_roster_sheet, + get_player_url, + owner_only, + get_context_user, + get_cal_user, +) +from .random_content import ( # noqa: F401 + random_conf_gif, + random_no_gif, + random_salute_gif, + random_conf_word, + random_codename, + random_no_phrase, + random_gif, + random_from_list, + random_insult, +) +from .search_utils import ( # noqa: F401 + fuzzy_search, + fuzzy_player_search, + cardset_search, +) +from .discord_utils import ( # noqa: F401 + send_to_bothole, + send_to_news, + typing_pause, + pause_then_type, + check_if_pdhole, + bad_channel, + get_channel, + get_emoji, + react_and_reply, + send_to_channel, + get_or_create_role, + get_special_embed, + get_random_embed, + get_team_embed, + create_channel_old, + create_channel, +) +from .scouting import ( # noqa: F401 + SCOUT_TOKENS_PER_DAY, + SCOUT_WINDOW_SECONDS, + SCOUTABLE_PACK_TYPES, + RARITY_SYMBOLS, + get_scout_tokens_used, + build_scout_embed, + build_scouted_card_list, + create_scout_opportunity, +) diff --git a/helpers/main.py b/helpers/main.py index 9823183..edbe9cf 100644 --- a/helpers/main.py +++ b/helpers/main.py @@ -7,21 +7,30 @@ import random import discord import aiohttp from discord.ext import commands -from api_calls import * +import requests +from api_calls import db_get, db_patch, db_post, team_hash, logger from bs4 import BeautifulSoup from typing import Optional, Union, List from in_game.gameplay_models import Team -from constants import * -from discord_ui import * -from random_content import * +from constants import ( + IMAGES, + LIVE_CARDSET_ID, + PD_SEASON, + PKMN_REF_URL, + RATINGS_BATTER_FORMULA, + RATINGS_PITCHER_FORMULA, + RATINGS_SHEET_KEY, + SBA_COLOR, +) +from discord_ui import Confirm, Pagination from utils import ( get_roster_sheet, get_cal_user, ) -from search_utils import * -from discord_utils import * +from search_utils import fuzzy_search +from discord_utils import get_channel, get_emoji, get_or_create_role, get_team_embed async def get_player_photo(player): diff --git a/in_game/ai_manager.py b/in_game/ai_manager.py index 58c20d8..3fcc23d 100644 --- a/in_game/ai_manager.py +++ b/in_game/ai_manager.py @@ -18,7 +18,7 @@ from db_calls_gameplay import ( get_one_game, ) from api_calls import db_get, db_post -from peewee import * +from peewee import CharField, IntegerField, Model, SqliteDatabase from in_game import data_cache from in_game.gameplay_models import Play, Session, Game, Team, Lineup diff --git a/in_game/gameplay_models.py b/in_game/gameplay_models.py index 07648a4..ecd84ce 100644 --- a/in_game/gameplay_models.py +++ b/in_game/gameplay_models.py @@ -19,7 +19,15 @@ from sqlmodel import ( ) from sqlalchemy import Column, func -from exceptions import * +from exceptions import ( + CardNotFoundException, + GameException, + LineupsMissingException, + MultipleHumanTeamsException, + NoHumanTeamsException, + PlayInitException, + log_exception, +) from in_game.managerai_responses import ( DefenseResponse, JumpResponse, diff --git a/play_lock.py b/play_lock.py index cb046f4..e079d11 100644 --- a/play_lock.py +++ b/play_lock.py @@ -4,10 +4,17 @@ Play locking utilities to prevent concurrent play modifications. This module is separate to avoid circular imports between logic_gameplay and utilities. """ +from __future__ import annotations + import logging from contextlib import contextmanager +from typing import TYPE_CHECKING + from sqlmodel import Session +if TYPE_CHECKING: + from in_game.gameplay_models import Play + logger = logging.getLogger("discord_app") diff --git a/tests/players_refactor/test_team_management.py b/tests/players_refactor/test_team_management.py index e790a3a..11429b9 100644 --- a/tests/players_refactor/test_team_management.py +++ b/tests/players_refactor/test_team_management.py @@ -331,7 +331,7 @@ class TestTeamManagement: @patch("helpers.get_team_by_owner") async def test_pullroster_command_no_sheet( - self, mock_get_by_owner, team_management_cog, mock_interaction + self, mock_get_by_owner, team_management_cog, mock_interaction, sample_team_data ): """Test roster pull when team has no Google Sheet configured.""" team_data_no_sheet = {**sample_team_data, "gsheet": None} diff --git a/utilities/buttons.py b/utilities/buttons.py index 5109ff1..5f87a04 100644 --- a/utilities/buttons.py +++ b/utilities/buttons.py @@ -3,7 +3,7 @@ import discord from typing import Literal from dice import ab_roll, jump_roll -from exceptions import * +from exceptions import ButtonOptionNotChosen, InvalidResponder, log_exception from helpers import random_insult from in_game.gameplay_models import Play