Skip to content

Commit

Permalink
The only mypy is now strict mypy.
Browse files Browse the repository at this point in the history
Fixes #6794.
  • Loading branch information
bakert committed Nov 12, 2019
1 parent 5423c38 commit 2fd534c
Show file tree
Hide file tree
Showing 49 changed files with 128 additions and 158 deletions.
13 changes: 7 additions & 6 deletions decksite/auth.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
from functools import wraps
from typing import Callable, Optional
from typing import Any, Callable, Dict, List, Optional, Tuple

from flask import redirect, request, session, url_for
from werkzeug import wrappers

from decksite.data import person


def login_required(f: Callable) -> Callable:
@wraps(f)
def decorated_function(*args, **kwargs):
def decorated_function(*args: List[Any], **kwargs: Dict[str, Any]) -> wrappers.Response:
if session.get('id') is None:
return redirect(url_for('authenticate', target=request.url))
return f(*args, **kwargs)
return decorated_function

def demimod_required(f: Callable) -> Callable:
@wraps(f)
def decorated_function(*args, **kwargs):
def decorated_function(*args: List[Any], **kwargs: Dict[str, Any]) -> wrappers.Response:
if session.get('admin') is None and session.get('demimod') is None:
return redirect(url_for('authenticate', target=request.url))
if session.get('admin') is False and session.get('demimod') is False:
Expand All @@ -26,7 +27,7 @@ def decorated_function(*args, **kwargs):

def admin_required(f: Callable) -> Callable:
@wraps(f)
def decorated_function(*args, **kwargs):
def decorated_function(*args: List[Any], **kwargs: Dict[str, Any]) -> wrappers.Response:
if session.get('admin') is None:
return redirect(url_for('authenticate', target=request.url))
if session.get('admin') is False:
Expand All @@ -36,7 +37,7 @@ def decorated_function(*args, **kwargs):

def admin_required_no_redirect(f: Callable) -> Callable:
@wraps(f)
def decorated_function(*args, **kwargs):
def decorated_function(*args: List[Any], **kwargs: Dict[str, Any]) -> Tuple[str, int]:
if not session.get('admin'):
return '', 403
return f(*args, **kwargs)
Expand Down Expand Up @@ -64,7 +65,7 @@ def hide_intro() -> bool:

def load_person(f: Callable) -> Callable:
@wraps(f)
def decorated_function(*args, **kwargs):
def decorated_function(*args: List[Any], **kwargs: Dict[str, Any]) -> Any:
if discord_id() is not None:
p = person.maybe_load_person_by_discord_id(discord_id())
if p:
Expand Down
4 changes: 2 additions & 2 deletions decksite/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import datetime
import functools
import os
from typing import Callable
from typing import Any, Callable, Dict, List

from flask import make_response, request
from werkzeug.contrib.cache import SimpleCache
Expand All @@ -29,7 +29,7 @@ def cached_impl(cacheable: bool = False,
"""
def decorator(f: Callable) -> Callable:
@functools.wraps(f)
def decorated_function(*args, **kwargs):
def decorated_function(*args: List[Any], **kwargs: Dict[str, Any]) -> Callable:
cache_key = key.format(id=request.full_path, locale=localization.get_locale()) # include querystring
cache_policy = ''
if not cacheable:
Expand Down
2 changes: 1 addition & 1 deletion decksite/data/person.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ def associate(d: deck.Deck, discord_id: int) -> int:
sql = 'UPDATE person SET discord_id = %s WHERE id = %s'
return db().execute(sql, [discord_id, person_id])

def is_allowed_to_retire(deck_id: int, discord_id: int) -> bool:
def is_allowed_to_retire(deck_id: Optional[int], discord_id: Optional[int]) -> bool:
if not deck_id:
return False
if not discord_id:
Expand Down
35 changes: 18 additions & 17 deletions decksite/league.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import json
import time
from enum import Enum
from typing import Any, Dict, List, Optional
from typing import Any, Dict, List, Optional, Set, Tuple

from flask import url_for
from werkzeug.datastructures import ImmutableMultiDict
Expand All @@ -12,6 +12,7 @@
from decksite.data.form import Form
from decksite.database import db
from magic import card, decklist, fetcher, legality, rotation
from magic.decklist import DecklistType
from magic.models import Deck
from shared import configuration, dtutil, guarantee, redis
from shared.container import Container
Expand Down Expand Up @@ -43,11 +44,11 @@ def __init__(self,
self.recent_decks.append({'name':d['name'], 'list':json.dumps(recent_deck)})
if mtgo_username is not None:
self.mtgo_username = mtgo_username
self.deck = None
self.card_errors: Dict[str, List[str]] = {}
self.card_warnings: Dict[str, List[str]] = {}
self.deck = Container()
self.card_errors: Dict[str, Set[str]] = {}
self.card_warnings: Dict[str, Set[str]] = {}

def do_validation(self):
def do_validation(self) -> None:
if len(self.mtgo_username) == 0:
self.errors['mtgo_username'] = 'Magic Online Username is required'
elif len(self.mtgo_username) > card.MAX_LEN_VARCHAR:
Expand All @@ -67,8 +68,8 @@ def do_validation(self):
self.url = url_for('competition', competition_id=self.competition_id, _external=True)
self.parse_and_validate_decklist()

def parse_and_validate_decklist(self):
self.decklist = self.decklist.strip()
def parse_and_validate_decklist(self) -> None:
self.decklist: str = self.decklist.strip()
if len(self.decklist) == 0:
self.errors['decklist'] = 'Decklist is required'
else:
Expand All @@ -78,8 +79,8 @@ def parse_and_validate_decklist(self):
if self.deck is not None:
self.check_deck_legality()

def parse_decklist(self):
self.cards = None
def parse_decklist(self) -> None:
self.cards: DecklistType = {}
if self.decklist.startswith('<?xml'):
try:
self.cards = decklist.parse_xml(self.decklist)
Expand All @@ -91,17 +92,17 @@ def parse_decklist(self):
except InvalidDataException as e:
self.errors['decklist'] = '{specific}. Try exporting from Magic Online as Text and pasting the result.'.format(specific=str(e))

def vivify_deck(self):
def vivify_deck(self) -> None:
try:
self.deck = decklist.vivify(self.cards)
except InvalidDataException as e:
self.errors['decklist'] = str(e)

def check_deck_legality(self):
errors: Dict[str, Dict[str, List[str]]] = {}
def check_deck_legality(self) -> None:
errors: Dict[str, Dict[str, Set[str]]] = {}
if 'Penny Dreadful' not in legality.legal_formats(self.deck, None, errors):
self.errors['decklist'] = ' '.join(errors.get('Penny Dreadful', {}).pop('Legality_General', ['Not a legal deck']))
self.card_errors = errors.get('Penny Dreadful')
self.card_errors = errors.get('Penny Dreadful', {})
banned_for_bugs = {c.name for c in self.deck.all_cards() if any([b.get('bannable', False) for b in c.bugs or []])}
playable_bugs = {c.name for c in self.deck.all_cards() if c.pd_legal and any([not b.get('bannable', False) for b in c.bugs or []])}
if len(banned_for_bugs) > 0:
Expand All @@ -113,7 +114,7 @@ def check_deck_legality(self):


class DeckCheckForm(SignUpForm):
def do_validation(self):
def do_validation(self) -> None:
self.parse_and_validate_decklist()
if len(self.errors) == 0:
self.validation_ok_message = 'The deck is legal'
Expand All @@ -140,7 +141,7 @@ def __init__(self,
{'text': 'Lose 0–2', 'value': '0–2', 'selected': self.get('result', None) == '0–2'},
]

def do_validation(self):
def do_validation(self) -> None:
self.id = self.entry
if len(self.entry) == 0:
self.errors['entry'] = 'Please select your deck'
Expand Down Expand Up @@ -171,7 +172,7 @@ def __init__(self,
if len(self.decks) == 0:
self.errors['entry'] = "You don't have any decks to retire"

def do_validation(self):
def do_validation(self) -> None:
if len(self.decks) == 0:
self.errors['entry'] = "You don't have any decks to retire"
elif len(self.entry) == 0:
Expand Down Expand Up @@ -289,7 +290,7 @@ def report(form: ReportForm) -> bool:
db().release_lock('deck_id:{id}'.format(id=form.opponent))
db().release_lock('deck_id:{id}'.format(id=form.entry))

def winner_and_loser(params):
def winner_and_loser(params: Container) -> Tuple[Optional[int], Optional[int]]:
if params.entry_games > params.opponent_games:
return (params.entry, params.opponent)
if params.opponent_games > params.entry_games:
Expand Down
4 changes: 2 additions & 2 deletions decksite/scrapers/tappedout.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import re
import urllib
from typing import Dict, List, Optional
from typing import Dict, List, Optional, Set

from bs4 import BeautifulSoup

Expand Down Expand Up @@ -93,7 +93,7 @@ def scrape_url(url: str) -> deck.Deck:
raw_deck.update(parse_printable(raw_deck)) # type: ignore
raw_deck = set_values(raw_deck)
vivified = decklist.vivify(raw_deck['cards'])
errors: Dict[str, Dict[str, List[str]]] = {}
errors: Dict[str, Dict[str, Set[str]]] = {}
if 'Penny Dreadful' not in legality.legal_formats(vivified, None, errors):
print(repr(raw_deck['cards']))
raise InvalidDataException('Deck is not legal in Penny Dreadful - {error}'.format(error=errors.get('Penny Dreadful')))
Expand Down
2 changes: 1 addition & 1 deletion decksite/views/about.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def __init__(self, src: Optional[str]) -> None:
self.cards = exciting_cards()
self.num_tournaments_title_case = self.num_tournaments().title()

def page_title(self):
def page_title(self) -> str:
return 'About Penny Dreadful'

def exciting_cards() -> List[Card]:
Expand Down
2 changes: 1 addition & 1 deletion decksite/views/achievements.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ def __init__(self, achievements: List[Container]) -> None:
a.has_leaderboard = True
self.show_seasons = True

def page_title(self):
def page_title(self) -> str:
return 'Achievements'
2 changes: 1 addition & 1 deletion decksite/views/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ def __init__(self, admin_menu: List[Dict[str, str]]) -> None:
super().__init__()
self.admin_menu = admin_menu

def page_title(self):
def page_title(self) -> str:
return 'Admin Menu'
4 changes: 2 additions & 2 deletions decksite/views/archetype.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List
from typing import Any, List

from flask import url_for

Expand Down Expand Up @@ -56,7 +56,7 @@ def og_url(self) -> str:
def og_description(self) -> str:
return 'Penny Dreadful {name} archetype'.format(name=self.archetype.name)

def __getattr__(self, attr):
def __getattr__(self, attr: str) -> Any:
return getattr(self.archetype, attr)

def page_title(self) -> str:
Expand Down
2 changes: 1 addition & 1 deletion decksite/views/archetypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,5 +91,5 @@ def convert(m: Container) -> Container:

self.num_archetypes = len([mu for mu in self.archetypes[0].matchups if mu.show_in_matchups_grid]) if self.archetypes else 0

def page_title(self):
def page_title(self) -> str:
return 'Archetypes'
2 changes: 1 addition & 1 deletion decksite/views/card.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,5 @@ def __init__(self, card: CardContainer, tournament_only: bool = False) -> None:
def __getattr__(self, attr: str) -> Any:
return getattr(self.card, attr)

def page_title(self):
def page_title(self) -> str:
return self.card.name
2 changes: 1 addition & 1 deletion decksite/views/cards.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,5 @@ def convert(c: Container) -> Container:
self.cards = [convert(c) for c in cards]
self.show_filters_toggle = True

def page_title(self):
def page_title(self) -> str:
return 'Cards'
4 changes: 2 additions & 2 deletions decksite/views/competition.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ def __init__(self, competition: Comp) -> None:
self.date = dtutil.display_date(competition.start_date)
self.sponsor_name = competition.sponsor_name

def __getattr__(self, attr):
def __getattr__(self, attr: str) -> Any:
return getattr(self.competition, attr)

def page_title(self):
def page_title(self) -> str:
return self.competition.name
2 changes: 1 addition & 1 deletion decksite/views/competitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ def __init__(self, competitions: List[Competition]) -> None:
self.competitions = competitions
self.show_seasons = True

def page_title(self):
def page_title(self) -> str:
return 'Competitions'
12 changes: 6 additions & 6 deletions decksite/views/deck.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Dict, Optional
from typing import Any, Dict, List, Optional

import inflect
import titlecase
Expand Down Expand Up @@ -85,7 +85,7 @@ def __getattr__(self, attr: str) -> Any:
def page_title(self) -> str:
return self.deck.name if self.public() else '(Active League Run)'

def sections(self):
def sections(self) -> List[Dict[str, Any]]:
sections = []
if self.creatures():
sections.append({'name': 'Creatures', 'entries': self.creatures(), 'num_entries': sum([c['n'] for c in self.creatures()])})
Expand All @@ -97,16 +97,16 @@ def sections(self):
sections.append({'name': 'Sideboard', 'entries': self.sideboard(), 'num_entries': sum([c['n'] for c in self.sideboard()])})
return sections

def creatures(self):
def creatures(self) -> List[Dict[str, Any]]:
return [entry for entry in self.deck.maindeck if entry.card.is_creature()]

def spells(self):
def spells(self) -> List[Dict[str, Any]]:
return [entry for entry in self.deck.maindeck if entry.card.is_spell()]

def lands(self):
def lands(self) -> List[Dict[str, Any]]:
return [entry for entry in self.deck.maindeck if entry.card.is_land()]

def sideboard(self):
def sideboard(self) -> List[Dict[str, Any]]:
return self.deck.sideboard

def public(self) -> bool:
Expand Down
2 changes: 1 addition & 1 deletion decksite/views/decks.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ def __init__(self, league_only: bool = False) -> None:
self.show_seasons = True
self.league_only = self.hide_top8 = self.show_omw = self.hide_source = league_only

def page_title(self):
def page_title(self) -> str:
deck_type = 'League ' if self.league_only else ''
return '{season_name} {deck_type}Decks'.format(season_name=self.season_name(), deck_type=deck_type)
2 changes: 1 addition & 1 deletion decksite/views/edit_aliases.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ def __init__(self, aliases: List[Container], all_people: Sequence[Person]) -> No
self.people = all_people
self.aliases = aliases

def page_title(self):
def page_title(self) -> str:
return 'Edit Aliases'
2 changes: 1 addition & 1 deletion decksite/views/edit_archetypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ def __init__(self, archetypes: List[Archetype], search_results: List[Deck], q: s
self.query = q
self.notquery = notq

def page_title(self):
def page_title(self) -> str:
return 'Edit Archetypes'
2 changes: 1 addition & 1 deletion decksite/views/edit_league.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ def __init__(self, status: Status) -> None:
self.action_display = 'Close' if is_open else 'Open'
self.action = self.action_display.lower()

def page_title(self):
def page_title(self) -> str:
return 'Edit League'
2 changes: 1 addition & 1 deletion decksite/views/edit_matches.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ def __init__(self, decks: List[Deck], matches: List[Container]) -> None:
else:
m.right_url = None

def page_title(self):
def page_title(self) -> str:
return 'Edit Matches'
2 changes: 1 addition & 1 deletion decksite/views/edit_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,5 @@ def __init__(self,
self.excluded_archetypes = excluded_archetype_info
self.has_excluded_archetypes = len(self.excluded_archetypes) > 0

def page_title(self):
def page_title(self) -> str:
return 'Edit Rules'
2 changes: 1 addition & 1 deletion decksite/views/faqs.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ def __init__(self) -> None:
super().__init__()
self.hide_intro = True # It has the same content as this page so don't repeat.

def page_title(self):
def page_title(self) -> str:
return 'Frequently Asked Questions'
4 changes: 2 additions & 2 deletions decksite/views/league_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ def __init__(self) -> None:
self.retire_url = url_for('retire')
self.bugs_url = url_for('tournaments', _anchor='bugs')

def page_title(self):
def page_title(self) -> str:
return 'League'

def discord_url(self):
def discord_url(self) -> str:
return 'https://discord.gg/Yekrz3s' # Invite directly into #league channel

def suffix(d: int) -> str:
Expand Down

0 comments on commit 2fd534c

Please sign in to comment.