Skip to content

Commit db6e374

Browse files
authored
Merge pull request #101 from jepler/build-docs
build docs during CI
2 parents 2440e88 + 4eb910f commit db6e374

File tree

4 files changed

+95
-13
lines changed

4 files changed

+95
-13
lines changed

.github/workflows/test.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,22 @@ on:
1313
types: [rerequested]
1414

1515
jobs:
16+
docs:
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Set up Python
20+
uses: actions/setup-python@v5
21+
with:
22+
python-version: '3.12'
23+
24+
- uses: actions/checkout@v4
25+
26+
- name: Install deps
27+
run: python -mpip install -r requirements-dev.txt
28+
29+
- name: Build HTML docs
30+
run: make html
31+
1632
test:
1733
strategy:
1834
fail-fast: false

index.rst

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
.. SPDX-FileCopyrightText: 2021 Jeff Epler
2+
..
3+
.. SPDX-License-Identifier: GPL-3.0-only
4+
5+
wwvbpy
6+
======
7+
8+
.. image:: https://github.com/jepler/wwvbpy/actions/workflows/test.yml/badge.svg
9+
:target: https://github.com/jepler/wwvbpy/actions/workflows/test.yml
10+
:alt: Test wwvbpy
11+
12+
.. image:: https://img.shields.io/pypi/v/wwvb
13+
:target: https://pypi.org/project/wwvb
14+
:alt: PyPI
15+
16+
17+
.. toctree::
18+
:maxdepth: 2
19+
:caption: Contents:
20+
21+
wwvb module
22+
===========
23+
24+
.. automodule:: wwvb
25+
:members:
26+
27+
uwwvb module
28+
============
29+
30+
.. automodule:: uwwvb
31+
:members:

requirements-dev.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ pre-commit
1414
python-dateutil
1515
requests; implementation_name=="cpython"
1616
setuptools>=68; implementation_name=="cpython"
17+
sphinx
18+
sphinx-autodoc-typehints
19+
sphinx-rtd-theme
1720
twine; implementation_name=="cpython"
1821
types-beautifulsoup4
1922
types-python-dateutil

src/wwvb/__init__.py

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -329,13 +329,28 @@ class _WWVBMinute(NamedTuple):
329329
"""
330330

331331
year: int
332+
"""2-digit year within the WWVB epoch"""
333+
332334
days: int
335+
"""1-based day of year"""
336+
333337
hour: int
338+
"""UTC hour of day"""
339+
334340
min: int
341+
"""Minute of hour"""
342+
335343
dst: int
344+
"""2-bit DST code """
345+
336346
ut1: int
347+
"""UT1 offset in units of 100ms, range -900 to +900ms"""
348+
337349
ls: bool
350+
"""Leap second warning flag"""
351+
338352
ly: bool
353+
"""Leap year flag"""
339354

340355

341356
class WWVBMinute(_WWVBMinute):
@@ -463,14 +478,14 @@ def as_timecode(self) -> WWVBTimecode:
463478
"""Fill a WWVBTimecode structure representing this minute. Fills both the amplitude and phase codes."""
464479
t = WWVBTimecode(self.minute_length())
465480

466-
self.fill_am_timecode(t)
467-
self.fill_pm_timecode(t)
481+
self._fill_am_timecode(t)
482+
self._fill_pm_timecode(t)
468483

469484
return t
470485

471486
@property
472-
def leap_sec(self) -> int:
473-
"""Return the 2-bit leap_sec value used by the PM code"""
487+
def _leap_sec(self) -> int:
488+
"""Return the 2-bit _leap_sec value used by the PM code"""
474489
if not self.ls:
475490
return 0
476491
if self.ut1 < 0:
@@ -487,7 +502,7 @@ def minute_of_century(self) -> int:
487502
// 60
488503
)
489504

490-
def fill_am_timecode(self, t: WWVBTimecode) -> None:
505+
def _fill_am_timecode(self, t: WWVBTimecode) -> None:
491506
"""Fill the amplitude (AM) portion of a timecode object"""
492507
for i in [0, 9, 19, 29, 39, 49]:
493508
t.am[i] = AmplitudeModulation.MARK
@@ -509,7 +524,7 @@ def fill_am_timecode(self, t: WWVBTimecode) -> None:
509524
t.am[56] = AmplitudeModulation(self.ls)
510525
t._put_am_bcd(self.dst, 57, 58)
511526

512-
def fill_pm_timecode_extended(self, t: WWVBTimecode) -> None:
527+
def _fill_pm_timecode_extended(self, t: WWVBTimecode) -> None:
513528
"""During minutes 10..15 and 40..45, the amplitude signal holds 'extended information'"""
514529
assert 10 <= self.min < 16 or 40 <= self.min < 46
515530
minno = self.min % 10
@@ -543,14 +558,14 @@ def fill_pm_timecode_extended(self, t: WWVBTimecode) -> None:
543558
for i in range(60):
544559
t._put_pm_bit(i, full_seq[i + offset])
545560

546-
def fill_pm_timecode_regular(self, t: WWVBTimecode) -> None: # noqa: PLR0915
561+
def _fill_pm_timecode_regular(self, t: WWVBTimecode) -> None: # noqa: PLR0915
547562
"""Except during minutes 10..15 and 40..45, the amplitude signal holds 'regular information'"""
548563
t._put_pm_bin(0, 13, SYNC_T)
549564

550565
moc = self.minute_of_century
551-
leap_sec = self.leap_sec
566+
_leap_sec = self._leap_sec
552567
dst_on = self.dst
553-
dst_ls = _dst_ls_lut[dst_on | (leap_sec << 2)]
568+
dst_ls = _dst_ls_lut[dst_on | (_leap_sec << 2)]
554569
dst_next = _get_dst_next(self.as_datetime())
555570
t._put_pm_bin(13, 5, _hamming_parity(moc))
556571
t._put_pm_bit(18, _extract_bit(moc, 25))
@@ -599,12 +614,12 @@ def fill_pm_timecode_regular(self, t: WWVBTimecode) -> None: # noqa: PLR0915
599614
if len(t.phase) > 60:
600615
t._put_pm_bit(60, PhaseModulation.ZERO)
601616

602-
def fill_pm_timecode(self, t: WWVBTimecode) -> None:
617+
def _fill_pm_timecode(self, t: WWVBTimecode) -> None:
603618
"""Fill the phase portion of a timecode object"""
604619
if 10 <= self.min < 16 or 40 <= self.min < 46:
605-
self.fill_pm_timecode_extended(t)
620+
self._fill_pm_timecode_extended(t)
606621
else:
607-
self.fill_pm_timecode_regular(t)
622+
self._fill_pm_timecode_regular(t)
608623

609624
def next_minute(self, newut1: int | None = None, newls: bool | None = None) -> WWVBMinute:
610625
"""Return an object representing the next minute"""
@@ -745,7 +760,10 @@ class WWVBTimecode:
745760
"""Represent the amplitude and/or phase signal, usually over 1 minute"""
746761

747762
am: list[AmplitudeModulation]
763+
"""The amplitude modulation data"""
764+
748765
phase: list[PhaseModulation]
766+
"""The phase modulation data"""
749767

750768
def __init__(self, sz: int) -> None:
751769
"""Construct a WWVB timecode ``sz`` seconds long"""
@@ -881,7 +899,21 @@ def print_timecodes_json(
881899
channel: str,
882900
file: TextIO,
883901
) -> None:
884-
"""Print a range of timecodes with a header. This header is in a format understood by WWVBMinute.fromstring"""
902+
"""Print a range of timecodes in JSON format.
903+
904+
The result is a json array of minute data. Each minute data is an object with the following members:
905+
906+
* year (int)
907+
* days (int)
908+
* hour (int)
909+
* minute (int)
910+
* amplitude (string; only if channel is amplitude or both)
911+
* phase: (string; only if channel is phase or both)
912+
913+
The amplitude and phase strings are of length 60 during most minutes, length 61
914+
during a minute that includes a (positive) leap second, and theoretically
915+
length 59 in the case of a negative leap second.
916+
"""
885917
result = []
886918
for _ in range(minutes):
887919
data: dict[str, Any] = {

0 commit comments

Comments
 (0)