Replace some isinstance calls with TypeGuard.

These aren't as ergonomic as I'd hoped because of
https://www.python.org/dev/peps/pep-0647/#narrowing-of-implicit-self-and-cls-parameters.

I added a decorator `@self_type_guard` so we can avoid needing to import
the descendent types in the typeguard implementation (which wouldn't fix
any circular imports, just move them).
This commit is contained in:
Dan Albert
2022-02-12 14:57:33 -08:00
parent 85e7b1762d
commit 2e901f3586
5 changed files with 57 additions and 7 deletions

View File

@@ -13,7 +13,15 @@ import random
from dataclasses import dataclass, field
from datetime import timedelta
from functools import cached_property
from typing import Iterator, List, Optional, Set, TYPE_CHECKING, Tuple
from typing import (
Iterator,
List,
Optional,
Set,
TYPE_CHECKING,
Tuple,
TypeGuard,
)
from dcs.mapping import Point
from dcs.unit import Unit
@@ -42,6 +50,7 @@ from game.theater.theatergroundobject import (
EwrGroundObject,
NavalGroundObject,
)
from game.typeguard import self_type_guard
from game.utils import Distance, Heading, Speed, feet, knots, meters, nautical_miles
from .closestairfields import ObjectiveDistanceCache
from .traveltime import GroundSpeed, TravelTime
@@ -320,6 +329,18 @@ class FlightPlan:
"""The time that the mission is complete and the flight RTBs."""
raise NotImplementedError
@self_type_guard
def is_loiter(self, flight_plan: FlightPlan) -> TypeGuard[LoiterFlightPlan]:
return False
@self_type_guard
def is_patrol(self, flight_plan: FlightPlan) -> TypeGuard[PatrollingFlightPlan]:
return False
@self_type_guard
def is_formation(self, flight_plan: FlightPlan) -> TypeGuard[FormationFlightPlan]:
return False
@dataclass(frozen=True)
class LoiterFlightPlan(FlightPlan):
@@ -357,6 +378,10 @@ class LoiterFlightPlan(FlightPlan):
def mission_departure_time(self) -> timedelta:
raise NotImplementedError
@self_type_guard
def is_loiter(self, flight_plan: FlightPlan) -> TypeGuard[LoiterFlightPlan]:
return True
@dataclass(frozen=True)
class FormationFlightPlan(LoiterFlightPlan):
@@ -442,6 +467,10 @@ class FormationFlightPlan(LoiterFlightPlan):
def mission_departure_time(self) -> timedelta:
return self.split_time
@self_type_guard
def is_formation(self, flight_plan: FlightPlan) -> TypeGuard[FormationFlightPlan]:
return True
@dataclass(frozen=True)
class PatrollingFlightPlan(FlightPlan):
@@ -498,6 +527,10 @@ class PatrollingFlightPlan(FlightPlan):
def mission_departure_time(self) -> timedelta:
return self.patrol_end_time
@self_type_guard
def is_patrol(self, flight_plan: FlightPlan) -> TypeGuard[PatrollingFlightPlan]:
return True
@dataclass(frozen=True)
class BarCapFlightPlan(PatrollingFlightPlan):