From 53bd16b2a85a8310c5678e23a2bcec37a182335f Mon Sep 17 00:00:00 2001 From: Leon Morten Richter Date: Fri, 1 Nov 2024 11:12:37 +0100 Subject: [PATCH] feat: unify enum __str__ by adding ReprEnum --- pyais/constants.py | 32 +++++++++++++++++++------------- tests/test_repr.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 13 deletions(-) create mode 100644 tests/test_repr.py diff --git a/pyais/constants.py b/pyais/constants.py index 920af6a..8a3b4c1 100644 --- a/pyais/constants.py +++ b/pyais/constants.py @@ -1,5 +1,5 @@ import typing -from enum import Enum, IntEnum +from enum import Enum # Keywords UNDEFINED = 'Undefined' @@ -9,7 +9,13 @@ ANSI_RESET = '\x1b[0m' -class TurnRate(float, Enum): +class ReprEnum(Enum): + + def __str__(self) -> str: + return str(self.value) + + +class TurnRate(float, ReprEnum): # Source: https://gpsd.gitlab.io/gpsd/AIVDM.html#_types_1_2_and_3_position_report_class_a # turning right at more than 5deg/30s (No TI available) NO_TI_RIGHT = 127 @@ -19,7 +25,7 @@ class TurnRate(float, Enum): NO_TI_DEFAULT = -128 -class TalkerID(str, Enum): +class TalkerID(str, ReprEnum): """ Enum of all NMEA talker IDs. See: https://gpsd.gitlab.io/gpsd/AIVDM.html#_talker_ids""" Base_Station = "AB" @@ -43,7 +49,7 @@ def from_value(cls, v: typing.Optional[typing.Any]) -> typing.Optional["TalkerID return cls(v) if v is not None else None -class NavigationStatus(IntEnum): +class NavigationStatus(int, ReprEnum): UnderWayUsingEngine = 0 AtAnchor = 1 NotUnderCommand = 2 @@ -70,7 +76,7 @@ def from_value(cls, v: typing.Optional[typing.Any]) -> typing.Optional["Navigati return cls(v) if v is not None else None -class ManeuverIndicator(IntEnum): +class ManeuverIndicator(int, ReprEnum): NotAvailable = 0 NoSpecialManeuver = 1 SpecialManeuver = 2 @@ -85,7 +91,7 @@ def from_value(cls, v: typing.Optional[typing.Any]) -> typing.Optional["Maneuver return cls(v) if v is not None else None -class EpfdType(IntEnum): +class EpfdType(int, ReprEnum): Undefined = 0 GPS = 1 GLONASS = 2 @@ -106,7 +112,7 @@ def from_value(cls, v: typing.Optional[typing.Any]) -> typing.Optional["EpfdType return cls(v) if v is not None else None -class ShipType(IntEnum): +class ShipType(int, ReprEnum): NotAvailable = 0 # 20's WIG = 20 @@ -207,7 +213,7 @@ def from_value(cls, v: typing.Optional[typing.Any]) -> typing.Optional["ShipType return cls(v) if v is not None else None -class DacFid(IntEnum): +class DacFid(int, ReprEnum): DangerousCargoIndication = 13 TidalWindow = 15 NumPersonsOnBoard = 17 @@ -226,7 +232,7 @@ def from_value(cls, v: typing.Optional[typing.Any]) -> typing.Optional["DacFid"] return cls(v) if v is not None else None -class NavAid(IntEnum): +class NavAid(int, ReprEnum): DEFAULT = 0 REFERENCE_POINT = 1 RACON = 2 @@ -269,7 +275,7 @@ def from_value(cls, v: typing.Optional[typing.Any]) -> typing.Optional["NavAid"] return cls(v) if v is not None else None -class TransmitMode(IntEnum): +class TransmitMode(int, ReprEnum): TXA_TXB_RXA_RXB = 0 # default TXA_RXA_RXB = 1 TXB_RXA_RXB = 2 @@ -284,7 +290,7 @@ def from_value(cls, v: typing.Optional[typing.Any]) -> typing.Optional["Transmit return cls(v) if v is not None else None -class StationType(IntEnum): +class StationType(int, ReprEnum): ALL = 0 RESERVED = 1 CLASS_B_ALL = 2 @@ -307,7 +313,7 @@ def from_value(cls, v: typing.Optional[typing.Any]) -> typing.Optional["StationT return cls(v) if v is not None else None -class StationIntervals(IntEnum): +class StationIntervals(int, ReprEnum): AUTONOMOUS_MODE = 0 MINUTES_10 = 1 MINUTES_6 = 2 @@ -330,7 +336,7 @@ def from_value(cls, v: typing.Optional[typing.Any]) -> typing.Optional["StationI return cls(v) if v is not None else None -class SyncState(IntEnum): +class SyncState(int, ReprEnum): """ https://www.navcen.uscg.gov/?pageName=AISMessagesA#Sync """ diff --git a/tests/test_repr.py b/tests/test_repr.py new file mode 100644 index 0000000..cadbfc9 --- /dev/null +++ b/tests/test_repr.py @@ -0,0 +1,33 @@ +import unittest +from pyais.constants import TurnRate, TalkerID, NavigationStatus, ManeuverIndicator, EpfdType, ShipType + + +class TestPyAISConstants(unittest.TestCase): + + def test_turn_rate_no_ti_default(self): + self.assertEqual(repr(TurnRate.NO_TI_DEFAULT), "") + self.assertEqual(str(TurnRate.NO_TI_DEFAULT), "-128.0") + + def test_talker_id_base_station(self): + self.assertEqual(repr(TalkerID.Base_Station), "") + self.assertEqual(str(TalkerID.Base_Station), "AB") + + def test_navigation_status_aground(self): + self.assertEqual(repr(NavigationStatus.Aground), "") + self.assertEqual(str(NavigationStatus.Aground), "6") + + def test_maneuver_indicator_no_special_maneuver(self): + self.assertEqual(repr(ManeuverIndicator.NoSpecialManeuver), "") + self.assertEqual(str(ManeuverIndicator.NoSpecialManeuver), "1") + + def test_epfd_type_glonass(self): + self.assertEqual(repr(EpfdType.GLONASS), "") + self.assertEqual(str(EpfdType.GLONASS), "2") + + def test_ship_type_wig_hazardous_category_a(self): + self.assertEqual(repr(ShipType.WIG_HazardousCategory_A), "") + self.assertEqual(str(ShipType.WIG_HazardousCategory_A), "21") + + +if __name__ == '__main__': + unittest.main()