wwvb 7.0.0__py3-none-any.whl → 8.0.0rc2__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
@@ -20,15 +20,30 @@ import enum
20
20
  import json
21
21
  import warnings
22
22
  from dataclasses import dataclass
23
- from typing import ClassVar
23
+ from typing import ClassVar, Literal
24
24
 
25
25
  from . import iersdata
26
26
  from .tz import Mountain
27
27
 
28
+ WWVBChannel = Literal["amplitude", "phase", "both"]
29
+
28
30
  TYPE_CHECKING = False
29
31
  if TYPE_CHECKING:
30
32
  from collections.abc import Generator
31
- from typing import Any, Self, TextIO, TypeVar
33
+ from typing import NotRequired, Self, TextIO, TypedDict, TypeVar
34
+
35
+ class JsonMinute(TypedDict):
36
+ """Implementation detail
37
+
38
+ This is the Python object type that is serialized by `print_timecodes_json`
39
+ """
40
+
41
+ year: int
42
+ days: int
43
+ hour: int
44
+ minute: int
45
+ amplitude: NotRequired[str]
46
+ phase: NotRequired[str]
32
47
 
33
48
  T = TypeVar("T")
34
49
 
@@ -787,7 +802,12 @@ class WWVBMinuteIERS(WWVBMinute):
787
802
 
788
803
 
789
804
  def _bcd_bits(n: int) -> Generator[bool]:
790
- """Return the bcd representation of n, starting with the least significant bit"""
805
+ """Return the (infinite) bcd representation of n, starting with the least significant bit
806
+
807
+ This continues to yield `False` forever after the nonzero bcd digits have been genrated.
808
+ This allows to `zip(strict=False)` the resulting bits together with a sequence of indices
809
+ and ensure all the upper bits are set to zero.
810
+ """
791
811
  while True:
792
812
  d = n % 10
793
813
  n = n // 10
@@ -866,7 +886,7 @@ class WWVBTimecode:
866
886
  Treating 'poslist' as a sequence of indices, update the AM signal with the value as a BCD number
867
887
  """
868
888
  pos = list(poslist)[::-1]
869
- for p, b in zip(pos, _bcd_bits(v)):
889
+ for p, b in zip(pos, _bcd_bits(v), strict=False):
870
890
  if b:
871
891
  self.am[p] = AmplitudeModulation.ONE
872
892
  else:
@@ -894,7 +914,7 @@ class WWVBTimecode:
894
914
  return ("⁰", "¹", "²", "¿")[am]
895
915
  return ("₀", "₁", "₂", "⸮")[am]
896
916
 
897
- return "".join(convert_one(i, j) for i, j in zip(self.am, self.phase))
917
+ return "".join(convert_one(i, j) for i, j in zip(self.am, self.phase, strict=True))
898
918
 
899
919
  def __repr__(self) -> str:
900
920
  """Implement repr()"""
@@ -912,7 +932,7 @@ class WWVBTimecode:
912
932
 
913
933
  def to_both_string(self, charset: list[str]) -> str:
914
934
  """Convert both channels to a string"""
915
- return "".join(charset[i + j * 3] for i, j in zip(self.am, self.phase))
935
+ return "".join(charset[i + j * 3] for i, j in zip(self.am, self.phase, strict=True))
916
936
 
917
937
 
918
938
  styles = {
@@ -927,7 +947,7 @@ styles = {
927
947
  def print_timecodes(
928
948
  w: WWVBMinute,
929
949
  minutes: int,
930
- channel: str,
950
+ channel: WWVBChannel,
931
951
  style: str,
932
952
  file: TextIO,
933
953
  *,
@@ -964,7 +984,7 @@ def print_timecodes(
964
984
  def print_timecodes_json(
965
985
  w: WWVBMinute,
966
986
  minutes: int,
967
- channel: str,
987
+ channel: WWVBChannel,
968
988
  file: TextIO,
969
989
  ) -> None:
970
990
  """Print a range of timecodes in JSON format.
@@ -984,7 +1004,7 @@ def print_timecodes_json(
984
1004
  """
985
1005
  result = []
986
1006
  for _ in range(minutes):
987
- data: dict[str, Any] = {
1007
+ data: JsonMinute = {
988
1008
  "year": w.year,
989
1009
  "days": w.days,
990
1010
  "hour": w.hour,
wwvb/__version__.py CHANGED
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '7.0.0'
32
- __version_tuple__ = version_tuple = (7, 0, 0)
31
+ __version__ = version = '8.0.0rc2'
32
+ __version_tuple__ = version_tuple = (8, 0, 0, 'rc2')
33
33
 
34
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": "H4sIAOvijWgC/+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+zUyyvbb/gE8h8bi3oTQAA"}
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
@@ -15,13 +15,16 @@ import gzip
15
15
  import io
16
16
  import json
17
17
  import pathlib
18
- from typing import Callable
18
+ from typing import TYPE_CHECKING
19
19
 
20
20
  import bs4
21
21
  import click
22
22
  import platformdirs
23
23
  import requests
24
24
 
25
+ if TYPE_CHECKING:
26
+ from collections.abc import Callable
27
+
25
28
  DIST_PATH = pathlib.Path(__file__).parent / "iersdata.json"
26
29
 
27
30
  IERS_URL = "https://datacenter.iers.org/data/csv/finals2000A.all.csv"
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()
@@ -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,19 +1,16 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wwvb
3
- Version: 7.0.0
3
+ Version: 8.0.0rc2
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://wwvbpy.readthedocs.io/en/latest/
8
8
  Classifier: Programming Language :: Python :: 3
9
- Classifier: Programming Language :: Python :: 3.9
10
- Classifier: Programming Language :: Python :: 3.10
11
- Classifier: Programming Language :: Python :: 3.11
12
9
  Classifier: Programming Language :: Python :: Implementation :: PyPy
13
10
  Classifier: Programming Language :: Python :: Implementation :: CPython
14
11
  Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
15
12
  Classifier: Operating System :: OS Independent
16
- Requires-Python: >=3.9
13
+ Requires-Python: >=3.10
17
14
  Description-Content-Type: text/markdown
18
15
  Requires-Dist: adafruit-circuitpython-datetime
19
16
  Requires-Dist: beautifulsoup4
@@ -29,11 +26,7 @@ SPDX-FileCopyrightText: 2021-2024 Jeff Epler
29
26
 
30
27
  SPDX-License-Identifier: GPL-3.0-only
31
28
  -->
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
29
  [![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
30
 
38
31
  # Purpose
39
32
 
@@ -63,7 +56,7 @@ The package includes:
63
56
 
64
57
  # Development status
65
58
 
66
- The author ([@jepler](https://github.com/jepler)) occasionally develops and maintains this project, but
59
+ The author ([@jepler](https://unpythonic.net)) occasionally develops and maintains this project, but
67
60
  issues are not likely to be acted on. They would be interested in adding
68
61
  co-maintainer(s).
69
62
 
@@ -0,0 +1,18 @@
1
+ uwwvb.py,sha256=Ybf8DeOZ5VjfqRGtO90_oEEW6HhGaztIVlh4L423MdQ,5801
2
+ wwvb/__init__.py,sha256=aFz_HXvOD5D4k_pWDgHA_kTWkBz-s3Ed5qY6W6MmuKE,34127
3
+ wwvb/__version__.py,sha256=BQnZGkrpqxv2i40P0cKXrysqXuu3x1wKpbxl8fOcQu8,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=WsyFqkoxlvJS70dwW8vQhMseVACX0VwQRWWm2NyfV4Y,5846
13
+ wwvb/wwvbtk.py,sha256=cFBUduN8rQEdrpB0NtHK5r8HNDYfg_3XD7mbhYrVSrk,5284
14
+ wwvb-8.0.0rc2.dist-info/METADATA,sha256=sgVxOqNBSjlsAdw02aZJMSxkACg7GCBmXs8O5Fc7kww,9467
15
+ wwvb-8.0.0rc2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
+ wwvb-8.0.0rc2.dist-info/entry_points.txt,sha256=KSevvHWLEKxOxUQ-L-OQidD4Sj2BPEfhZ2TQhOgyys4,179
17
+ wwvb-8.0.0rc2.dist-info/top_level.txt,sha256=0IYdkhEAMgurpv_F-76rlyn4GdxepGFzG99tivVdQVU,11
18
+ wwvb-8.0.0rc2.dist-info/RECORD,,
@@ -1,18 +0,0 @@
1
- uwwvb.py,sha256=Ybf8DeOZ5VjfqRGtO90_oEEW6HhGaztIVlh4L423MdQ,5801
2
- wwvb/__init__.py,sha256=tSEjmfqKR0KYdN7tUySGcXpK_W8rzQTtEXG7P_0WPMA,33432
3
- wwvb/__version__.py,sha256=lB_6pZBic6H_5wY9p7_cc7miE65gtXFl65pORFxuiX0,704
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=fEElNoF4UJMySnUvNXFlI9TT9k67jdrrGKzO6A1F2rQ,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=cdLwWfulywHmGhaiK6L-m_QQAdpfDfyDFagbe_Y8Rgk,5186
14
- wwvb-7.0.0.dist-info/METADATA,sha256=6oqjB6nkDQAYeoe8hGbSq5jk9Cj7q9swibX6jubJ-b4,10201
15
- wwvb-7.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
16
- wwvb-7.0.0.dist-info/entry_points.txt,sha256=KSevvHWLEKxOxUQ-L-OQidD4Sj2BPEfhZ2TQhOgyys4,179
17
- wwvb-7.0.0.dist-info/top_level.txt,sha256=0IYdkhEAMgurpv_F-76rlyn4GdxepGFzG99tivVdQVU,11
18
- wwvb-7.0.0.dist-info/RECORD,,
File without changes