wwvb 6.0.1__py3-none-any.whl → 8.0.0rc1__py3-none-any.whl

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/__init__.py CHANGED
@@ -19,23 +19,36 @@ import datetime
19
19
  import enum
20
20
  import json
21
21
  import warnings
22
- from typing import TYPE_CHECKING, Any, NamedTuple, TextIO, TypeVar
22
+ from dataclasses import dataclass
23
+ from typing import ClassVar, Literal
23
24
 
24
25
  from . import iersdata
25
26
  from .tz import Mountain
26
27
 
28
+ WWVBChannel = Literal["amplitude", "phase", "both"]
29
+
30
+ TYPE_CHECKING = False
27
31
  if TYPE_CHECKING:
28
32
  from collections.abc import Generator
33
+ from typing import NotRequired, Self, TextIO, TypedDict, TypeVar
29
34
 
30
- HOUR = datetime.timedelta(seconds=3600)
31
- SECOND = datetime.timedelta(seconds=1)
32
- T = TypeVar("T")
35
+ class JsonMinute(TypedDict):
36
+ """Implementation detail
33
37
 
38
+ This is the Python object type that is serialized by `print_timecodes_json`
39
+ """
34
40
 
35
- def _removeprefix(s: str, p: str) -> str:
36
- if s.startswith(p):
37
- return s[len(p) :]
38
- return s
41
+ year: int
42
+ days: int
43
+ hour: int
44
+ minute: int
45
+ amplitude: NotRequired[str]
46
+ phase: NotRequired[str]
47
+
48
+ T = TypeVar("T")
49
+
50
+ HOUR = datetime.timedelta(seconds=3600)
51
+ SECOND = datetime.timedelta(seconds=1)
39
52
 
40
53
 
41
54
  def _date(dt: datetime.date) -> datetime.date:
@@ -339,8 +352,13 @@ class DstStatus(enum.IntEnum):
339
352
  """DST in effect all day today"""
340
353
 
341
354
 
342
- class _WWVBMinute(NamedTuple):
343
- """(implementation detail)"""
355
+ @dataclass(frozen=True)
356
+ class WWVBMinute:
357
+ """Uniquely identifies a minute of time in the WWVB system.
358
+
359
+ To use ``ut1`` and ``ls`` information from IERS, create a `WWVBMinuteIERS`
360
+ object instead.
361
+ """
344
362
 
345
363
  year: int
346
364
  """2-digit year within the WWVB epoch"""
@@ -351,7 +369,7 @@ class _WWVBMinute(NamedTuple):
351
369
  hour: int
352
370
  """UTC hour of day"""
353
371
 
354
- min: int
372
+ minute: int
355
373
  """Minute of hour"""
356
374
 
357
375
  dst: DstStatus
@@ -366,18 +384,10 @@ class _WWVBMinute(NamedTuple):
366
384
  ly: bool
367
385
  """Leap year flag"""
368
386
 
387
+ epoch: ClassVar[int] = 1970
369
388
 
370
- class WWVBMinute(_WWVBMinute):
371
- """Uniquely identifies a minute of time in the WWVB system.
372
-
373
- To use ``ut1`` and ``ls`` information from IERS, create a `WWVBMinuteIERS`
374
- object instead.
375
- """
376
-
377
- epoch: int = 1970
378
-
379
- def __new__( # noqa: PYI034
380
- cls,
389
+ def __init__(
390
+ self,
381
391
  year: int,
382
392
  days: int,
383
393
  hour: int,
@@ -387,7 +397,7 @@ class WWVBMinute(_WWVBMinute):
387
397
  *,
388
398
  ls: bool | None = None,
389
399
  ly: bool | None = None,
390
- ) -> WWVBMinute:
400
+ ) -> None:
391
401
  """Construct a WWVBMinute
392
402
 
393
403
  :param year: The 2- or 4-digit year. This parameter is converted by the `full_year` method.
@@ -401,15 +411,23 @@ class WWVBMinute(_WWVBMinute):
401
411
  :param ls: Leap second warning flag
402
412
  :param ly: Leap year flag
403
413
  """
404
- dst = cls.get_dst(year, days) if dst is None else DstStatus(dst)
414
+ dst = self.get_dst(year, days) if dst is None else DstStatus(dst)
405
415
  if ut1 is None and ls is None:
406
- ut1, ls = cls._get_dut1_info(year, days)
416
+ ut1, ls = self._get_dut1_info(year, days)
407
417
  elif ut1 is None or ls is None:
408
418
  raise ValueError("sepecify both ut1 and ls or neither one")
409
- year = cls.full_year(year)
419
+ year = self.full_year(year)
410
420
  if ly is None:
411
421
  ly = isly(year)
412
- return _WWVBMinute.__new__(cls, year, days, hour, minute, dst, ut1, ls, ly)
422
+
423
+ super().__setattr__("year", year)
424
+ super().__setattr__("days", days)
425
+ super().__setattr__("hour", hour)
426
+ super().__setattr__("minute", minute)
427
+ super().__setattr__("dst", dst)
428
+ super().__setattr__("ut1", ut1)
429
+ super().__setattr__("ls", ls)
430
+ super().__setattr__("ly", ly)
413
431
 
414
432
  @classmethod
415
433
  def full_year(cls, year: int) -> int:
@@ -443,7 +461,7 @@ class WWVBMinute(_WWVBMinute):
443
461
  """Implement str()"""
444
462
  return (
445
463
  f"year={self.year:4d} days={self.days:03d} hour={self.hour:02d} "
446
- f"min={self.min:02d} dst={self.dst} ut1={self.ut1} ly={int(self.ly)} "
464
+ f"min={self.minute:02d} dst={self.dst} ut1={self.ut1} ly={int(self.ly)} "
447
465
  f"ls={int(self.ls)}"
448
466
  )
449
467
 
@@ -453,7 +471,7 @@ class WWVBMinute(_WWVBMinute):
453
471
  The returned object has ``tzinfo=datetime.timezone.utc``.
454
472
  """
455
473
  d = datetime.datetime(self.year, 1, 1, tzinfo=datetime.timezone.utc)
456
- d += datetime.timedelta(self.days - 1, self.hour * 3600 + self.min * 60)
474
+ d += datetime.timedelta(self.days - 1, self.hour * 3600 + self.minute * 60)
457
475
  return d
458
476
 
459
477
  as_datetime = as_datetime_utc
@@ -507,7 +525,7 @@ class WWVBMinute(_WWVBMinute):
507
525
  return 60
508
526
  if not self._is_end_of_month():
509
527
  return 60
510
- if self.hour != 23 or self.min != 59:
528
+ if self.hour != 23 or self.minute != 59:
511
529
  return 60
512
530
  if self.ut1 > 0:
513
531
  return 59
@@ -551,7 +569,7 @@ class WWVBMinute(_WWVBMinute):
551
569
  t.am[60] = AmplitudeModulation.MARK
552
570
  for i in [4, 10, 11, 14, 20, 21, 24, 34, 35, 44, 54]:
553
571
  t.am[i] = AmplitudeModulation.ZERO
554
- t._put_am_bcd(self.min, 1, 2, 3, 5, 6, 7, 8)
572
+ t._put_am_bcd(self.minute, 1, 2, 3, 5, 6, 7, 8)
555
573
  t._put_am_bcd(self.hour, 12, 13, 15, 16, 17, 18)
556
574
  t._put_am_bcd(self.days, 22, 23, 25, 26, 27, 28, 30, 31, 32, 33)
557
575
  ut1_sign = self.ut1 >= 0
@@ -565,14 +583,14 @@ class WWVBMinute(_WWVBMinute):
565
583
 
566
584
  def _fill_pm_timecode_extended(self, t: WWVBTimecode) -> None:
567
585
  """During minutes 10..15 and 40..45, the amplitude signal holds 'extended information'"""
568
- assert 10 <= self.min < 16 or 40 <= self.min < 46
569
- minno = self.min % 10
586
+ assert 10 <= self.minute < 16 or 40 <= self.minute < 46
587
+ minno = self.minute % 10
570
588
  assert minno < 6
571
589
 
572
590
  dst = self.dst
573
591
  # Note that these are 1 different than Table 11
574
592
  # because our LFSR sequence is zero-based
575
- seqno = (self.min // 30) * 2
593
+ seqno = (self.minute // 30) * 2
576
594
  if dst == 0:
577
595
  pass
578
596
  elif dst == 3:
@@ -655,17 +673,17 @@ class WWVBMinute(_WWVBMinute):
655
673
 
656
674
  def _fill_pm_timecode(self, t: WWVBTimecode) -> None:
657
675
  """Fill the phase portion of a timecode object"""
658
- if 10 <= self.min < 16 or 40 <= self.min < 46:
676
+ if 10 <= self.minute < 16 or 40 <= self.minute < 46:
659
677
  self._fill_pm_timecode_extended(t)
660
678
  else:
661
679
  self._fill_pm_timecode_regular(t)
662
680
 
663
- def next_minute(self, *, newut1: int | None = None, newls: bool | None = None) -> WWVBMinute:
681
+ def next_minute(self, *, newut1: int | None = None, newls: bool | None = None) -> Self:
664
682
  """Return an object representing the next minute"""
665
683
  d = self.as_datetime() + datetime.timedelta(minutes=1)
666
684
  return self.from_datetime(d, newut1=newut1, newls=newls, old_time=self)
667
685
 
668
- def previous_minute(self, *, newut1: int | None = None, newls: bool | None = None) -> WWVBMinute:
686
+ def previous_minute(self, *, newut1: int | None = None, newls: bool | None = None) -> Self:
669
687
  """Return an object representing the previous minute"""
670
688
  d = self.as_datetime() - datetime.timedelta(minutes=1)
671
689
  return self.from_datetime(d, newut1=newut1, newls=newls, old_time=self)
@@ -684,9 +702,9 @@ class WWVBMinute(_WWVBMinute):
684
702
  return 0, False
685
703
 
686
704
  @classmethod
687
- def fromstring(cls, s: str) -> WWVBMinute:
705
+ def fromstring(cls, s: str) -> Self:
688
706
  """Construct a WWVBMinute from a string representation created by print_timecodes"""
689
- s = _removeprefix(s, "WWVB timecode: ")
707
+ s = s.removeprefix("WWVB timecode: ")
690
708
  d: dict[str, int] = {}
691
709
  for part in s.split():
692
710
  k, v = part.split("=")
@@ -700,7 +718,7 @@ class WWVBMinute(_WWVBMinute):
700
718
  dst = d.pop("dst", None)
701
719
  ut1 = d.pop("ut1", None)
702
720
  ls = d.pop("ls", None)
703
- d.pop("ly", None)
721
+ d.pop("ly", None) # Always use calculated ly flag
704
722
  if d:
705
723
  raise ValueError(f"Invalid options: {d}")
706
724
  return cls(year, days, hour, minute, dst, ut1=ut1, ls=None if ls is None else bool(ls))
@@ -713,7 +731,7 @@ class WWVBMinute(_WWVBMinute):
713
731
  newut1: int | None = None,
714
732
  newls: bool | None = None,
715
733
  old_time: WWVBMinute | None = None,
716
- ) -> WWVBMinute:
734
+ ) -> Self:
717
735
  """Construct a WWVBMinute from a datetime, possibly specifying ut1/ls data or propagating it from an old time"""
718
736
  u = d.utctimetuple()
719
737
  if newls is None and newut1 is None:
@@ -721,7 +739,7 @@ class WWVBMinute(_WWVBMinute):
721
739
  return cls(u.tm_year, u.tm_yday, u.tm_hour, u.tm_min, ut1=newut1, ls=newls)
722
740
 
723
741
  @classmethod
724
- def from_timecode_am(cls, t: WWVBTimecode) -> WWVBMinute | None: # noqa: PLR0912
742
+ def from_timecode_am(cls, t: WWVBTimecode) -> Self | None: # noqa: PLR0912
725
743
  """Construct a WWVBMinute from a WWVBTimecode"""
726
744
  for i in (0, 9, 19, 29, 39, 49, 59):
727
745
  if t.am[i] != AmplitudeModulation.MARK:
@@ -764,6 +782,15 @@ class WWVBMinute(_WWVBMinute):
764
782
  return None
765
783
  return cls(year, days, hour, minute, dst, ut1, ls=ls, ly=ly)
766
784
 
785
+ @property
786
+ def min(self) -> int:
787
+ """Deprecated alias for `WWVBMinute.minute`
788
+
789
+ Update your code to use the `minute` property instead of the `min` property.
790
+ """
791
+ warnings.warn("WWVBMinute.min property is deprecated", category=DeprecationWarning, stacklevel=1)
792
+ return self.minute
793
+
767
794
 
768
795
  class WWVBMinuteIERS(WWVBMinute):
769
796
  """A WWVBMinute that uses a database of DUT1 information"""
@@ -915,7 +942,7 @@ styles = {
915
942
  def print_timecodes(
916
943
  w: WWVBMinute,
917
944
  minutes: int,
918
- channel: str,
945
+ channel: WWVBChannel,
919
946
  style: str,
920
947
  file: TextIO,
921
948
  *,
@@ -934,7 +961,7 @@ def print_timecodes(
934
961
  print(file=file)
935
962
  print(f"WWVB timecode: {w!s}{channel_text}{style_text}", file=file)
936
963
  first = False
937
- pfx = f"{w.year:04d}-{w.days:03d} {w.hour:02d}:{w.min:02d} "
964
+ pfx = f"{w.year:04d}-{w.days:03d} {w.hour:02d}:{w.minute:02d} "
938
965
  tc = w.as_timecode()
939
966
  if len(style_chars) == 6:
940
967
  print(f"{pfx} {tc.to_both_string(style_chars)}", file=file)
@@ -952,7 +979,7 @@ def print_timecodes(
952
979
  def print_timecodes_json(
953
980
  w: WWVBMinute,
954
981
  minutes: int,
955
- channel: str,
982
+ channel: WWVBChannel,
956
983
  file: TextIO,
957
984
  ) -> None:
958
985
  """Print a range of timecodes in JSON format.
@@ -972,11 +999,11 @@ def print_timecodes_json(
972
999
  """
973
1000
  result = []
974
1001
  for _ in range(minutes):
975
- data: dict[str, Any] = {
1002
+ data: JsonMinute = {
976
1003
  "year": w.year,
977
1004
  "days": w.days,
978
1005
  "hour": w.hour,
979
- "minute": w.min,
1006
+ "minute": w.minute,
980
1007
  }
981
1008
 
982
1009
  tc = w.as_timecode()
wwvb/__version__.py CHANGED
@@ -1,7 +1,14 @@
1
1
  # file generated by setuptools-scm
2
2
  # don't change, don't track in version control
3
3
 
4
- __all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
4
+ __all__ = [
5
+ "__version__",
6
+ "__version_tuple__",
7
+ "version",
8
+ "version_tuple",
9
+ "__commit_id__",
10
+ "commit_id",
11
+ ]
5
12
 
6
13
  TYPE_CHECKING = False
7
14
  if TYPE_CHECKING:
@@ -9,13 +16,19 @@ if TYPE_CHECKING:
9
16
  from typing import Union
10
17
 
11
18
  VERSION_TUPLE = Tuple[Union[int, str], ...]
19
+ COMMIT_ID = Union[str, None]
12
20
  else:
13
21
  VERSION_TUPLE = object
22
+ COMMIT_ID = object
14
23
 
15
24
  version: str
16
25
  __version__: str
17
26
  __version_tuple__: VERSION_TUPLE
18
27
  version_tuple: VERSION_TUPLE
28
+ commit_id: COMMIT_ID
29
+ __commit_id__: COMMIT_ID
19
30
 
20
- __version__ = version = '6.0.1'
21
- __version_tuple__ = version_tuple = (6, 0, 1)
31
+ __version__ = version = '8.0.0rc1'
32
+ __version_tuple__ = version_tuple = (8, 0, 0, 'rc1')
33
+
34
+ __commit_id__ = commit_id = None
wwvb/decode.py CHANGED
@@ -6,10 +6,10 @@
6
6
  from __future__ import annotations
7
7
 
8
8
  import sys
9
- from typing import TYPE_CHECKING
10
9
 
11
10
  import wwvb
12
11
 
12
+ TYPE_CHECKING = False
13
13
  if TYPE_CHECKING:
14
14
  from collections.abc import Generator
15
15
 
wwvb/gen.py CHANGED
@@ -9,15 +9,18 @@ from __future__ import annotations
9
9
 
10
10
  import datetime
11
11
  import sys
12
- from typing import Any
13
12
 
14
13
  import click
15
14
  import dateutil.parser
16
15
 
17
16
  from . import WWVBMinute, WWVBMinuteIERS, print_timecodes, print_timecodes_json, styles
18
17
 
18
+ TYPE_CHECKING = False
19
+ if TYPE_CHECKING:
20
+ from . import WWVBChannel
19
21
 
20
- def parse_timespec(ctx: Any, param: Any, value: list[str]) -> datetime.datetime: # noqa: ARG001
22
+
23
+ def parse_timespec(ctx: click.Context, param: click.Parameter, value: list[str]) -> datetime.datetime: # noqa: ARG001
21
24
  """Parse a time specifier from the commandline"""
22
25
  try:
23
26
  if len(value) == 5:
@@ -95,7 +98,7 @@ def main(
95
98
  dut1: int,
96
99
  minutes: int,
97
100
  style: str,
98
- channel: str,
101
+ channel: WWVBChannel,
99
102
  all_timecodes: bool,
100
103
  timespec: datetime.datetime,
101
104
  ) -> None:
wwvb/iersdata.json CHANGED
@@ -1 +1 @@
1
- {"START": "1972-01-01", "OFFSETS_GZ": "H4sIAIYEZWgC/+2aa3LDMAiEL5uHLTuxnN5/pn/aTmfSSiAWhGy+E2SWZQE58zwiH/1YivB/96vMXiIX2Io8CTyIrDSWGqlMRdrpDa6aJFnr0m4wYZkCE2UmSF0V+13vBveStK6JTfQyW3O86HLJf0RvDgy5u4FCI+WVKTsVoUdHzsrRoWRfYHIItZ5EEgu0Beu58EgEpMpO9zf4/s3iNO4y7/hqEwOZIPu3+PuO2T7Ic5E8GxsnZHvUYOtELxW1WP+0yx/caFxpyAooq6lq06UEr+UkLeXOIDPZ6EBrqb5K8Tvu6/B9CdnZqFQL05s2KauWy/IeF/tJGAisjK9MgGyDuUkRq4G1gRE+VjA30uZNPsdantkgMq58QO4fw+sqzj+A2/16mmvnyy9UzDvMktDgKYlnkFeB2rx+wNANG40aA4OgsY03AWoDCVs/XMmkyQ0+0jWaUqPdwA0m/MRuccGjCwirHToWzbcs8P7U1nZZLSYdHapWu5HqVg1YjK2fPEwvPZPzLPUF848tyid2u7dh8B7h+wVQ923Q+kqxZe3JclSSB+YTM3nnHrjgFth/vzgZzw6cbOMYa4bHFPU/DR3mp/ubKM4cgwMnHZW4GFxFprOVcevAKGva6oExn1MOmyGDJQPm0rpU8bjqdOo993O6Xz9ofToZela5vwrWoTn4l4o5CIIaKejCEgSnJv784V6y0/IJeROtycVNAAA="}
1
+ {"START": "1972-01-01", "OFFSETS_GZ": "H4sIAJLBtmgC/+2aa3LDMAiEL5uHLTuxnN5/pn/aTmfSSiAWhGy+E2SWZQE58zwiH/1YivB/96vMXiIX2Io8CTyIrDSWGqlMRdrpDa6aJFnr0m4wYZkCE2UmSF0V+13vBveStK6JTfQyW3O86HLJf0RvDgy5u4FCI+WVKTsVoUdHzsrRoWRfYHIItZ5EEgu0Beu58EgEpMpO9zf4/s3iNO4y7/hqEwOZIPu3+PuO2T7Ic5E8GxsnZHvUYOtELxW1WP+0yx/caFxpyAooq6lq06UEr+UkLeXOIDPZ6EBrqb5K8Tvu6/B9CdnZqFQL05s2KauWy/IeF/tJGAisjK9MgGyDuUkRq4G1gRE+VjA30uZNPsdantkgMq58QO4fw+sqzj+A2/16mmvnyy9UzDvMktDgKYlnkFeB2rx+wNANG40aA4OgsY03AWoDCVs/XMmkyQ0+0jWaUqPdwA0m/MRuccGjCwirHToWzbcs8P7U1nZZLSYdHapWu5HqVg1YjK2fPEwvPZPzLPUF848tyid2u7dh8B7h+wVQ923Q+kqxZe3JclSSB+YTM3nnHrjgFth/vzgZzw6cbOMYa4bHFPU/DR3mp/ubKM4cgwMnHZW4GFxFprOVcevAKGva6oExn1MOmyGDJQPm0rpU8bjqdOo993O6Xz9ofToZela5vwrWoTn4l4o5CIIaKejCEgSnJv784V+z0yyz2F/zCTF9VskETgAA"}
wwvb/updateiers.py CHANGED
@@ -47,6 +47,7 @@ def update_iersdata( # noqa: PLR0915
47
47
  """Update iersdata.py"""
48
48
  offsets: list[int] = []
49
49
  iersdata_text = _get_text(IERS_URL)
50
+ table_start: datetime.date | None = None
50
51
  for r in csv.DictReader(io.StringIO(iersdata_text), delimiter=";"):
51
52
  jd = float(r["MJD"])
52
53
  offs_str = r["UT1-UTC"]
@@ -79,6 +80,8 @@ def update_iersdata( # noqa: PLR0915
79
80
 
80
81
  offsets.append(offs)
81
82
 
83
+ assert table_start is not None
84
+
82
85
  wwvb_text = _get_text(NIST_URL)
83
86
  wwvb_data = bs4.BeautifulSoup(wwvb_text, features="html.parser")
84
87
  wwvb_dut1_table = wwvb_data.findAll("table")[2]
@@ -88,6 +91,7 @@ def update_iersdata( # noqa: PLR0915
88
91
  wwvb_data_stamp = datetime.datetime.fromisoformat(meta.attrs["content"]).replace(tzinfo=None).date()
89
92
 
90
93
  def patch(patch_start: datetime.date, patch_end: datetime.date, val: int) -> None:
94
+ assert table_start is not None
91
95
  off_start = (patch_start - table_start).days
92
96
  off_end = (patch_end - table_start).days
93
97
  offsets[off_start:off_end] = [val] * (off_end - off_start)
wwvb/wwvbtk.py CHANGED
@@ -8,13 +8,13 @@ from __future__ import annotations
8
8
 
9
9
  import datetime
10
10
  import functools
11
- from tkinter import Canvas, TclError, Tk
12
- from typing import TYPE_CHECKING, Any
11
+ from tkinter import Canvas, Event, TclError, Tk
13
12
 
14
13
  import click
15
14
 
16
15
  import wwvb
17
16
 
17
+ TYPE_CHECKING = False
18
18
  if TYPE_CHECKING:
19
19
  from collections.abc import Generator
20
20
 
@@ -25,7 +25,7 @@ def _app() -> Tk:
25
25
  return Tk()
26
26
 
27
27
 
28
- def validate_colors(ctx: Any, param: Any, value: str) -> list[str]: # noqa: ARG001
28
+ def validate_colors(ctx: click.Context, param: click.Parameter, value: str) -> list[str]: # noqa: ARG001
29
29
  """Check that all colors in a string are valid, splitting it to a list"""
30
30
  app = _app()
31
31
  colors = value.split()
@@ -69,7 +69,7 @@ def main(colors: list[str], size: int, min_size: int | None) -> None: # noqa: P
69
69
  def deadline_ms(deadline: datetime.datetime) -> int:
70
70
  """Compute the number of ms until a deadline"""
71
71
  now = datetime.datetime.now(datetime.timezone.utc)
72
- return int(max(0, (deadline - now).total_seconds()) * 1000)
72
+ return int(max(0.0, (deadline - now).total_seconds()) * 1000)
73
73
 
74
74
  def wwvbtick() -> Generator[tuple[datetime.datetime, wwvb.AmplitudeModulation]]:
75
75
  """Yield consecutive values of the WWVB amplitude signal, going from minute to minute"""
@@ -106,7 +106,7 @@ def main(colors: list[str], size: int, min_size: int | None) -> None: # noqa: P
106
106
  canvas.pack(fill="both", expand=True)
107
107
  app.wm_deiconify()
108
108
 
109
- def resize_canvas(event: Any) -> None:
109
+ def resize_canvas(event: Event) -> None:
110
110
  """Keep the circle filling the window when it is resized"""
111
111
  sz = min(event.width, event.height) - 8
112
112
  if sz < 0:
@@ -141,10 +141,12 @@ def main(colors: list[str], size: int, min_size: int | None) -> None: # noqa: P
141
141
 
142
142
  controller = controller_func().__next__
143
143
 
144
+ # pyrefly: ignore # bad-assignment
144
145
  def after_func() -> None:
145
146
  """Repeatedly run the controller after the desired interval"""
146
147
  app.after(controller(), after_func)
147
148
 
149
+ # pyrefly: ignore # bad-argument-type
148
150
  app.after_idle(after_func)
149
151
  app.mainloop()
150
152
 
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wwvb
3
- Version: 6.0.1
3
+ Version: 8.0.0rc1
4
4
  Summary: Generate WWVB timecodes for any desired time
5
5
  Author-email: Jeff Epler <jepler@gmail.com>
6
- Project-URL: Source, https://github.com/jepler/wwvbpy
7
- Project-URL: Documentation, https://github.com/jepler/wwvbpy
6
+ Project-URL: Source, https://codeberg.org/jepler/wwvbpy
7
+ Project-URL: Documentation, https://codeberg.org/jepler/wwvbpy
8
8
  Classifier: Programming Language :: Python :: 3
9
9
  Classifier: Programming Language :: Python :: 3.9
10
10
  Classifier: Programming Language :: Python :: 3.10
@@ -29,11 +29,7 @@ SPDX-FileCopyrightText: 2021-2024 Jeff Epler
29
29
 
30
30
  SPDX-License-Identifier: GPL-3.0-only
31
31
  -->
32
- [![Test wwvbgen](https://github.com/jepler/wwvbpy/actions/workflows/test.yml/badge.svg)](https://github.com/jepler/wwvbpy/actions/workflows/test.yml)
33
- [![codecov](https://codecov.io/gh/jepler/wwvbpy/branch/main/graph/badge.svg?token=Exx0c3Gp65)](https://codecov.io/gh/jepler/wwvbpy)
34
- [![Update DUT1 data](https://github.com/jepler/wwvbpy/actions/workflows/cron.yml/badge.svg)](https://github.com/jepler/wwvbpy/actions/workflows/cron.yml)
35
32
  [![PyPI](https://img.shields.io/pypi/v/wwvb)](https://pypi.org/project/wwvb)
36
- [![pre-commit.ci status](https://results.pre-commit.ci/badge/github/jepler/wwvbpy/main.svg)](https://results.pre-commit.ci/latest/github/jepler/wwvbpy/main)
37
33
 
38
34
  # Purpose
39
35
 
@@ -63,7 +59,7 @@ The package includes:
63
59
 
64
60
  # Development status
65
61
 
66
- The author ([@jepler](https://github.com/jepler)) occasionally develops and maintains this project, but
62
+ The author ([@jepler](https://unpythonic.net)) occasionally develops and maintains this project, but
67
63
  issues are not likely to be acted on. They would be interested in adding
68
64
  co-maintainer(s).
69
65
 
@@ -0,0 +1,18 @@
1
+ uwwvb.py,sha256=Ybf8DeOZ5VjfqRGtO90_oEEW6HhGaztIVlh4L423MdQ,5801
2
+ wwvb/__init__.py,sha256=8QRSFHrGEEnjvalE_mtcVCGvEzPwUl7Os9srr1V5nY0,33832
3
+ wwvb/__version__.py,sha256=Rclf3PGSRaeFMb7D6Z8qQ4TeuY5MHu6vmzjC3bfviAU,714
4
+ wwvb/decode.py,sha256=JQw8XT9AoXlJAl16JRZzjECUPfA7jLhDxI-_XSibzbc,2748
5
+ wwvb/dut1table.py,sha256=HVX1338RlQzAQ-bsMPEdmCqoyIxSWoJSoRu1YGyaJO4,875
6
+ wwvb/gen.py,sha256=iMTYLtyy3ItC4AplTakkOhHNHzDFVmApjlVwYIK72nI,3798
7
+ wwvb/iersdata.json,sha256=lUMrygiih4_ItKX_t8Hqnx5bt9_1D1jocPycbtzOfhE,769
8
+ wwvb/iersdata.json.license,sha256=1k5fhRCuOn0yXbwHtB21G0Nntnf0qMxstflMHuK3-Js,71
9
+ wwvb/iersdata.py,sha256=nMqA1xcE-iPtmi9m5qcTIJwfsCxZwoNsxHfM-wvooMQ,1210
10
+ wwvb/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ wwvb/tz.py,sha256=nlxKnzFPmqLLtC-cEDhWaJ3v3GCSPfqzVtUMf8EEdZ0,248
12
+ wwvb/updateiers.py,sha256=q3QY--fj06HJ9wCRCmVQK7pCpdXhCudP8BdUPG5WWOA,5781
13
+ wwvb/wwvbtk.py,sha256=cFBUduN8rQEdrpB0NtHK5r8HNDYfg_3XD7mbhYrVSrk,5284
14
+ wwvb-8.0.0rc1.dist-info/METADATA,sha256=f_izwyK9BqO8nSNAzycXQHzMsGSFi1oCsh1T1fHdzOg,9612
15
+ wwvb-8.0.0rc1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
+ wwvb-8.0.0rc1.dist-info/entry_points.txt,sha256=KSevvHWLEKxOxUQ-L-OQidD4Sj2BPEfhZ2TQhOgyys4,179
17
+ wwvb-8.0.0rc1.dist-info/top_level.txt,sha256=0IYdkhEAMgurpv_F-76rlyn4GdxepGFzG99tivVdQVU,11
18
+ wwvb-8.0.0rc1.dist-info/RECORD,,
@@ -1,18 +0,0 @@
1
- uwwvb.py,sha256=Ybf8DeOZ5VjfqRGtO90_oEEW6HhGaztIVlh4L423MdQ,5801
2
- wwvb/__init__.py,sha256=MRuk6nzitxbIcUfqVLkx-EzGTYYxm96ItfBlR4BSZuQ,32922
3
- wwvb/__version__.py,sha256=Csuu0TOiQZOQ062iwCy2GXvCmrtL4NFhA6E0Bwg71sw,511
4
- wwvb/decode.py,sha256=llTLKBW49nl6COheM90NsyMnTNeVApl2oeCHtl6Tf3w,2759
5
- wwvb/dut1table.py,sha256=HVX1338RlQzAQ-bsMPEdmCqoyIxSWoJSoRu1YGyaJO4,875
6
- wwvb/gen.py,sha256=_fpUypu_2nZfG5Vjnya0B8C26nk1WOhnLMTCXwskAHs,3720
7
- wwvb/iersdata.json,sha256=jKYjjxlDTqY7hDhPmYYZqbb_ZCNtMFvsQlUu1JRnlgg,765
8
- wwvb/iersdata.json.license,sha256=1k5fhRCuOn0yXbwHtB21G0Nntnf0qMxstflMHuK3-Js,71
9
- wwvb/iersdata.py,sha256=nMqA1xcE-iPtmi9m5qcTIJwfsCxZwoNsxHfM-wvooMQ,1210
10
- wwvb/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
- wwvb/tz.py,sha256=nlxKnzFPmqLLtC-cEDhWaJ3v3GCSPfqzVtUMf8EEdZ0,248
12
- wwvb/updateiers.py,sha256=Zemj6m0hwPLP31y8ODAS7sqLeB8SSHvv833pfUPHMUo,5661
13
- wwvb/wwvbtk.py,sha256=9RcSssben6CEsX7P3Rmphvmlnp8HoAb9gMFcCP35ryk,5184
14
- wwvb-6.0.1.dist-info/METADATA,sha256=ghsmh_zcHo7cqytknevo4D_Ot4O1tOt5mZ3aacbJnFI,10201
15
- wwvb-6.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
- wwvb-6.0.1.dist-info/entry_points.txt,sha256=KSevvHWLEKxOxUQ-L-OQidD4Sj2BPEfhZ2TQhOgyys4,179
17
- wwvb-6.0.1.dist-info/top_level.txt,sha256=0IYdkhEAMgurpv_F-76rlyn4GdxepGFzG99tivVdQVU,11
18
- wwvb-6.0.1.dist-info/RECORD,,
File without changes