wwvb 3.0.7__tar.gz → 3.0.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {wwvb-3.0.7 → wwvb-3.0.8}/.pre-commit-config.yaml +1 -1
- {wwvb-3.0.7/src/wwvb.egg-info → wwvb-3.0.8}/PKG-INFO +1 -1
- {wwvb-3.0.7 → wwvb-3.0.8}/conf.py +0 -1
- {wwvb-3.0.7 → wwvb-3.0.8}/src/uwwvb.py +1 -1
- {wwvb-3.0.7 → wwvb-3.0.8}/src/wwvb/__init__.py +6 -14
- {wwvb-3.0.7 → wwvb-3.0.8}/src/wwvb/__version__.py +2 -2
- {wwvb-3.0.7 → wwvb-3.0.8}/src/wwvb/decode.py +1 -1
- {wwvb-3.0.7 → wwvb-3.0.8}/src/wwvb/gen.py +1 -4
- {wwvb-3.0.7 → wwvb-3.0.8}/src/wwvb/iersdata.py +1 -1
- {wwvb-3.0.7 → wwvb-3.0.8}/src/wwvb/iersdata_dist.py +2 -4
- {wwvb-3.0.7 → wwvb-3.0.8}/src/wwvb/testcli.py +0 -2
- {wwvb-3.0.7 → wwvb-3.0.8}/src/wwvb/testuwwvb.py +1 -3
- {wwvb-3.0.7 → wwvb-3.0.8}/src/wwvb/testwwvb.py +0 -1
- {wwvb-3.0.7 → wwvb-3.0.8}/src/wwvb/updateiers.py +2 -3
- {wwvb-3.0.7 → wwvb-3.0.8}/src/wwvb/wwvbtk.py +2 -4
- {wwvb-3.0.7 → wwvb-3.0.8/src/wwvb.egg-info}/PKG-INFO +1 -1
- {wwvb-3.0.7 → wwvb-3.0.8}/.coveragerc +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/.github/workflows/codeql.yml +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/.github/workflows/cron.yml +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/.github/workflows/release.yml +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/.github/workflows/test.yml +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/.gitignore +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/.pylintrc +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/LICENSES/Apache-2.0.txt +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/LICENSES/CC0-1.0.txt +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/LICENSES/GPL-3.0-only.txt +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/LICENSES/Unlicense.txt +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/Makefile +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/README.md +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/_static/.empty +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/adafruit_datetime.pyi +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/codecov.yml +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/pyproject.toml +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/requirements-dev.txt +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/setup.cfg +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/src/wwvb/dut1table.py +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/src/wwvb/py.typed +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/src/wwvb/testdaylight.py +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/src/wwvb/testls.py +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/src/wwvb/testpm.py +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/src/wwvb/tz.py +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/src/wwvb.egg-info/SOURCES.txt +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/src/wwvb.egg-info/dependency_links.txt +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/src/wwvb.egg-info/entry_points.txt +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/src/wwvb.egg-info/requires.txt +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/src/wwvb.egg-info/top_level.txt +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/1998leapsecond +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/2012leapsecond +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/all-headers +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/bar +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/both +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/cradek +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/duration +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/enddst-phase +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/enddst-phase-2 +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/endleapyear +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/leapday1 +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/leapday28 +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/leapday29 +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/negleapsecond +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/nextdst +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/nextst +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/nonleapday1 +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/nonleapday28 +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/phase +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/startdst +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/startdst-phase +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/startdst-phase-2 +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/startleapyear +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/startst +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/y2k +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/y2k-1 +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/y2k1 +0 -0
- {wwvb-3.0.7 → wwvb-3.0.8}/tests/y2k1-1 +0 -0
@@ -87,7 +87,7 @@ def get_am_bcd(seq: list[int], *poslist: int) -> int | None:
|
|
87
87
|
return result
|
88
88
|
|
89
89
|
|
90
|
-
def decode_wwvb(
|
90
|
+
def decode_wwvb(
|
91
91
|
t: list[int] | None,
|
92
92
|
) -> WWVBMinute | None:
|
93
93
|
"""Convert a received minute of wwvb symbols to a WWVBMinute. Returns None if any error is detected."""
|
@@ -19,7 +19,7 @@ from .tz import Mountain
|
|
19
19
|
HOUR = datetime.timedelta(seconds=3600)
|
20
20
|
SECOND = datetime.timedelta(seconds=1)
|
21
21
|
DateOrDatetime = TypeVar("DateOrDatetime", datetime.date, datetime.datetime)
|
22
|
-
T = TypeVar("T")
|
22
|
+
T = TypeVar("T")
|
23
23
|
|
24
24
|
|
25
25
|
def require(x: Optional[T]) -> T:
|
@@ -336,7 +336,7 @@ class WWVBMinute(_WWVBMinute):
|
|
336
336
|
|
337
337
|
epoch: int = 1970
|
338
338
|
|
339
|
-
def __new__(
|
339
|
+
def __new__(
|
340
340
|
cls,
|
341
341
|
year: int,
|
342
342
|
days: int,
|
@@ -534,9 +534,7 @@ class WWVBMinute(_WWVBMinute):
|
|
534
534
|
for i in range(60):
|
535
535
|
t._put_pm_bit(i, full_seq[i + offset])
|
536
536
|
|
537
|
-
def fill_pm_timecode_regular(
|
538
|
-
self, t: "WWVBTimecode"
|
539
|
-
) -> None:
|
537
|
+
def fill_pm_timecode_regular(self, t: "WWVBTimecode") -> None:
|
540
538
|
"""Except during minutes 10..15 and 40..45, the amplitude signal holds 'regular information'"""
|
541
539
|
t._put_pm_bin(0, 13, SYNC_T)
|
542
540
|
|
@@ -610,9 +608,7 @@ class WWVBMinute(_WWVBMinute):
|
|
610
608
|
return self.from_datetime(d, newut1, newls, self)
|
611
609
|
|
612
610
|
@classmethod
|
613
|
-
def _get_dut1_info(
|
614
|
-
cls: type, year: int, days: int, old_time: "Optional[WWVBMinute]" = None
|
615
|
-
) -> Tuple[int, bool]:
|
611
|
+
def _get_dut1_info(cls: type, year: int, days: int, old_time: "Optional[WWVBMinute]" = None) -> Tuple[int, bool]:
|
616
612
|
"""Return the DUT1 information for a given day, possibly propagating information from a previous timestamp"""
|
617
613
|
if old_time is not None:
|
618
614
|
if old_time.minute_length() != 60:
|
@@ -664,9 +660,7 @@ class WWVBMinute(_WWVBMinute):
|
|
664
660
|
return cls(u.tm_year, u.tm_yday, u.tm_hour, u.tm_min, ut1=newut1, ls=newls)
|
665
661
|
|
666
662
|
@classmethod
|
667
|
-
def from_timecode_am(
|
668
|
-
cls, t: "WWVBTimecode"
|
669
|
-
) -> Optional["WWVBMinute"]:
|
663
|
+
def from_timecode_am(cls, t: "WWVBTimecode") -> Optional["WWVBMinute"]:
|
670
664
|
"""Construct a WWVBMinute from a WWVBTimecode"""
|
671
665
|
for i in (0, 9, 19, 29, 39, 49, 59):
|
672
666
|
if t.am[i] != AmplitudeModulation.MARK:
|
@@ -748,7 +742,7 @@ class WWVBTimecode:
|
|
748
742
|
phase: List[PhaseModulation]
|
749
743
|
|
750
744
|
def __init__(self, sz: int) -> None:
|
751
|
-
self.am = [AmplitudeModulation.UNSET] * sz
|
745
|
+
self.am = [AmplitudeModulation.UNSET] * sz
|
752
746
|
self.phase = [PhaseModulation.UNSET] * sz
|
753
747
|
|
754
748
|
def _get_am_bcd(self, *poslist: int) -> Optional[int]:
|
@@ -835,7 +829,6 @@ styles = {
|
|
835
829
|
}
|
836
830
|
|
837
831
|
|
838
|
-
# pylint: disable=too-many-arguments
|
839
832
|
def print_timecodes(
|
840
833
|
w: WWVBMinute,
|
841
834
|
minutes: int,
|
@@ -873,7 +866,6 @@ def print_timecodes(
|
|
873
866
|
w = w.next_minute()
|
874
867
|
|
875
868
|
|
876
|
-
# pylint: disable=too-many-arguments
|
877
869
|
def print_timecodes_json(
|
878
870
|
w: WWVBMinute,
|
879
871
|
minutes: int,
|
@@ -23,7 +23,7 @@ import wwvb
|
|
23
23
|
always_zero = set((4, 10, 11, 14, 20, 21, 34, 35, 44, 54))
|
24
24
|
|
25
25
|
|
26
|
-
def wwvbreceive() -> Generator[Optional[wwvb.WWVBTimecode], wwvb.AmplitudeModulation, None]:
|
26
|
+
def wwvbreceive() -> Generator[Optional[wwvb.WWVBTimecode], wwvb.AmplitudeModulation, None]:
|
27
27
|
"""A stateful decoder of WWVB signals"""
|
28
28
|
minute: List[wwvb.AmplitudeModulation] = []
|
29
29
|
state = 1
|
@@ -16,9 +16,7 @@ import dateutil.parser
|
|
16
16
|
from . import WWVBMinute, WWVBMinuteIERS, print_timecodes, print_timecodes_json, styles
|
17
17
|
|
18
18
|
|
19
|
-
def parse_timespec(
|
20
|
-
ctx: Any, param: Any, value: List[str]
|
21
|
-
) -> datetime.datetime:
|
19
|
+
def parse_timespec(ctx: Any, param: Any, value: List[str]) -> datetime.datetime:
|
22
20
|
"""Parse a time specifier from the commandline"""
|
23
21
|
try:
|
24
22
|
if len(value) == 5:
|
@@ -87,7 +85,6 @@ def parse_timespec( # pylint: disable=unused-argument
|
|
87
85
|
help="Modulation to show (default: amplitude)",
|
88
86
|
)
|
89
87
|
@click.argument("timespec", type=str, nargs=-1, callback=parse_timespec)
|
90
|
-
# pylint: disable=too-many-arguments, too-many-locals
|
91
88
|
def main(
|
92
89
|
iers: bool,
|
93
90
|
leap_second: bool,
|
@@ -21,7 +21,7 @@ for location in [
|
|
21
21
|
filename = os.path.join(location, "wwvbpy_iersdata.py")
|
22
22
|
if os.path.exists(filename):
|
23
23
|
with open(filename, encoding="utf-8") as f:
|
24
|
-
exec(f.read(), globals(), globals())
|
24
|
+
exec(f.read(), globals(), globals())
|
25
25
|
break
|
26
26
|
|
27
27
|
start = datetime.datetime.combine(DUT1_DATA_START, datetime.time()).replace(tzinfo=datetime.timezone.utc)
|
@@ -1,11 +1,9 @@
|
|
1
1
|
# -*- python3 -*-
|
2
|
+
# fmt: off
|
2
3
|
"""File generated from public data - not subject to copyright"""
|
3
|
-
|
4
4
|
# SPDX-FileCopyrightText: Public domain
|
5
5
|
# SPDX-License-Identifier: CC0-1.0
|
6
|
-
# fmt: off
|
7
6
|
# isort: skip_file
|
8
|
-
# pylint: disable=invalid-name
|
9
7
|
import datetime
|
10
8
|
__all__ = ['DUT1_DATA_START', 'DUT1_OFFSETS']
|
11
9
|
DUT1_DATA_START = datetime.date(1972, 1, 1)
|
@@ -36,5 +34,5 @@ DUT1_OFFSETS = str( # 19720101
|
|
36
34
|
+i*126+h*176+g*97+f*91+e*52+o*116+n*98+m*70+l*133+k*91+j*91 # 20140507
|
37
35
|
+i*77+h*140+g*91+f*84+e*70+d*34+n*72+m*76+l*66+k*53+j*56 # 20160831
|
38
36
|
+i*105+h*77+g*45+q*25+p*63+o*91+n*154+m*105+l*190+k*118 # 20190501
|
39
|
-
+j*105+i*807+j*376+k*
|
37
|
+
+j*105+i*807+j*376+k*775+l*67+k*2+l*6+k*133 # 20250405
|
40
38
|
)
|
@@ -21,9 +21,7 @@ EitherDatetimeOrNone = Union[None, datetime.datetime, adafruit_datetime.datetime
|
|
21
21
|
class WWVBRoundtrip(unittest.TestCase):
|
22
22
|
"""tests of uwwvb.py"""
|
23
23
|
|
24
|
-
def assertDateTimeEqualExceptTzInfo(
|
25
|
-
self, a: EitherDatetimeOrNone, b: EitherDatetimeOrNone
|
26
|
-
) -> None:
|
24
|
+
def assertDateTimeEqualExceptTzInfo(self, a: EitherDatetimeOrNone, b: EitherDatetimeOrNone) -> None:
|
27
25
|
"""Test two datetime objects for equality
|
28
26
|
|
29
27
|
This equality test excludes tzinfo, and allows adafruit_datetime and core datetime modules to compare equal"""
|
@@ -45,7 +45,7 @@ def _get_text(url: str) -> str:
|
|
45
45
|
return open(url, encoding="utf-8").read()
|
46
46
|
|
47
47
|
|
48
|
-
def update_iersdata(
|
48
|
+
def update_iersdata(
|
49
49
|
target_file: str,
|
50
50
|
) -> None:
|
51
51
|
"""Update iersdata.py"""
|
@@ -130,12 +130,11 @@ def update_iersdata( # pylint: disable=too-many-locals, too-many-branches, too-
|
|
130
130
|
print(*args, file=output)
|
131
131
|
|
132
132
|
code("# -*- python3 -*-")
|
133
|
+
code("# fmt: off")
|
133
134
|
code('"""File generated from public data - not subject to copyright"""')
|
134
135
|
code("# SPDX" + "-FileCopyrightText: Public domain")
|
135
136
|
code("# SPDX" + "-License-Identifier: CC0-1.0")
|
136
|
-
code("# fmt: off")
|
137
137
|
code("# isort: skip_file")
|
138
|
-
code("# pylint: disable=invalid-name")
|
139
138
|
code("import datetime")
|
140
139
|
|
141
140
|
code("__all__ = ['DUT1_DATA_START', 'DUT1_OFFSETS']")
|
@@ -9,7 +9,7 @@
|
|
9
9
|
import functools
|
10
10
|
import threading
|
11
11
|
import time
|
12
|
-
from tkinter import Canvas, TclError, Tk
|
12
|
+
from tkinter import Canvas, TclError, Tk
|
13
13
|
from typing import Any, Generator, Optional, Tuple
|
14
14
|
|
15
15
|
import click
|
@@ -23,9 +23,7 @@ def _app() -> Tk:
|
|
23
23
|
return Tk()
|
24
24
|
|
25
25
|
|
26
|
-
def validate_colors(
|
27
|
-
ctx: Any, param: Any, value: str
|
28
|
-
) -> list[str]:
|
26
|
+
def validate_colors(ctx: Any, param: Any, value: str) -> list[str]:
|
29
27
|
"""Check that all colors in a string are valid, splitting it to a list"""
|
30
28
|
app = _app()
|
31
29
|
colors = value.split()
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|