diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7243ab9..78efec7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,7 +11,7 @@ on: jobs: release: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - name: Dump GitHub context env: @@ -23,7 +23,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v1 with: - python-version: 3.7 + python-version: 3.10 - name: Install deps run: python -mpip install -r requirements-dev.txt diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4b99ed6..0d1ff4f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,7 +14,7 @@ on: jobs: docs: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - name: Set up Python uses: actions/setup-python@v2 @@ -42,7 +42,7 @@ jobs: env: PYTHON: ${{ matrix.python-version }} - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - name: Dump GitHub context env: @@ -73,7 +73,7 @@ jobs: fail_ci_if_error: true pre-commit: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - uses: actions/setup-python@v1 diff --git a/leapseconddata/__init__.py b/leapseconddata/__init__.py index 73c6dea..9dc5142 100755 --- a/leapseconddata/__init__.py +++ b/leapseconddata/__init__.py @@ -28,6 +28,7 @@ import io import logging import re import urllib.request +from dataclasses import dataclass, field from typing import BinaryIO, List, NamedTuple, Optional, Union tai = datetime.timezone(datetime.timedelta(0), "TAI") @@ -58,24 +59,8 @@ def _from_ntp_epoch(value: int) -> datetime.datetime: return NTP_EPOCH + datetime.timedelta(seconds=value) -_LeapSecondData = NamedTuple( - "_LeapSecondData", - ( - ("leap_seconds", List[LeapSecondInfo]), - ("valid_until", Optional[datetime.datetime]), - ("last_updated", Optional[datetime.datetime]), - ), -) - -_LeapSecondData.leap_seconds.__doc__ = """All known and scheduled leap seconds""" -_LeapSecondData.valid_until.__doc__ = """The list is valid until this UTC time""" -_LeapSecondData.last_updated.__doc__ = """The last time the list was updated to add a new upcoming leap second. - -It is only updated when a new leap second is scheduled, so this date may be -well in the past. Use `valid_until` to determine validity.""" - - -class LeapSecondData(_LeapSecondData): +@dataclass(frozen=True) +class LeapSecondData: """Represent the list of known and scheduled leapseconds :param List[LeapSecondInfo] leap_seconds: A list of leap seconds @@ -83,25 +68,15 @@ class LeapSecondData(_LeapSecondData): :param Optional[datetime.datetime] updated: The last update time of the data, if available """ - __slots__ = () - leap_seconds: List[LeapSecondInfo] """All known and scheduled leap seconds""" - valid_until: Optional[datetime.datetime] + valid_until: Optional[datetime.datetime] = field(default=None) """The list is valid until this UTC time""" - last_updated: Optional[datetime.datetime] + last_updated: Optional[datetime.datetime] = field(default=None) """The last time the list was updated to add a new upcoming leap second""" - def __new__( - cls, - leap_seconds: List[LeapSecondInfo], - valid_until: Optional[datetime.datetime] = None, - last_updated: Optional[datetime.datetime] = None, - ) -> LeapSecondData: - return super().__new__(cls, leap_seconds, valid_until, last_updated) - def _check_validity(self, when: Optional[datetime.datetime]) -> Optional[str]: if when is None: when = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)