mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
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:
@@ -12,7 +12,6 @@ from game.ato.flightwaypoint import FlightWaypoint
|
||||
from game.ato.flightwaypointtype import FlightWaypointType
|
||||
from game.ato.starttype import StartType
|
||||
from game.utils import Distance, LBS_TO_KG, Speed, pairwise
|
||||
from gen.flights.flightplan import LoiterFlightPlan
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from game.ato.flight import Flight
|
||||
@@ -44,7 +43,7 @@ class InFlight(FlightState, ABC):
|
||||
# at a loiter point but still a regular InFlight (Loiter overrides this
|
||||
# method) that means we're traveling from the loiter point but no longer
|
||||
# loitering.
|
||||
assert isinstance(self.flight.flight_plan, LoiterFlightPlan)
|
||||
assert self.flight.flight_plan.is_loiter(self.flight.flight_plan)
|
||||
travel_time -= self.flight.flight_plan.hold_duration
|
||||
return travel_time
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ from dcs import Point
|
||||
from game.ato.flightstate import FlightState, InFlight
|
||||
from game.ato.flightstate.navigating import Navigating
|
||||
from game.utils import Distance, Speed
|
||||
from gen.flights.flightplan import LoiterFlightPlan
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from game.ato.flight import Flight
|
||||
@@ -17,7 +16,7 @@ if TYPE_CHECKING:
|
||||
|
||||
class Loiter(InFlight):
|
||||
def __init__(self, flight: Flight, settings: Settings, waypoint_index: int) -> None:
|
||||
assert isinstance(flight.flight_plan, LoiterFlightPlan)
|
||||
assert flight.flight_plan.is_loiter(flight.flight_plan)
|
||||
self.hold_duration = flight.flight_plan.hold_duration
|
||||
super().__init__(flight, settings, waypoint_index)
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ from game.ato import FlightType
|
||||
from game.ato.flightstate import InFlight
|
||||
from game.threatzones import ThreatPoly
|
||||
from game.utils import Distance, Speed, dcs_to_shapely_point
|
||||
from gen.flights.flightplan import PatrollingFlightPlan
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from game.ato.flight import Flight
|
||||
@@ -19,7 +18,7 @@ if TYPE_CHECKING:
|
||||
|
||||
class RaceTrack(InFlight):
|
||||
def __init__(self, flight: Flight, settings: Settings, waypoint_index: int) -> None:
|
||||
assert isinstance(flight.flight_plan, PatrollingFlightPlan)
|
||||
assert flight.flight_plan.is_patrol(flight.flight_plan)
|
||||
self.patrol_duration = flight.flight_plan.patrol_duration
|
||||
super().__init__(flight, settings, waypoint_index)
|
||||
self.commit_region = LineString(
|
||||
|
||||
20
game/typeguard.py
Normal file
20
game/typeguard.py
Normal file
@@ -0,0 +1,20 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Callable, TypeGuard, TypeVar
|
||||
|
||||
SelfT = TypeVar("SelfT")
|
||||
BaseT = TypeVar("BaseT")
|
||||
GuardT = TypeVar("GuardT")
|
||||
|
||||
|
||||
def self_type_guard(
|
||||
f: Callable[[SelfT, BaseT], TypeGuard[GuardT]]
|
||||
) -> Callable[[SelfT, BaseT], TypeGuard[GuardT]]:
|
||||
def decorator(s: SelfT, arg: BaseT) -> TypeGuard[GuardT]:
|
||||
if id(s) != id(arg):
|
||||
raise ValueError(
|
||||
"self type guards must be called with self as the argument"
|
||||
)
|
||||
return f(s, arg)
|
||||
|
||||
return decorator
|
||||
Reference in New Issue
Block a user