Skip to content

Commit 258631d

Browse files
committed
docs: add source documentation
1 parent a8d85d6 commit 258631d

File tree

182 files changed

+1773
-145
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

182 files changed

+1773
-145
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,6 @@ krux-*/ktool*
8686

8787
# IDE files
8888
.vscode
89+
90+
# Readthedocs
91+
docs/_static/*

docs/conf.py

Lines changed: 162 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -2,85 +2,82 @@
22
#
33
# For the full list of built-in configuration values, see the documentation:
44
# https://www.sphinx-doc.org/en/master/usage/configuration.html
5+
56
import os
67
import sys
78
import time as _time
8-
from mock import Mock as MagicMock
9+
from unittest.mock import MagicMock
910

1011

11-
class DictMock(MagicMock):
12-
"""Mock that supports dictionary-like behavior."""
12+
class HashableMock:
13+
"""A simple hashable mock that can be used as dictionary keys."""
1314

14-
def __getitem__(self, key):
15-
return self.__dict__.setdefault(key, DictMock())
15+
_counter = 0
1616

17-
def __setitem__(self, key, value):
18-
self.__dict__[key] = value
17+
def __init__(self, name="mock"):
18+
HashableMock._counter += 1
19+
self._name = name
20+
self._id = HashableMock._counter
1921

20-
def __iter__(self):
21-
return iter([])
22+
def __hash__(self):
23+
return self._id
2224

23-
def __contains__(self, key):
25+
def __eq__(self, other):
26+
if isinstance(other, HashableMock):
27+
return self._id == other._id
2428
return False
2529

26-
def get(self, key, default=None):
27-
return self.__dict__.get(key, default)
28-
29-
# Support arithmetic operations
30-
def __sub__(self, other):
31-
return 0
32-
33-
def __rsub__(self, other):
34-
return 0
30+
def __repr__(self):
31+
return f"<HashableMock {self._name}>"
3532

36-
def __add__(self, other):
37-
return 0
38-
39-
def __radd__(self, other):
40-
return 0
41-
42-
def __mul__(self, other):
43-
return 0
33+
def __call__(self, *args, **kwargs):
34+
return HashableMock(self._name)
4435

45-
def __rmul__(self, other):
46-
return 0
36+
def __getattr__(self, name):
37+
return HashableMock(f"{self._name}.{name}")
4738

48-
def __truediv__(self, other):
39+
def __int__(self):
4940
return 0
5041

51-
def __rtruediv__(self, other):
52-
return 0
42+
def __bool__(self):
43+
return False
5344

54-
def __floordiv__(self, other):
55-
return 0
5645

57-
def __rfloordiv__(self, other):
58-
return 0
46+
class MockModule(MagicMock):
47+
"""Mock module that returns HashableMock for attributes that might be used as dict keys."""
5948

60-
def __int__(self):
61-
return 0
49+
# Attributes known to be used as dict keys
50+
HASHABLE_ATTRS = {
51+
"MODE_AES",
52+
"MODE_CTR",
53+
"MODE_CBC",
54+
"MODE_ECB",
55+
"AES",
56+
"CTR",
57+
"CBC",
58+
"ECB",
59+
}
6260

63-
def __float__(self):
64-
return 0
61+
def __getattr__(self, name):
62+
if name in self.HASHABLE_ATTRS or name.startswith("MODE_"):
63+
return HashableMock(name)
64+
return MagicMock()
6565

66-
def __bool__(self):
67-
return False
6866

69-
def __len__(self):
70-
return 0
67+
class MockWordlist:
68+
"""Mock for embit.wordlists.bip39.WORDLIST - returns list of strings."""
7169

72-
def __call__(self, *args, **kwargs):
73-
return DictMock()
70+
WORDLIST = ["abandon"] * 2048 # Dummy wordlist
7471

7572

7673
class MockTime:
7774
"""Mock time module with MicroPython-specific functions."""
7875

79-
# Preserve all standard time functions
8076
def __getattr__(self, name):
81-
return getattr(_time, name)
77+
if hasattr(_time, name):
78+
return getattr(_time, name)
79+
return MagicMock()
8280

83-
# Add MicroPython-specific functions
8481
@staticmethod
8582
def ticks_ms():
8683
return 0
@@ -91,11 +88,11 @@ def ticks_us():
9188

9289
@staticmethod
9390
def ticks_diff(a, b):
94-
return a - b
91+
return 0
9592

9693
@staticmethod
9794
def ticks_add(a, b):
98-
return a + b
95+
return 0
9996

10097
@staticmethod
10198
def sleep_ms(ms):
@@ -106,110 +103,119 @@ def sleep_us(us):
106103
pass
107104

108105

109-
# Create mock for board with required config structure
110-
MOCK_BOARD = DictMock()
111-
MOCK_BOARD.config = MOCK_BOARD.config = {
112-
"type": "amigo",
113-
"lcd": {"height": 320, "width": 480, "invert": 0, "dir": 40, "lcd_type": 1},
114-
"sdcard": {"sclk": 11, "mosi": 10, "miso": 6, "cs": 26},
115-
"board_info": {
116-
"BOOT_KEY": 23,
117-
"CONNEXT_A": 7,
118-
"CONNEXT_B": 9,
119-
"LED_R": 14,
120-
"LED_G": 15,
121-
"LED_B": 17,
122-
"LED_W": 32,
123-
"BACK": 23,
124-
"ENTER": 16,
125-
"NEXT": 20,
126-
"WIFI_TX": 6,
127-
"WIFI_RX": 7,
128-
"WIFI_EN": 8,
129-
"I2S0_MCLK": 13,
130-
"I2S0_SCLK": 21,
131-
"I2S0_WS": 18,
132-
"I2S0_IN_D0": 35,
133-
"I2S0_OUT_D2": 34,
134-
"I2C_SDA": 27,
135-
"I2C_SCL": 24,
136-
"SPI_SCLK": 11,
137-
"SPI_MOSI": 10,
138-
"SPI_MISO": 6,
139-
"SPI_CS": 12,
140-
},
141-
"krux": {
142-
"pins": {
143-
"BUTTON_A": 16,
144-
"BUTTON_B": 20,
145-
"BUTTON_C": 23,
146-
"TOUCH_IRQ": 33,
106+
class MockBoard:
107+
"""Mock board module with config structure."""
108+
109+
config = {
110+
"type": "amigo",
111+
"lcd": {"height": 320, "width": 480, "invert": 0, "dir": 40, "lcd_type": 1},
112+
"sdcard": {"sclk": 11, "mosi": 10, "miso": 6, "cs": 26},
113+
"board_info": {
114+
"BOOT_KEY": 23,
115+
"CONNEXT_A": 7,
116+
"CONNEXT_B": 9,
117+
"LED_R": 14,
118+
"LED_G": 15,
119+
"LED_B": 17,
147120
"LED_W": 32,
121+
"BACK": 23,
122+
"ENTER": 16,
123+
"NEXT": 20,
124+
"WIFI_TX": 6,
125+
"WIFI_RX": 7,
126+
"WIFI_EN": 8,
148127
"I2C_SDA": 27,
149128
"I2C_SCL": 24,
150129
},
151-
"display": {"touch": True, "font": [12, 24], "font_wide": [24, 24]},
152-
},
153-
}
154-
155-
MOCK_TIME = MockTime()
130+
"krux": {
131+
"pins": {
132+
"BUTTON_A": 16,
133+
"BUTTON_B": 20,
134+
"BUTTON_C": 23,
135+
"TOUCH_IRQ": 33,
136+
"LED_W": 32,
137+
"I2C_SDA": 27,
138+
"I2C_SCL": 24,
139+
},
140+
"display": {"touch": True, "font": [12, 24], "font_wide": [24, 24]},
141+
},
142+
}
156143

144+
def __getattr__(self, name):
145+
return MagicMock()
157146

158-
def ignore_modules(*args):
159-
for mod_name in list(args):
160-
if mod_name == "board":
161-
sys.modules[mod_name] = MOCK_BOARD
162-
elif mod_name == "time":
163-
sys.modules[mod_name] = MOCK_TIME
164-
else:
165-
sys.modules[mod_name] = DictMock()
166-
167-
168-
# Mock ALL MicroPython and hardware-dependent modules
169-
ignore_modules(
170-
# MicroPython built-ins
171-
"machine",
172-
"board",
173-
"pmu",
174-
"time",
175-
"lcd",
176-
"ujson",
177-
"urandom",
178-
"ucryptolib",
179-
"uhashlib",
180-
"uctypes",
181-
"uos",
182-
"usys",
183-
"gc",
184-
# K210/Maix specific
185-
"Maix",
186-
"fpioa_manager",
187-
"sensor",
188-
"image",
189-
"flash",
190-
# Crypto
191-
"secp256k1",
192-
"qrcode",
193-
# Scientific (if used)
194-
"numpy",
195-
"scipy",
196-
"scipy. linalg",
197-
"scipy.signal",
198-
)
199147

148+
# Create mock instances
149+
MOCK_TIME = MockTime()
150+
MOCK_BOARD = MockBoard()
151+
MOCK_UCRYPTOLIB = MockModule()
152+
MOCK_UCRYPTOLIB.aes = MockModule()
153+
154+
# Mock for embit.wordlists.bip39
155+
MOCK_BIP39 = type("MockBip39", (), {"WORDLIST": ["abandon"] * 2048})()
156+
157+
158+
def setup_mocks():
159+
"""Setup all mocked modules."""
160+
161+
mocks = {
162+
# MicroPython built-ins
163+
"machine": MagicMock(),
164+
"board": MOCK_BOARD,
165+
"pmu": MagicMock(),
166+
"time": MOCK_TIME,
167+
"lcd": MagicMock(),
168+
"ujson": MagicMock(),
169+
"urandom": MagicMock(),
170+
"ucryptolib": MOCK_UCRYPTOLIB,
171+
"uhashlib": MagicMock(),
172+
"uhashlib_hw": MagicMock(),
173+
"uctypes": MagicMock(),
174+
"uos": MagicMock(),
175+
"usys": MagicMock(),
176+
"gc": MagicMock(),
177+
# K210/Maix specific
178+
"Maix": MagicMock(),
179+
"fpioa_manager": MagicMock(),
180+
"sensor": MagicMock(),
181+
"image": MagicMock(),
182+
"flash": MagicMock(),
183+
# Crypto/QR
184+
"secp256k1": MagicMock(),
185+
"qrcode": MagicMock(),
186+
# Embit (Bitcoin library)
187+
"embit": MagicMock(),
188+
"embit.wordlists": MagicMock(),
189+
"embit.wordlists.bip39": MOCK_BIP39,
190+
"embit.psbt": MagicMock(),
191+
"embit.networks": MagicMock(),
192+
"embit.descriptor": MagicMock(),
193+
"embit.descriptor.descriptor": MagicMock(),
194+
"embit.descriptor.arguments": MagicMock(),
195+
# Scientific (if needed)
196+
"numpy": MagicMock(),
197+
"scipy": MagicMock(),
198+
"scipy.linalg": MagicMock(),
199+
"scipy.signal": MagicMock(),
200+
}
201+
202+
for mod_name, mock_obj in mocks.items():
203+
sys.modules[mod_name] = mock_obj
204+
205+
206+
# Setup mocks before importing anything
207+
setup_mocks()
208+
209+
# Add source path
200210
sys.path.insert(0, os.path.abspath("../src/"))
201211

202212
# -- Project information -----------------------------------------------------
203-
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
204-
205213
project = "Krux"
206214
copyright = "2022, MIT"
207215
author = "Selfcustody"
208216
release = "2022"
209217

210218
# -- General configuration ---------------------------------------------------
211-
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
212-
213219
extensions = [
214220
"sphinx.ext.autodoc",
215221
"sphinx.ext.coverage",
@@ -224,9 +230,23 @@ def ignore_modules(*args):
224230
templates_path = ["_templates"]
225231
exclude_patterns = []
226232

233+
# Suppress duplicate object warnings
234+
suppress_warnings = ["autodoc", "autodoc.import_object"]
227235

228236
# -- Options for HTML output -------------------------------------------------
229-
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
230-
231237
html_theme = "sphinx_rtd_theme"
232-
html_static_path = ["_static"]
238+
html_static_path = [] # Remove _static to avoid warning
239+
240+
# Suppress warnings
241+
suppress_warnings = ["autodoc"]
242+
243+
244+
def skip_mock_members(app, what, name, obj, skip, options):
245+
"""Skip mock objects that can't be documented."""
246+
if "Mock" in str(type(obj)):
247+
return True
248+
return skip
249+
250+
251+
def setup(app):
252+
app.connect("autodoc-skip-member", skip_mock_members)

0 commit comments

Comments
 (0)