From 3dc386d3222735da8d8dc62c6a1502ee9cfee9fe Mon Sep 17 00:00:00 2001 From: gamecss <52902973+gamecss@users.noreply.github.com> Date: Sun, 16 Apr 2023 10:58:25 +0800 Subject: [PATCH] Add type hints --- metar/Datatypes.pyi | 125 ++++++++++++++++++++++++++++++++++++ metar/Metar.pyi | 150 ++++++++++++++++++++++++++++++++++++++++++++ metar/Station.pyi | 23 +++++++ metar/py.typed | 0 setup.py | 2 +- 5 files changed, 299 insertions(+), 1 deletion(-) create mode 100644 metar/Datatypes.pyi create mode 100644 metar/Metar.pyi create mode 100644 metar/Station.pyi create mode 100644 metar/py.typed diff --git a/metar/Datatypes.pyi b/metar/Datatypes.pyi new file mode 100644 index 00000000..6294be5a --- /dev/null +++ b/metar/Datatypes.pyi @@ -0,0 +1,125 @@ +from typing import Literal, Optional, Union + +GreaterOrLess = Literal[">", "<"] +Value = Union[str, float] + +TemperatureUnit = Literal["F", "C", "K", "f", "c", "k"] + +class temperature: + _units: TemperatureUnit + _value: float + + def __init__(self, value: Value, units: TemperatureUnit = "C") -> None: ... + def __str__(self) -> str: ... + def value(self, units: Optional[TemperatureUnit] = None) -> float: ... + def string(self, units: Optional[TemperatureUnit] = None) -> str: ... + +PressureUnit = Literal["MB", "HPA", "IN", "mb", "hPa", "in"] + +class pressure: + _units: PressureUnit + _value: float + + def __init__(self, value: Value, units: PressureUnit = "MB") -> None: ... + def __str__(self) -> str: ... + def value(self, units: Optional[PressureUnit] = None) -> float: ... + def string(self, units: Optional[PressureUnit] = None) -> str: ... + +SpeedUnit = Literal["KT", "MPS", "KMH", "MPH", "kt", "mps", "kmh", "mph"] + +class speed: + _units: SpeedUnit + _value: float + _gtlt: GreaterOrLess + + def __init__( + self, + value: Value, + units: Optional[SpeedUnit] = None, + gtlt: Optional[GreaterOrLess] = None, + ) -> None: ... + def __str__(self) -> str: ... + def value(self, units: Optional[SpeedUnit] = None) -> float: ... + def string(self, units: Optional[SpeedUnit] = None) -> str: ... + +DistanceUnit = Literal[ + "SM", "MI", "M", "KM", "FT", "IN", "sm", "mi", "m", "km", "ft", "in" +] + +class distance: + _units: DistanceUnit + _value: float + _gtlt: GreaterOrLess + _num: Optional[int] + _den: Optional[int] + + def __init__( + self, + value: Value, + units: Optional[DistanceUnit] = None, + gtlt: Optional[GreaterOrLess] = None, + ) -> None: ... + def __str__(self) -> str: ... + def value(self, units: Optional[DistanceUnit] = None) -> float: ... + def string(self, units: Optional[DistanceUnit] = None) -> str: ... + +CompassDirection = Literal[ + "N", + "NNE", + "NE", + "ENE", + "E", + "ESE", + "SE", + "SSE", + "S", + "SSW", + "SW", + "WSW", + "W", + "WNW", + "NW", + "NNW", +] + +class direction: + _compass: Optional[CompassDirection] + _degrees: float + + def __init__( + self, + d: Union[CompassDirection, Value], + ): ... + def __str__(self) -> str: ... + def value(self) -> float: ... + def string(self) -> str: ... + def compass(self) -> CompassDirection: ... + +PrecipitationUnit = Literal["IN", "CM", "in", "cm"] + +class precipitation(object): + _units: PrecipitationUnit + _value: float + _gtlt: GreaterOrLess + _istrace: bool + + def __init__( + self, + value: Value, + units: Optional[PrecipitationUnit] = None, + gtlt: Optional[GreaterOrLess] = None, + ) -> None: ... + def __str__(self) -> str: ... + def value(self, units: Optional[PrecipitationUnit] = None) -> float: ... + def string(self, units: Optional[PrecipitationUnit] = None) -> str: ... + def istrace(self) -> bool: ... + +class position: + latitude: Optional[float] + longitude: Optional[float] + + def __init__( + self, latitude: Optional[float] = None, longitude: Optional[float] = None + ): ... + def __str__(self) -> str: ... + def getdirection(self, position2: "position") -> direction: ... diff --git a/metar/Metar.pyi b/metar/Metar.pyi new file mode 100644 index 00000000..b6c388fe --- /dev/null +++ b/metar/Metar.pyi @@ -0,0 +1,150 @@ +from datetime import datetime, timedelta +from re import Match +from typing import Callable, List, Literal, Optional, Tuple, Union + +from metar.Datatypes import ( + direction, + distance, + precipitation, + pressure, + speed, + temperature, +) + +def xlate_loc(loc: str) -> str: ... +def _sanitize(code: str) -> str: ... +def _report_match(handler: Callable[[dict], None], match: Match) -> None: ... +def _unparsedGroup(self: "Metar", d: dict) -> None: ... + +class Metar: + code: str + type: Literal["METAR", "SPECI"] + correction: Optional[str] + mod: Literal["AUTO", "COR"] + station_id: Optional[str] + time: Optional[datetime] + cycle: Optional[int] + wind_dir: Optional[direction] + wind_speed: Optional[speed] + wind_gust: Optional[speed] + wind_dir_from: Optional[direction] + wind_dir_to: Optional[direction] + vis: Optional[distance] + vis_dir: Optional[direction] + max_vis: Optional[distance] + max_vis_dir: Optional[direction] + temp: Optional[temperature] + dewpt: Optional[temperature] + press: Optional[pressure] + runway: List[list] + weather: List[Tuple[str, str, str, str, str]] + recent: List[Tuple[str, str, str, str, str]] + sky: List[Tuple[str, Optional[distance], str]] + windshear: List[str] + wind_speed_peak: Optional[speed] + wind_dir_peak: Optional[direction] + peak_wind_time: Optional[datetime] + wind_shift_time: Optional[datetime] + max_temp_6hr: Optional[temperature] + min_temp_6hr: Optional[temperature] + max_temp_24hr: Optional[temperature] + min_temp_24hr: Optional[temperature] + press_sea_level: Optional[pressure] + precip_1hr: Optional[precipitation] + precip_3hr: Optional[precipitation] + precip_6hr: Optional[precipitation] + precip_24hr: Optional[precipitation] + snowdepth: Optional[distance] + ice_accretion_1hr: Optional[precipitation] + ice_accretion_3hr: Optional[precipitation] + ice_accretion_6hr: Optional[precipitation] + _trend: bool + _trend_groups: List[str] + _remarks: List[str] + _unparsed_groups: List[str] + _unparsed_remarks: List[str] + _now: datetime + month: int + year: int + + def __init__( + self, + metarcode: str, + month: Optional[int] = ..., + year: Optional[int] = ..., + utcdelta: Union[int, timedelta, None] = ..., + strict: bool = ..., + ): ... + @property + def decode_completed(self) -> bool: ... + def _do_trend_handlers(self, code: str) -> str: ... + def __str__(self) -> str: ... + def _handleType(self, d: dict) -> None: ... + def _handleCorrection(self, d: dict) -> None: ... + def _handleStation(self, d: dict) -> None: ... + def _handleModifier(self, d: dict) -> None: ... + def _handleTime(self, d: dict) -> None: ... + def _handleWind(self, d: dict) -> None: ... + def _handleVisibility(self, d: dict) -> None: ... + def _handleRunway(self, d: dict) -> None: ... + def _handleWeather(self, d: dict) -> None: ... + def _handleSky(self, d: dict) -> None: ... + def _handleTemp(self, d: dict) -> None: ... + def _handlePressure(self, d: dict) -> None: ... + def _handleRecent(self, d: dict) -> None: ... + def _handleWindShear(self, d: dict) -> None: ... + def _handleColor(self, d: dict) -> None: ... + def _handleRunwayState(self, d: dict) -> None: ... + def _handleTrend(self, d: dict) -> None: ... + def _startRemarks(self, d: dict) -> None: ... + def _handleSealvlPressRemark(self, d: dict) -> None: ... + def _handlePrecip24hrRemark(self, d: dict) -> None: ... + def _handlePrecip1hrRemark(self, d: dict) -> None: ... + def _handleTemp1hrRemark(self, d: dict) -> None: ... + def _handleTemp6hrRemark(self, d: dict) -> None: ... + def _handleTemp24hrRemark(self, d: dict) -> None: ... + def _handlePress3hrRemark(self, d: dict) -> None: ... + def _handlePeakWindRemark(self, d: dict) -> None: ... + def _handleWindShiftRemark(self, d: dict) -> None: ... + def _handleLightningRemark(self, d: dict) -> None: ... + def _handleTSLocRemark(self, d: dict) -> None: ... + def _handleAutoRemark(self, d: dict) -> None: ... + def _handleSnowDepthRemark(self, d: dict) -> None: ... + def _handleIceAccretionRemark(self, d: dict) -> None: ... + def _unparsedRemark(self, d: dict) -> None: ... + def string(self) -> str: ... + def report_type(self) -> str: ... + def wind( + self, + units: Literal["KT", "MPS", "KMH", "MPH", "kt", "mps", "kmh", "mph"] = ..., + ) -> str: ... + def peak_wind( + self, + units: Literal["KT", "MPS", "KMH", "MPH", "kt", "mps", "kmh", "mph"] = ..., + ) -> str: ... + def wind_shift( + self, + units: Literal["KT", "MPS", "KMH", "MPH", "kt", "mps", "kmh", "mph"] = ..., + ) -> str: ... + def visibility( + self, + units: Optional[ + Literal[ + "SM", "MI", "M", "KM", "FT", "IN", "sm", "mi", "m", "km", "ft", "in" + ] + ] = ..., + ) -> str: ... + def runway_visual_range( + self, + units: Optional[ + Literal[ + "SM", "MI", "M", "KM", "FT", "IN", "sm", "mi", "m", "km", "ft", "in" + ] + ] = ..., + ) -> str: ... + def present_weather(self) -> str: ... + def recent_weather(self) -> str: ... + def _weather(self, weather: list) -> str: ... + def sky_conditions(self, sep: str = "; ") -> str: ... + def trend(self) -> str: ... + def remarks(self, sep: str = "; ") -> str: ... diff --git a/metar/Station.pyi b/metar/Station.pyi new file mode 100644 index 00000000..04e5491b --- /dev/null +++ b/metar/Station.pyi @@ -0,0 +1,23 @@ +from typing import Dict, Optional + +from metar.Datatypes import position + +class station: + id: str + name: str + city: Optional[str] + state: Optional[str] + country: Optional[str] + position: position + + def __init__( + self, + id: str, + city: Optional[str] = None, + state: Optional[str] = None, + country: Optional[str] = None, + latitude: Optional[str] = None, + longitude: Optional[str] = None, + ): ... + +stations: Dict[str, station] diff --git a/metar/py.typed b/metar/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/setup.py b/setup.py index 120fab33..d660fc5b 100755 --- a/setup.py +++ b/setup.py @@ -36,7 +36,7 @@ long_description=LONG_DESCRIPTION, license="BSD", packages=["metar"], - package_data={"metar": ["nsd_cccc.txt"]}, + package_data={"metar": ["nsd_cccc.txt", "py.typed", "*.pyi"]}, platforms="Python 2.5 and later.", extras_require={"test": ["pytest"]}, classifiers=[