Files
dependabot[bot] c0e2a1b738 Bump pyrefly from 0.44.0 to 0.45.0 in /backend (#1461)
Bumps [pyrefly](https://github.com/facebook/pyrefly) from 0.44.0 to
0.45.0.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="93cacf99df"><code>93cacf9</code></a>
Update pyrefly version]</li>
<li><a
href="9ed447ce33"><code>9ed447c</code></a>
special-case numba.jit and numba.njit to preserve decorated function
signatures</li>
<li><a
href="495e7dcfaf"><code>495e7dc</code></a>
Remove Arc from HeavyTaskQueue</li>
<li><a
href="e34715c8b9"><code>e34715c</code></a>
Remove Arc from connection and lsp_queue</li>
<li><a
href="361ad739f1"><code>361ad73</code></a>
Borrow in server threads</li>
<li><a
href="f2482475e5"><code>f248247</code></a>
Run server threads in a thread scope</li>
<li><a
href="87cfca7e60"><code>87cfca7</code></a>
Stop listening for LSP requests after Exit notification</li>
<li><a
href="7f485246d8"><code>7f48524</code></a>
Move Pydantic lax mode into its own file</li>
<li><a
href="40759d7b44"><code>40759d7</code></a>
regression test for lazy class attr init</li>
<li><a
href="3f263a0470"><code>3f263a0</code></a>
Move suggest.rs into the pyrefly_util crate</li>
<li>Additional commits viewable in <a
href="https://github.com/facebook/pyrefly/compare/0.44.0...0.45.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pyrefly&package-manager=uv&previous-version=0.44.0&new-version=0.45.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Erik Vroon <erik.vroon@channable.com>
2025-12-09 12:24:57 +00:00

202 lines
7.2 KiB
Python

from collections.abc import AsyncIterator
from contextlib import asynccontextmanager
from typing import cast
from pydantic import BaseModel
from sqlalchemy import Table
from bracket.database import database
from bracket.models.db.club import Club, ClubInsertable
from bracket.models.db.court import Court, CourtInsertable
from bracket.models.db.match import Match, MatchInsertable
from bracket.models.db.player import Player, PlayerInsertable
from bracket.models.db.player_x_team import PlayerXTeamInsertable
from bracket.models.db.ranking import Ranking, RankingInsertable
from bracket.models.db.round import Round, RoundInsertable
from bracket.models.db.stage import Stage, StageInsertable
from bracket.models.db.stage_item import StageItem, StageItemInsertable
from bracket.models.db.stage_item_inputs import (
StageItemInputBase,
StageItemInputEmpty,
StageItemInputFinal,
StageItemInputInsertable,
)
from bracket.models.db.team import Team, TeamInsertable
from bracket.models.db.tournament import Tournament, TournamentInsertable
from bracket.models.db.user import UserBase, UserInDB
from bracket.models.db.user_x_club import UserXClub, UserXClubInsertable, UserXClubRelation
from bracket.schema import (
clubs,
courts,
matches,
players,
players_x_teams,
rankings,
rounds,
stage_item_inputs,
stage_items,
stages,
teams,
tournaments,
users,
users_x_clubs,
)
from bracket.sql.teams import get_teams_by_id
from bracket.utils.db import insert_generic
from bracket.utils.dummy_records import DUMMY_CLUB, DUMMY_RANKING1, DUMMY_TOURNAMENT
from bracket.utils.id_types import TeamId
from tests.integration_tests.mocks import get_mock_token, get_mock_user
from tests.integration_tests.models import AuthContext
async def assert_row_count_and_clear(table: Table, expected_rows: int) -> None:
# assert len(await database.fetch_all(query=table.select())) == expected_rows
await database.execute(query=table.delete())
@asynccontextmanager
async def inserted_generic[BaseModelT: BaseModel](
data_model: BaseModelT, table: Table, return_type: type[BaseModelT]
) -> AsyncIterator[BaseModelT]:
last_record_id, row_inserted = await insert_generic(database, data_model, table, return_type)
try:
yield row_inserted
finally:
await database.execute(query=table.delete().where(table.c.id == last_record_id))
@asynccontextmanager
async def inserted_user(user: UserBase) -> AsyncIterator[UserInDB]:
async with inserted_generic(user, users, UserInDB) as row_inserted:
yield cast("UserInDB", row_inserted)
@asynccontextmanager
async def inserted_club(club: ClubInsertable) -> AsyncIterator[Club]:
async with inserted_generic(club, clubs, Club) as row_inserted:
yield cast("Club", row_inserted)
@asynccontextmanager
async def inserted_tournament(tournament: TournamentInsertable) -> AsyncIterator[Tournament]:
async with inserted_generic(tournament, tournaments, Tournament) as row_inserted:
yield cast("Tournament", row_inserted)
@asynccontextmanager
async def inserted_team(team: TeamInsertable) -> AsyncIterator[Team]:
async with inserted_generic(team, teams, Team) as row_inserted:
yield cast("Team", row_inserted)
@asynccontextmanager
async def inserted_court(court: CourtInsertable) -> AsyncIterator[Court]:
async with inserted_generic(court, courts, Court) as row_inserted:
yield cast("Court", row_inserted)
@asynccontextmanager
async def inserted_ranking(ranking: RankingInsertable) -> AsyncIterator[Ranking]:
async with inserted_generic(ranking, rankings, Ranking) as row_inserted:
yield cast("Ranking", row_inserted)
@asynccontextmanager
async def inserted_player(player: PlayerInsertable) -> AsyncIterator[Player]:
async with inserted_generic(player, players, Player) as row_inserted:
yield cast("Player", row_inserted)
@asynccontextmanager
async def inserted_player_in_team(
player: PlayerInsertable, team_id: TeamId
) -> AsyncIterator[Player]:
async with inserted_generic(player, players, Player) as row_inserted:
async with inserted_generic(
PlayerXTeamInsertable(player_id=cast("Player", row_inserted).id, team_id=team_id),
players_x_teams,
PlayerXTeamInsertable,
):
yield cast("Player", row_inserted)
@asynccontextmanager
async def inserted_stage(stage: StageInsertable) -> AsyncIterator[Stage]:
async with inserted_generic(stage, stages, Stage) as row_inserted:
yield cast("Stage", row_inserted)
@asynccontextmanager
async def inserted_stage_item(stage_item: StageItemInsertable) -> AsyncIterator[StageItem]:
async with inserted_generic(stage_item, stage_items, StageItem) as row_inserted:
yield StageItem(**row_inserted.model_dump())
@asynccontextmanager
async def inserted_stage_item_input(
stage_item_input: StageItemInputInsertable,
) -> AsyncIterator[StageItemInputFinal | StageItemInputEmpty]:
async with inserted_generic(
stage_item_input,
stage_item_inputs,
StageItemInputBase, # pyrefly: ignore[bad-argument-type]
) as row_inserted:
if stage_item_input.team_id is not None:
[team] = await get_teams_by_id(
{stage_item_input.team_id}, stage_item_input.tournament_id
)
yield StageItemInputFinal.model_validate(
row_inserted.model_dump() | {"team": team, "team_id": team.id}
)
else:
yield StageItemInputEmpty.model_validate(row_inserted.model_dump())
@asynccontextmanager
async def inserted_round(round_: RoundInsertable) -> AsyncIterator[Round]:
async with inserted_generic(round_, rounds, Round) as row_inserted:
yield cast("Round", row_inserted)
@asynccontextmanager
async def inserted_match(match: MatchInsertable) -> AsyncIterator[Match]:
async with inserted_generic(match, matches, Match) as row_inserted:
yield cast("Match", row_inserted)
@asynccontextmanager
async def inserted_user_x_club(user_x_club: UserXClubInsertable) -> AsyncIterator[UserXClub]:
async with inserted_generic(user_x_club, users_x_clubs, UserXClub) as row_inserted:
yield cast("UserXClub", row_inserted)
@asynccontextmanager
async def inserted_auth_context() -> AsyncIterator[AuthContext]:
mock_user = get_mock_user()
async with (
inserted_user(mock_user) as user_inserted,
inserted_club(DUMMY_CLUB) as club_inserted,
inserted_tournament(
DUMMY_TOURNAMENT.model_copy(update={"club_id": club_inserted.id})
) as tournament_inserted,
inserted_ranking(
DUMMY_RANKING1.model_copy(update={"tournament_id": tournament_inserted.id})
) as ranking_inserted,
inserted_user_x_club(
UserXClubInsertable(
user_id=user_inserted.id,
club_id=club_inserted.id,
relation=UserXClubRelation.OWNER,
)
) as user_x_club_inserted,
):
yield AuthContext(
headers={"Authorization": f"Bearer {get_mock_token(mock_user.email)}"},
user=user_inserted,
club=club_inserted,
tournament=tournament_inserted,
user_x_club=user_x_club_inserted,
ranking=ranking_inserted,
)